about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_codegen_ssa')
-rw-r--r--src/librustc_codegen_ssa/README.md2
-rw-r--r--src/librustc_codegen_ssa/back/write.rs6
-rw-r--r--src/librustc_codegen_ssa/base.rs17
-rw-r--r--src/librustc_codegen_ssa/callee.rs53
-rw-r--r--src/librustc_codegen_ssa/common.rs5
-rw-r--r--src/librustc_codegen_ssa/error_codes.rs35
-rw-r--r--src/librustc_codegen_ssa/lib.rs12
-rw-r--r--src/librustc_codegen_ssa/meth.rs12
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs8
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs17
-rw-r--r--src/librustc_codegen_ssa/traits/backend.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/builder.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/consts.rs4
-rw-r--r--src/librustc_codegen_ssa/traits/debuginfo.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/declare.rs4
-rw-r--r--src/librustc_codegen_ssa/traits/misc.rs8
-rw-r--r--src/librustc_codegen_ssa/traits/mod.rs1
19 files changed, 107 insertions, 91 deletions
diff --git a/src/librustc_codegen_ssa/README.md b/src/librustc_codegen_ssa/README.md
index c8bb2e7ee99..a09a0c22c1b 100644
--- a/src/librustc_codegen_ssa/README.md
+++ b/src/librustc_codegen_ssa/README.md
@@ -84,7 +84,7 @@ pub trait BuilderMethods<'a, 'tcx>:
 {
     fn new_block<'b>(
         cx: &'a Self::CodegenCx,
-        llfn: Self::Value,
+        llfn: Self::Function,
         name: &'b str
     ) -> Self;
     /* ... */
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 481db26e1a8..ef3b115890f 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -22,7 +22,8 @@ use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry};
 use rustc::util::profiling::SelfProfilerRef;
 use rustc_fs_util::link_or_copy;
 use rustc_data_structures::svh::Svh;
-use rustc_errors::{Handler, Level, FatalError, DiagnosticId};
+use rustc_data_structures::sync::Lrc;
+use rustc_errors::{Handler, Level, FatalError, DiagnosticId, SourceMapperDyn};
 use rustc_errors::emitter::{Emitter};
 use rustc_target::spec::MergeFunctions;
 use syntax::attr;
@@ -1681,6 +1682,9 @@ impl Emitter for SharedEmitter {
         }
         drop(self.sender.send(SharedEmitterMessage::AbortIfErrors));
     }
+    fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
+        None
+    }
 }
 
 impl SharedEmitterMain {
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 935087714a7..1c441ca7cbf 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -36,7 +36,6 @@ use crate::mir::place::PlaceRef;
 use crate::back::write::{OngoingCodegen, start_async_codegen, submit_pre_lto_module_to_llvm,
     submit_post_lto_module_to_llvm};
 use crate::{MemFlags, CrateInfo};
-use crate::callee;
 use crate::common::{RealPredicate, TypeKind, IntPredicate};
 use crate::meth;
 use crate::mir;
@@ -377,8 +376,7 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
     let sig = instance.fn_sig(cx.tcx());
     let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
 
-    let lldecl = cx.instances().borrow().get(&instance).cloned().unwrap_or_else(||
-        bug!("Instance `{:?}` not already declared", instance));
+    let lldecl = cx.get_fn(instance);
 
     let mir = cx.tcx().instance_mir(instance.def);
     mir::codegen_mir::<Bx>(cx, lldecl, &mir, instance, sig);
@@ -400,7 +398,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
         return;
     }
 
