Prepare call/invoke for opaque pointers
Rather than relying on `getPointerElementType()` from LLVM function pointers, we now pass the function type explicitly when building `call` or `invoke` instructions.
This commit is contained in:
parent
61a941b8ba
commit
183d79cc09
15 changed files with 168 additions and 151 deletions
|
@ -441,9 +441,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
|
||||
bx.insert_reference_to_gdb_debug_scripts_section_global();
|
||||
|
||||
let isize_ty = cx.type_isize();
|
||||
let i8pp_ty = cx.type_ptr_to(cx.type_i8p());
|
||||
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
|
||||
|
||||
let (start_fn, args) = if use_start_lang_item {
|
||||
let (start_fn, start_ty, args) = if use_start_lang_item {
|
||||
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
|
||||
let start_fn = cx.get_fn_addr(
|
||||
ty::Instance::resolve(
|
||||
|
@ -455,16 +457,15 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
.unwrap()
|
||||
.unwrap(),
|
||||
);
|
||||
(
|
||||
start_fn,
|
||||
vec![bx.pointercast(rust_main, cx.type_ptr_to(cx.type_i8p())), arg_argc, arg_argv],
|
||||
)
|
||||
let start_ty = cx.type_func(&[cx.val_ty(rust_main), isize_ty, i8pp_ty], isize_ty);
|
||||
(start_fn, start_ty, vec![rust_main, arg_argc, arg_argv])
|
||||
} else {
|
||||
debug!("using user-defined start fn");
|
||||
(rust_main, vec![arg_argc, arg_argv])
|
||||
let start_ty = cx.type_func(&[isize_ty, i8pp_ty], isize_ty);
|
||||
(rust_main, start_ty, vec![arg_argc, arg_argv])
|
||||
};
|
||||
|
||||
let result = bx.call(start_fn, &args, None);
|
||||
let result = bx.call(start_ty, start_fn, &args, None);
|
||||
let cast = bx.intcast(result, cx.type_int(), true);
|
||||
bx.ret(cast);
|
||||
|
||||
|
|
|
@ -132,14 +132,21 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
|
|||
) {
|
||||
// If there is a cleanup block and the function we're calling can unwind, then
|
||||
// do an invoke, otherwise do a call.
|
||||
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
|
||||
if let Some(cleanup) = cleanup.filter(|_| fn_abi.can_unwind) {
|
||||
let ret_llbb = if let Some((_, target)) = destination {
|
||||
fx.llbb(target)
|
||||
} else {
|
||||
fx.unreachable_block()
|
||||
};
|
||||
let invokeret =
|
||||
bx.invoke(fn_ptr, &llargs, ret_llbb, self.llblock(fx, cleanup), self.funclet(fx));
|
||||
let invokeret = bx.invoke(
|
||||
fn_ty,
|
||||
fn_ptr,
|
||||
&llargs,
|
||||
ret_llbb,
|
||||
self.llblock(fx, cleanup),
|
||||
self.funclet(fx),
|
||||
);
|
||||
bx.apply_attrs_callsite(&fn_abi, invokeret);
|
||||
|
||||
if let Some((ret_dest, target)) = destination {
|
||||
|
@ -148,7 +155,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
|
|||
fx.store_return(&mut ret_bx, ret_dest, &fn_abi.ret, invokeret);
|
||||
}
|
||||
} else {
|
||||
let llret = bx.call(fn_ptr, &llargs, self.funclet(fx));
|
||||
let llret = bx.call(fn_ty, fn_ptr, &llargs, self.funclet(fx));
|
||||
bx.apply_attrs_callsite(&fn_abi, llret);
|
||||
if fx.mir[self.bb].is_cleanup {
|
||||
// Cleanup is always the cold path. Don't inline
|
||||
|
|
|
@ -518,7 +518,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
};
|
||||
let instance = ty::Instance::mono(bx.tcx(), def_id);
|
||||
let r = bx.cx().get_fn_addr(instance);
|
||||
let call = bx.call(r, &[llsize, llalign], None);
|
||||
let ty = bx.type_func(&[bx.type_isize(), bx.type_isize()], bx.type_i8p());
|
||||
let call = bx.call(ty, r, &[llsize, llalign], None);
|
||||
let val = bx.pointercast(call, llty_ptr);
|
||||
|
||||
let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
|
||||
|
|
|
@ -72,6 +72,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
);
|
||||
fn invoke(
|
||||
&mut self,
|
||||
llty: Self::Type,
|
||||
llfn: Self::Value,
|
||||
args: &[Self::Value],
|
||||
then: Self::BasicBlock,
|
||||
|
@ -303,6 +304,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
|
||||
fn call(
|
||||
&mut self,
|
||||
llty: Self::Type,
|
||||
llfn: Self::Value,
|
||||
args: &[Self::Value],
|
||||
funclet: Option<&Self::Funclet>,
|
||||
|
|
|
@ -102,6 +102,7 @@ impl<T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscM
|
|||
pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
|
||||
fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
|
||||
fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type;
|
||||
fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type;
|
||||
fn fn_ptr_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type;
|
||||
fn reg_backend_type(&self, ty: &Reg) -> Self::Type;
|
||||
fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue