1
Fork 0

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:
Josh Stone 2021-08-03 15:09:57 -07:00
parent 61a941b8ba
commit 183d79cc09
15 changed files with 168 additions and 151 deletions

View file

@ -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);

View file

@ -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

View file

@ -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 };

View file

@ -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>,

View file

@ -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;