-    let main_llfn = cx.get_fn(instance);
+    let main_llfn = cx.get_fn_addr(instance);
 
     let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
     match et {
@@ -455,10 +453,13 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
 
         let (start_fn, args) = if use_start_lang_item {
             let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
-            let start_fn = callee::resolve_and_get_fn(
-                cx,
-                start_def_id,
-                cx.tcx().intern_substs(&[main_ret_ty.into()]),
+            let start_fn = cx.get_fn_addr(
+                ty::Instance::resolve(
+                    cx.tcx(),
+                    ty::ParamEnv::reveal_all(),
+                    start_def_id,
+                    cx.tcx().intern_substs(&[main_ret_ty.into()]),
+                ).unwrap()
             );
             (start_fn, vec![bx.pointercast(rust_main, cx.type_ptr_to(cx.type_i8p())),
                             arg_argc, arg_argv])
diff --git a/src/librustc_codegen_ssa/callee.rs b/src/librustc_codegen_ssa/callee.rs
deleted file mode 100644
index 6ba6774cbf8..00000000000
--- a/src/librustc_codegen_ssa/callee.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use crate::traits::*;
-use rustc::ty;
-use rustc::ty::subst::SubstsRef;
-use rustc::hir::def_id::DefId;
-
-pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>(
-    cx: &Cx,
-    def_id: DefId,
-    substs: SubstsRef<'tcx>,
-) -> Cx::Value {
-    cx.get_fn(
-        ty::Instance::resolve(
-            cx.tcx(),
-            ty::ParamEnv::reveal_all(),
-            def_id,
-            substs
-        ).unwrap()
-    )
-}
-
-pub fn resolve_and_get_fn_for_ptr<'tcx,
-    Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
->(
-    cx: &Cx,
-    def_id: DefId,
-    substs: SubstsRef<'tcx>,
-) -> Cx::Value {
-    cx.get_fn(
-        ty::Instance::resolve_for_fn_ptr(
-            cx.tcx(),
-            ty::ParamEnv::reveal_all(),
-            def_id,
-            substs
-        ).unwrap()
-    )
-}
-
-pub fn resolve_and_get_fn_for_vtable<'tcx,
-    Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
->(
-    cx: &Cx,
-    def_id: DefId,
-    substs: SubstsRef<'tcx>,
-) -> Cx::Value {
-    cx.get_fn(
-        ty::Instance::resolve_for_vtable(
-            cx.tcx(),
-            ty::ParamEnv::reveal_all(),
-            def_id,
-            substs
-        ).unwrap()
-    )
-}
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index e3aa35ef4eb..ac39ca98476 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/src/librustc_codegen_ssa/common.rs
@@ -1,6 +1,7 @@
 #![allow(non_camel_case_types, non_snake_case)]
 
 use rustc::ty::{Ty, TyCtxt};
+use rustc::session::Session;
 use syntax_pos::Span;
 
 use rustc::hir::def_id::DefId;
@@ -200,3 +201,7 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
     }
 }
+
+pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
+    span_err!(a, b, E0511, "{}", c);
+}
diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs
index 8ff41c275a8..02e26d8f6ec 100644
--- a/src/librustc_codegen_ssa/error_codes.rs
+++ b/src/librustc_codegen_ssa/error_codes.rs
@@ -1,5 +1,40 @@
 syntax::register_diagnostics! {
 
+E0511: r##"
+Invalid monomorphization of an intrinsic function was used. Erroneous code
+example:
+
+```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
+#![feature(platform_intrinsics)]
+
+extern "platform-intrinsic" {
+    fn simd_add<T>(a: T, b: T) -> T;
+}
+
+fn main() {
+    unsafe { simd_add(0, 1); }
+    // error: invalid monomorphization of `simd_add` intrinsic
+}
+```
+
+The generic type has to be a SIMD type. Example:
+
+```
+#![feature(repr_simd)]
+#![feature(platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i32x2(i32, i32);
+
+extern "platform-intrinsic" {
+    fn simd_add<T>(a: T, b: T) -> T;
+}
+
+unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
+```
+"##,
+
 E0668: r##"
 Malformed inline assembly rejected by LLVM.
 
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index d700001430e..0221a04b045 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -27,6 +27,7 @@ use rustc::dep_graph::WorkProduct;
 use rustc::session::config::{OutputFilenames, OutputType};
 use rustc::middle::lang_items::LangItem;
 use rustc::hir::def_id::CrateNum;
+use rustc::ty::query::Providers;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::svh::Svh;
@@ -41,7 +42,6 @@ pub mod traits;
 pub mod mir;
 pub mod debuginfo;
 pub mod base;
-pub mod callee;
 pub mod glue;
 pub mod meth;
 pub mod mono_item;
@@ -156,3 +156,13 @@ pub struct CodegenResults {
     pub linker_info: back::linker::LinkerInfo,
     pub crate_info: CrateInfo,
 }
+
+pub fn provide(providers: &mut Providers<'_>) {
+    crate::back::symbol_export::provide(providers);
+    crate::base::provide_both(providers);
+}
+
+pub fn provide_extern(providers: &mut Providers<'_>) {
+    crate::back::symbol_export::provide_extern(providers);
+    crate::base::provide_both(providers);
+}
diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs
index 7fe9f5f2513..266d2e5b18d 100644
--- a/src/librustc_codegen_ssa/meth.rs
+++ b/src/librustc_codegen_ssa/meth.rs
@@ -1,6 +1,5 @@
 use rustc_target::abi::call::FnType;
 
-use crate::callee;
 use crate::traits::*;
 
 use rustc::ty::{self, Ty, Instance};
@@ -92,7 +91,14 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
 
     let methods = methods.cloned().map(|opt_mth| {
         opt_mth.map_or(nullptr, |(def_id, substs)| {
-            callee::resolve_and_get_fn_for_vtable(cx, def_id, substs)
+            cx.get_fn_addr(
+                ty::Instance::resolve_for_vtable(
+                    cx.tcx(),
+                    ty::ParamEnv::reveal_all(),
+                    def_id,
+                    substs,
+                ).unwrap()
+            )
         })
     });
 
@@ -102,7 +108,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
     // `get_vtable` in rust_mir/interpret/traits.rs
     // /////////////////////////////////////////////////////////////////////////////////////////////
     let components: Vec<_> = [
-        cx.get_fn(Instance::resolve_drop_in_place(cx.tcx(), ty)),
+        cx.get_fn_addr(Instance::resolve_drop_in_place(cx.tcx(), ty)),
         cx.const_usize(layout.size.bytes()),
         cx.const_usize(layout.align.abi.bytes())
     ].iter().cloned().chain(methods).collect();
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index b0df81ba1ab..dc77d025c00 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -358,7 +358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty)
             }
             _ => {
-                (bx.get_fn(drop_fn),
+                (bx.get_fn_addr(drop_fn),
                  FnType::of_instance(&bx, drop_fn))
             }
         };
