about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-10-29 21:46:25 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-12-03 15:41:56 +0200
commit052d0edbc1c2572ba735ef911a5ab7e9c2a703bc (patch)
tree69fd9047f0ed41e79040271959d202277bcf414d
parent39e50e2f289a58a46f46044d8e9d296b9e7ac7e6 (diff)
downloadrust-052d0edbc1c2572ba735ef911a5ab7e9c2a703bc.tar.gz
rust-052d0edbc1c2572ba735ef911a5ab7e9c2a703bc.zip
rustc: compute FnAbi's for virtual calls through FnAbi::of_instance.
-rw-r--r--src/librustc/ty/layout.rs20
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs46
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs2
5 files changed, 36 insertions, 36 deletions
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index c67e6a0a13e..52f0bb220ad 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -2347,9 +2347,8 @@ where
         + HasTyCtxt<'tcx>
         + HasParamEnv<'tcx>,
 {
-    fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self;
     fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
-    fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
+    fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
     fn new_internal(
         cx: &C,
         sig: ty::FnSig<'tcx>,
@@ -2367,25 +2366,22 @@ where
         + HasTyCtxt<'tcx>
         + HasParamEnv<'tcx>,
 {
-    fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self {
+    fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
+        call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
+    }
+
+    fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
         let sig = instance.fn_sig(cx.tcx());
         let sig = cx
             .tcx()
             .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
-        call::FnAbi::new(cx, sig, &[])
-    }
-
-    fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
-        call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
-    }
 
-    fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
-        FnAbiExt::new_internal(cx, sig, extra_args, |ty, arg_idx| {
+        call::FnAbi::new_internal(cx, sig, extra_args, |ty, arg_idx| {
             let mut layout = cx.layout_of(ty);
             // Don't pass the vtable, it's not an argument of the virtual fn.
             // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
             // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
-            if arg_idx == Some(0) {
+            if let (ty::InstanceDef::Virtual(..), Some(0)) = (&instance.def, arg_idx) {
                 let fat_pointer_ty = if layout.is_unsized() {
                     // unsized `self` is passed as a pointer to `self`
                     // FIXME (mikeyhew) change this to use &own if it is ever added to the language
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index b6a3bf2f878..74f4970333c 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -40,7 +40,7 @@ pub fn get_fn(
     let sym = tcx.symbol_name(instance).name.as_str();
     debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx()), sym);
 
-    let fn_abi = FnAbi::of_instance(cx, instance);
+    let fn_abi = FnAbi::of_instance(cx, instance, &[]);
 
     let llfn = if let Some(llfn) = cx.get_declared_value(&sym) {
         // Create a fn pointer with the new signature.
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index 3d2f6efb072..75a4a966694 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -43,7 +43,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         assert!(!instance.substs.needs_infer() &&
                 !instance.substs.has_param_types());
 
-        let fn_abi = FnAbi::of_instance(self, instance);
+        let fn_abi = FnAbi::of_instance(self, instance, &[]);
         let lldecl = self.declare_fn(symbol_name, &fn_abi);
         unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
         let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 370c172f97f..3ef6caec2f2 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -345,20 +345,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             &args1[..]
         };
         let (drop_fn, fn_abi) = match ty.kind {
+            // FIXME(eddyb) perhaps move some of this logic into
+            // `Instance::resolve_drop_in_place`?
             ty::Dynamic(..) => {
-                let sig = drop_fn.fn_sig(self.cx.tcx());
-                let sig = self.cx.tcx().normalize_erasing_late_bound_regions(
-                    ty::ParamEnv::reveal_all(),
-                    &sig,
-                );
-                let fn_abi = FnAbi::new_vtable(&bx, sig, &[]);
+                let virtual_drop = Instance {
+                    def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
+                    substs: drop_fn.substs,
+                };
+                let fn_abi = FnAbi::of_instance(&bx, virtual_drop, &[]);
                 let vtable = args[1];
                 args = &args[..1];
                 (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_abi), fn_abi)
             }
             _ => {
                 (bx.get_fn_addr(drop_fn),
-                 FnAbi::of_instance(&bx, drop_fn))
+                 FnAbi::of_instance(&bx, drop_fn, &[]))
             }
         };
         helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
@@ -439,7 +440,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         // Obtain the panic entry point.
         let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
         let instance = ty::Instance::mono(bx.tcx(), def_id);
-        let fn_abi = FnAbi::of_instance(&bx, instance);
+        let fn_abi = FnAbi::of_instance(&bx, instance, &[]);
         let llfn = bx.get_fn_addr(instance);
 
         // Codegen the actual panic invoke/call.
@@ -474,6 +475,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             _ => bug!("{} is not callable", callee.layout.ty),
         };
         let def = instance.map(|i| i.def);
+
+        if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
+            // Empty drop glue; a no-op.
+            let &(_, target) = destination.as_ref().unwrap();
+            helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
+            helper.funclet_br(self, &mut bx, target);
+            return;
+        }
+
+        // FIXME(eddyb) avoid computing this if possible, when `instance` is
+        // available - right now `sig` is only needed for getting the `abi`
+        // and figuring out how many extra args were passed to a C-variadic `fn`.
         let sig = callee.layout.ty.fn_sig(bx.tcx());
         let sig = bx.tcx().normalize_erasing_late_bound_regions(
             ty::ParamEnv::reveal_all(),
@@ -514,18 +527,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             self.monomorphize(&op_ty)
         }).collect::<Vec<_>>();
 
-        let fn_abi = match def {
-            Some(ty::InstanceDef::Virtual(..)) => {
-                FnAbi::new_vtable(&bx, sig, &extra_args)
-            }
-            Some(ty::InstanceDef::DropGlue(_, None)) => {
-                // Empty drop glue; a no-op.
-                let &(_, target) = destination.as_ref().unwrap();
-                helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
-                helper.funclet_br(self, &mut bx, target);
-                return;
-            }
-            _ => FnAbi::new(&bx, sig, &extra_args)
+        let fn_abi = match instance {
+            Some(instance) => FnAbi::of_instance(&bx, instance, &extra_args),
+            None => FnAbi::new(&bx, sig, &extra_args)
         };
 
         // For normal codegen, this Miri-specific intrinsic is just a NOP.
@@ -549,7 +553,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let def_id =
                     common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
                 let instance = ty::Instance::mono(bx.tcx(), def_id);
-                let fn_abi = FnAbi::of_instance(&bx, instance);
+                let fn_abi = FnAbi::of_instance(&bx, instance, &[]);
                 let llfn = bx.get_fn_addr(instance);
 
                 if let Some((_, target)) = destination.as_ref() {
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 04b10287951..3a157ca24a4 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -129,7 +129,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
     let mir = cx.tcx().instance_mir(instance.def);
 
-    let fn_abi = FnAbi::of_instance(cx, instance);
+    let fn_abi = FnAbi::of_instance(cx, instance, &[]);
     debug!("fn_abi: {:?}", fn_abi);
 
     let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);