@@ -460,7 +460,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
         let instance = ty::Instance::mono(bx.tcx(), def_id);
         let fn_ty = FnType::of_instance(&bx, instance);
-        let llfn = bx.get_fn(instance);
+        let llfn = bx.get_fn_addr(instance);
 
         // Codegen the actual panic invoke/call.
         helper.do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup);
@@ -576,7 +576,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
                 let instance = ty::Instance::mono(bx.tcx(), def_id);
                 let fn_ty = FnType::of_instance(&bx, instance);
-                let llfn = bx.get_fn(instance);
+                let llfn = bx.get_fn_addr(instance);
 
                 if let Some((_, target)) = destination.as_ref() {
                     helper.maybe_sideeffect(self.mir, &mut bx, &[*target]);
@@ -793,7 +793,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         let fn_ptr = match (llfn, instance) {
             (Some(llfn), _) => llfn,
-            (None, Some(instance)) => bx.get_fn(instance),
+            (None, Some(instance)) => bx.get_fn_addr(instance),
             _ => span_bug!(span, "no llfn for call"),
         };
 
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index d5612d7b072..1a2e796a5b7 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -30,7 +30,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
 
     debug_context: FunctionDebugContext<Bx::DIScope>,
 
-    llfn: Bx::Value,
+    llfn: Bx::Function,
 
     cx: &'a Bx::CodegenCx,
 
@@ -183,7 +183,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
 
 pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
-    llfn: Bx::Value,
+    llfn: Bx::Function,
     mir: &'a Body<'tcx>,
     instance: Instance<'tcx>,
     sig: ty::FnSig<'tcx>,
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 2d97f828f07..1d1bc2a81a2 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -394,8 +394,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         // Statically compute the offset if we can, otherwise just use the element size,
         // as this will yield the lowest alignment.
         let layout = self.layout.field(bx, 0);
-        let offset = if bx.is_const_integral(llindex) {
-            layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
+        let offset = if let Some(llindex) = bx.const_to_opt_uint(llindex) {
+            layout.size.checked_mul(llindex, bx).unwrap_or(layout.size)
         } else {
             layout.size
         };
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 978e7218aa7..27442bb6bff 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -10,7 +10,6 @@ use syntax::source_map::{DUMMY_SP, Span};
 
 use crate::base;
 use crate::MemFlags;
-use crate::callee;
 use crate::common::{self, RealPredicate, IntPredicate};
 
 use crate::traits::*;
@@ -95,7 +94,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     let size = bx.const_usize(dest.layout.size.bytes());
 
                     // Use llvm.memset.p0i8.* to initialize all zero arrays
-                    if bx.cx().is_const_integral(v) && bx.cx().const_to_uint(v) == 0 {
+                    if bx.cx().const_to_opt_uint(v) == Some(0) {
                         let fill = bx.cx().const_u8(0);
                         bx.memset(start, fill, size, dest.align, MemFlags::empty());
                         return bx;
@@ -190,7 +189,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                     bug!("reifying a fn ptr that requires const arguments");
                                 }
                                 OperandValue::Immediate(
-                                    callee::resolve_and_get_fn_for_ptr(bx.cx(), def_id, substs))
+                                    bx.get_fn_addr(
+                                        ty::Instance::resolve_for_fn_ptr(
+                                            bx.tcx(),
+                                            ty::ParamEnv::reveal_all(),
+                                            def_id,
+                                            substs
+                                        ).unwrap()
+                                    )
+                                )
                             }
                             _ => {
                                 bug!("{} cannot be reified to a fn ptr", operand.layout.ty)
@@ -205,7 +212,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                     def_id,
                                     substs,
                                     ty::ClosureKind::FnOnce);
-                                OperandValue::Immediate(bx.cx().get_fn(instance))
+                                OperandValue::Immediate(bx.cx().get_fn_addr(instance))
                             }
                             _ => {
                                 bug!("{} cannot be cast to a fn ptr", operand.layout.ty)
@@ -488,7 +495,7 @@ 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(instance);
+                let r = bx.cx().get_fn_addr(instance);
                 let call = bx.call(r, &[llsize, llalign], None);
                 let val = bx.pointercast(call, llty_ptr);
 
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs
index cb197f51460..a7faf4eaf10 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/src/librustc_codegen_ssa/traits/backend.rs
@@ -14,6 +14,8 @@ use syntax_pos::symbol::InternedString;
 
 pub trait BackendTypes {
     type Value: CodegenObject;
+    type Function: CodegenObject;
+
     type BasicBlock: Copy;
     type Type: CodegenObject;
     type Funclet;
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index 1886701fb3a..62b5bcbb6c9 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -34,7 +34,7 @@ pub trait BuilderMethods<'a, 'tcx>:
     + HasTargetSpec
 
 {
-    fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
+    fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self;
     fn with_cx(cx: &'a Self::CodegenCx) -> Self;
     fn build_sibling_block(&self, name: &str) -> Self;
     fn cx(&self) -> &Self::CodegenCx;
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs
index e7ce03f1836..95ada60fae0 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/src/librustc_codegen_ssa/traits/consts.rs
@@ -21,11 +21,9 @@ pub trait ConstMethods<'tcx>: BackendTypes {
 
     fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
 
-    fn const_to_uint(&self, v: Self::Value) -> u64;
+    fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
     fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
 
-    fn is_const_integral(&self, v: Self::Value) -> bool;
-
     fn scalar_to_backend(
         &self,
         cv: Scalar,
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs
index e75f247da96..989e6cf9dca 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -20,7 +20,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
         &self,
         instance: Instance<'tcx>,
         sig: ty::FnSig<'tcx>,
-        llfn: Self::Value,
+        llfn: Self::Function,
         mir: &mir::Body<'_>,
     ) -> FunctionDebugContext<Self::DIScope>;
 
diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs
index 624a982b619..cd42044e48d 100644
--- a/src/librustc_codegen_ssa/traits/declare.rs
+++ b/src/librustc_codegen_ssa/traits/declare.rs
@@ -17,13 +17,13 @@ pub trait DeclareMethods<'tcx>: BackendTypes {
     ///
     /// If there’s a value with the same name already declared, the function will
     /// update the declaration and return existing Value instead.
-    fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Value;
+    fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Function;
 
     /// Declare a Rust function.
     ///
     /// If there’s a value with the same name already declared, the function will
     /// update the declaration and return existing Value instead.
-    fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Value;
+    fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Function;
 
     /// Declare a global with an intention to define it.
     ///
diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs
index 46c88a6113e..658ddd00280 100644
--- a/src/librustc_codegen_ssa/traits/misc.rs
+++ b/src/librustc_codegen_ssa/traits/misc.rs
@@ -11,14 +11,14 @@ pub trait MiscMethods<'tcx>: BackendTypes {
         &self,
     ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
     fn check_overflow(&self) -> bool;
-    fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, Self::Value>>;
-    fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
+    fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function;
+    fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value;
     fn eh_personality(&self) -> Self::Value;
     fn eh_unwind_resume(&self) -> Self::Value;
     fn sess(&self) -> &Session;
     fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
     fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
-    fn set_frame_pointer_elimination(&self, llfn: Self::Value);
-    fn apply_target_cpu_attr(&self, llfn: Self::Value);
+    fn set_frame_pointer_elimination(&self, llfn: Self::Function);
+    fn apply_target_cpu_attr(&self, llfn: Self::Function);
     fn create_used_variable(&self);
 }
diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs
index efe4a255701..4318ef16494 100644
--- a/src/librustc_codegen_ssa/traits/mod.rs
+++ b/src/librustc_codegen_ssa/traits/mod.rs
@@ -88,6 +88,7 @@ pub trait HasCodegen<'tcx>:
     type CodegenCx: CodegenMethods<'tcx>
         + BackendTypes<
             Value = Self::Value,
+            Function = Self::Function,
             BasicBlock = Self::BasicBlock,
             Type = Self::Type,
             Funclet = Self::Funclet,