about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm
diff options
context:
space:
mode:
authorDenis Merigoux <denis.merigoux@gmail.com>2018-09-21 16:13:15 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2018-11-16 14:34:26 +0200
commit441a7c10921341ca72423cd6230f9dee82a8dc47 (patch)
treeb07bca0fd22cc58917c94fca2839cf9330526078 /src/librustc_codegen_llvm
parent6a993fe353e1290d1e89345494ba389f6f1dae5e (diff)
downloadrust-441a7c10921341ca72423cd6230f9dee82a8dc47.tar.gz
rust-441a7c10921341ca72423cd6230f9dee82a8dc47.zip
Generalized mono_item.rs and base.rs:codegen_instance
Diffstat (limited to 'src/librustc_codegen_llvm')
-rw-r--r--src/librustc_codegen_llvm/base.rs38
-rw-r--r--src/librustc_codegen_llvm/context.rs8
-rw-r--r--src/librustc_codegen_llvm/interfaces/declare.rs20
-rw-r--r--src/librustc_codegen_llvm/interfaces/misc.rs5
-rw-r--r--src/librustc_codegen_llvm/interfaces/mod.rs4
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs151
6 files changed, 136 insertions, 90 deletions
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index c58e548f69d..d55c156cead 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -39,7 +39,7 @@ use rustc::middle::weak_lang_items;
 use rustc::mir::mono::{Linkage, Visibility, Stats, CodegenUnitNameBuilder};
 use rustc::middle::cstore::{EncodedMetadata};
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx};
+use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt};
 use rustc::ty::query::Providers;
 use rustc::middle::cstore::{self, LinkagePreference};
 use rustc::middle::exported_symbols;
@@ -76,6 +76,7 @@ use interfaces::*;
 use std::any::Any;
 use std::cmp;
 use std::ffi::CString;
+use std::marker;
 use std::ops::{Deref, DerefMut};
 use std::sync::mpsc;
 use std::time::{Instant, Duration};
@@ -90,27 +91,29 @@ use mir::operand::OperandValue;
 
 use rustc_codegen_utils::check_for_rustc_errors_attr;
 
-pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> {
-    cx: &'a CodegenCx<'ll, 'tcx>,
+pub struct StatRecorder<'a, 'tcx, Cx: 'a + CodegenMethods<'tcx>> {
+    cx: &'a Cx,
     name: Option<String>,
     istart: usize,
+    _marker: marker::PhantomData<&'tcx ()>,
 }
 
-impl StatRecorder<'a, 'll, 'tcx> {
-    pub fn new(cx: &'a CodegenCx<'ll, 'tcx>, name: String) -> Self {
-        let istart = cx.stats.borrow().n_llvm_insns;
+impl<'a, 'tcx, Cx: CodegenMethods<'tcx>> StatRecorder<'a, 'tcx, Cx> {
+    pub fn new(cx: &'a Cx, name: String) -> Self {
+        let istart = cx.stats().borrow().n_llvm_insns;
         StatRecorder {
             cx,
             name: Some(name),
             istart,
+            _marker: marker::PhantomData,
         }
     }
 }
 
-impl Drop for StatRecorder<'a, 'll, 'tcx> {
+impl<'a, 'tcx, Cx: CodegenMethods<'tcx>> Drop for StatRecorder<'a, 'tcx, Cx> {
     fn drop(&mut self) {
         if self.cx.sess().codegen_stats() {
-            let mut stats = self.cx.stats.borrow_mut();
+            let mut stats = self.cx.stats().borrow_mut();
             let iend = stats.n_llvm_insns;
             stats.fn_stats.push((self.name.take().unwrap(), iend - self.istart));
             stats.n_fns += 1;
@@ -449,10 +452,13 @@ pub fn memcpy_ty<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
     bx.memcpy(dst, dst_align, src, src_align, bx.cx().const_usize(size), flags);
 }
 
-pub fn codegen_instance(cx: &CodegenCx<'_, 'tcx>, instance: Instance<'tcx>) {
+pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
+    cx: &'a Bx::CodegenCx,
+    instance: Instance<'tcx>,
+) {
     let _s = if cx.sess().codegen_stats() {
         let mut instance_name = String::new();
-        DefPathBasedNames::new(cx.tcx, true, true)
+        DefPathBasedNames::new(cx.tcx(), true, true)
             .push_def_path(instance.def_id(), &mut instance_name);
         Some(StatRecorder::new(cx, instance_name))
     } else {
@@ -464,16 +470,16 @@ pub fn codegen_instance(cx: &CodegenCx<'_, 'tcx>, instance: Instance<'tcx>) {
     // release builds.
     info!("codegen_instance({})", instance);
 
-    let sig = instance.fn_sig(cx.tcx);
-    let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
+    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(||
+    let lldecl = cx.instances().borrow().get(&instance).cloned().unwrap_or_else(||
         bug!("Instance `{:?}` not already declared", instance));
 
-    cx.stats.borrow_mut().n_closures += 1;
+    cx.stats().borrow_mut().n_closures += 1;
 
-    let mir = cx.tcx.instance_mir(instance.def);
-    mir::codegen_mir::<Builder>(cx, lldecl, &mir, instance, sig);
+    let mir = cx.tcx().instance_mir(instance.def);
+    mir::codegen_mir::<Bx>(cx, lldecl, &mir, instance, sig);
 }
 
 pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index d7f850b84a9..1ccab0ec81a 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -417,6 +417,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn check_overflow(&self) -> bool {
         self.check_overflow
     }
+
+    fn stats(&self) -> &RefCell<Stats> {
+        &self.stats
+    }
+
+    fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>> {
+        &self.codegen_unit
+    }
 }
 
 impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {
diff --git a/src/librustc_codegen_llvm/interfaces/declare.rs b/src/librustc_codegen_llvm/interfaces/declare.rs
index d8a7382e45f..e3cdc93e5d2 100644
--- a/src/librustc_codegen_llvm/interfaces/declare.rs
+++ b/src/librustc_codegen_llvm/interfaces/declare.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 use super::backend::Backend;
+use monomorphize::Instance;
+use rustc::hir::def_id::DefId;
+use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty;
 
 pub trait DeclareMethods<'tcx>: Backend<'tcx> {
@@ -22,3 +25,20 @@ pub trait DeclareMethods<'tcx>: Backend<'tcx> {
     fn get_declared_value(&self, name: &str) -> Option<Self::Value>;
     fn get_defined_value(&self, name: &str) -> Option<Self::Value>;
 }
+
+pub trait PreDefineMethods<'tcx>: Backend<'tcx> {
+    fn predefine_static(
+        &self,
+        def_id: DefId,
+        linkage: Linkage,
+        visibility: Visibility,
+        symbol_name: &str,
+    );
+    fn predefine_fn(
+        &self,
+        instance: Instance<'tcx>,
+        linkage: Linkage,
+        visibility: Visibility,
+        symbol_name: &str,
+    );
+}
diff --git a/src/librustc_codegen_llvm/interfaces/misc.rs b/src/librustc_codegen_llvm/interfaces/misc.rs
index eb278a36b09..a9e6f930a8d 100644
--- a/src/librustc_codegen_llvm/interfaces/misc.rs
+++ b/src/librustc_codegen_llvm/interfaces/misc.rs
@@ -10,10 +10,13 @@
 
 use super::backend::Backend;
 use libc::c_uint;
+use monomorphize::partitioning::CodegenUnit;
+use rustc::mir::mono::Stats;
 use rustc::session::Session;
 use rustc::ty::{self, Instance, Ty};
 use rustc::util::nodemap::FxHashMap;
 use std::cell::RefCell;
+use std::sync::Arc;
 
 pub trait MiscMethods<'tcx>: Backend<'tcx> {
     fn vtables(
@@ -26,4 +29,6 @@ pub trait MiscMethods<'tcx>: Backend<'tcx> {
     fn eh_personality(&self) -> Self::Value;
     fn eh_unwind_resume(&self) -> Self::Value;
     fn sess(&self) -> &Session;
+    fn stats(&self) -> &RefCell<Stats>;
+    fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
 }
diff --git a/src/librustc_codegen_llvm/interfaces/mod.rs b/src/librustc_codegen_llvm/interfaces/mod.rs
index d1365fb62a6..6ff66261416 100644
--- a/src/librustc_codegen_llvm/interfaces/mod.rs
+++ b/src/librustc_codegen_llvm/interfaces/mod.rs
@@ -26,7 +26,7 @@ pub use self::backend::{Backend, BackendTypes};
 pub use self::builder::BuilderMethods;
 pub use self::consts::ConstMethods;
 pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
-pub use self::declare::DeclareMethods;
+pub use self::declare::{DeclareMethods, PreDefineMethods};
 pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods};
 pub use self::misc::MiscMethods;
 pub use self::statics::StaticMethods;
@@ -47,6 +47,7 @@ pub trait CodegenMethods<'tcx>:
     + IntrinsicDeclarationMethods<'tcx>
     + DeclareMethods<'tcx>
     + AsmMethods<'tcx>
+    + PreDefineMethods<'tcx>
 {
 }
 
@@ -61,6 +62,7 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
         + IntrinsicDeclarationMethods<'tcx>
         + DeclareMethods<'tcx>
         + AsmMethods<'tcx>
+        + PreDefineMethods<'tcx>
 {}
 
 pub trait HasCodegen<'tcx>: Backend<'tcx> {
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index 2e54c52cb0e..041cfbf00c6 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -25,24 +25,27 @@ use rustc::hir::def::Def;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty::TypeFoldable;
-use rustc::ty::layout::LayoutOf;
+use rustc::ty::layout::{LayoutOf, HasTyCtxt};
 use std::fmt;
+use builder::Builder;
 use interfaces::*;
 
 pub use rustc::mir::mono::MonoItem;
 
 pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt;
 
-pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
-    fn define(&self, cx: &CodegenCx<'a, 'tcx>) {
+pub trait MonoItemExt<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> :
+    fmt::Debug + BaseMonoItemExt<'a, 'tcx>
+{
+    fn define(&self, cx: &'a Bx::CodegenCx) {
         debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}",
-               self.to_string(cx.tcx),
+               self.to_string(cx.tcx()),
                self.to_raw_string(),
-               cx.codegen_unit.name());
+               cx.codegen_unit().name());
 
         match *self.as_mono_item() {
             MonoItem::Static(def_id) => {
-                let tcx = cx.tcx;
+                let tcx = cx.tcx();
                 let is_mutable = match tcx.describe_def(def_id) {
                     Some(Def::Static(_, is_mutable)) => is_mutable,
                     Some(other) => {
@@ -55,7 +58,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
                 cx.codegen_static(def_id, is_mutable);
             }
             MonoItem::GlobalAsm(node_id) => {
-                let item = cx.tcx.hir.expect_item(node_id);
+                let item = cx.tcx().hir.expect_item(node_id);
                 if let hir::ItemKind::GlobalAsm(ref ga) = item.node {
                     cx.codegen_global_asm(ga);
                 } else {
@@ -63,43 +66,43 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
                 }
             }
             MonoItem::Fn(instance) => {
-                base::codegen_instance(&cx, instance);
+                base::codegen_instance::<Bx>(&cx, instance);
             }
         }
 
         debug!("END IMPLEMENTING '{} ({})' in cgu {}",
-               self.to_string(cx.tcx),
+               self.to_string(cx.tcx()),
                self.to_raw_string(),
-               cx.codegen_unit.name());
+               cx.codegen_unit().name());
     }
 
     fn predefine(&self,
-                 cx: &CodegenCx<'a, 'tcx>,
+                 cx: &'a Bx::CodegenCx,
                  linkage: Linkage,
                  visibility: Visibility) {
         debug!("BEGIN PREDEFINING '{} ({})' in cgu {}",
-               self.to_string(cx.tcx),
+               self.to_string(cx.tcx()),
                self.to_raw_string(),
-               cx.codegen_unit.name());
+               cx.codegen_unit().name());
 
-        let symbol_name = self.symbol_name(cx.tcx).as_str();
+        let symbol_name = self.symbol_name(cx.tcx()).as_str();
 
         debug!("symbol {}", &symbol_name);
 
         match *self.as_mono_item() {
             MonoItem::Static(def_id) => {
-                predefine_static(cx, def_id, linkage, visibility, &symbol_name);
+                cx.predefine_static(def_id, linkage, visibility, &symbol_name);
             }
             MonoItem::Fn(instance) => {
-                predefine_fn(cx, instance, linkage, visibility, &symbol_name);
+                cx.predefine_fn(instance, linkage, visibility, &symbol_name);
             }
             MonoItem::GlobalAsm(..) => {}
         }
 
         debug!("END PREDEFINING '{} ({})' in cgu {}",
-               self.to_string(cx.tcx),
+               self.to_string(cx.tcx()),
                self.to_raw_string(),
-               cx.codegen_unit.name());
+               cx.codegen_unit().name());
     }
 
     fn to_raw_string(&self) -> String {
@@ -119,68 +122,70 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {}
+impl MonoItemExt<'a, 'tcx, Builder<'a, 'll, 'tcx>> for MonoItem<'tcx> {}
 
-fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
-                              def_id: DefId,
-                              linkage: Linkage,
-                              visibility: Visibility,
-                              symbol_name: &str) {
-    let instance = Instance::mono(cx.tcx, def_id);
-    let ty = instance.ty(cx.tcx);
-    let llty = cx.layout_of(ty).llvm_type(cx);
-
-    let g = cx.define_global(symbol_name, llty).unwrap_or_else(|| {
-        cx.sess().span_fatal(cx.tcx.def_span(def_id),
-            &format!("symbol `{}` is already defined", symbol_name))
-    });
-
-    unsafe {
-        llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage));
-        llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility));
-    }
+impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+    fn predefine_static(&self,
+                                  def_id: DefId,
+                                  linkage: Linkage,
+                                  visibility: Visibility,
+                                  symbol_name: &str) {
+        let instance = Instance::mono(self.tcx, def_id);
+        let ty = instance.ty(self.tcx);
+        let llty = self.layout_of(ty).llvm_type(self);
 
-    cx.instances.borrow_mut().insert(instance, g);
-}
+        let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {
+            self.sess().span_fatal(self.tcx.def_span(def_id),
+                &format!("symbol `{}` is already defined", symbol_name))
+        });
 
-fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
-                          instance: Instance<'tcx>,
-                          linkage: Linkage,
-                          visibility: Visibility,
-                          symbol_name: &str) {
-    assert!(!instance.substs.needs_infer() &&
-            !instance.substs.has_param_types());
-
-    let mono_sig = instance.fn_sig(cx.tcx);
-    let attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
-    let lldecl = cx.declare_fn(symbol_name, mono_sig);
-    unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
-    base::set_link_section(lldecl, &attrs);
-    if linkage == Linkage::LinkOnceODR ||
-        linkage == Linkage::WeakODR {
-        llvm::SetUniqueComdat(cx.llmod, lldecl);
+        unsafe {
+            llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage));
+            llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility));
+        }
+
+        self.instances.borrow_mut().insert(instance, g);
     }
 
-    // If we're compiling the compiler-builtins crate, e.g. the equivalent of
-    // compiler-rt, then we want to implicitly compile everything with hidden
-    // visibility as we're going to link this object all over the place but
-    // don't want the symbols to get exported.
-    if linkage != Linkage::Internal && linkage != Linkage::Private &&
-       cx.tcx.is_compiler_builtins(LOCAL_CRATE) {
-        unsafe {
-            llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden);
+    fn predefine_fn(&self,
+                              instance: Instance<'tcx>,
+                              linkage: Linkage,
+                              visibility: Visibility,
+                              symbol_name: &str) {
+        assert!(!instance.substs.needs_infer() &&
+                !instance.substs.has_param_types());
+
+        let mono_sig = instance.fn_sig(self.tcx());
+        let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
+        let lldecl = self.declare_fn(symbol_name, mono_sig);
+        unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
+        base::set_link_section(lldecl, &attrs);
+        if linkage == Linkage::LinkOnceODR ||
+            linkage == Linkage::WeakODR {
+            llvm::SetUniqueComdat(self.llmod, lldecl);
         }
-    } else {
-        unsafe {
-            llvm::LLVMRustSetVisibility(lldecl, base::visibility_to_llvm(visibility));
+
+        // If we're compiling the compiler-builtins crate, e.g. the equivalent of
+        // compiler-rt, then we want to implicitly compile everything with hidden
+        // visibility as we're going to link this object all over the place but
+        // don't want the symbols to get exported.
+        if linkage != Linkage::Internal && linkage != Linkage::Private &&
+           self.tcx.is_compiler_builtins(LOCAL_CRATE) {
+            unsafe {
+                llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden);
+            }
+        } else {
+            unsafe {
+                llvm::LLVMRustSetVisibility(lldecl, base::visibility_to_llvm(visibility));
+            }
         }
-    }
 
-    debug!("predefine_fn: mono_sig = {:?} instance = {:?}", mono_sig, instance);
-    if instance.def.is_inline(cx.tcx) {
-        attributes::inline(cx, lldecl, attributes::InlineAttr::Hint);
-    }
-    attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id()));
+        debug!("predefine_fn: mono_sig = {:?} instance = {:?}", mono_sig, instance);
+        if instance.def.is_inline(self.tcx) {
+            attributes::inline(self, lldecl, attributes::InlineAttr::Hint);
+        }
+        attributes::from_fn_attrs(self, lldecl, Some(instance.def.def_id()));
 
-    cx.instances.borrow_mut().insert(instance, lldecl);
+        self.instances.borrow_mut().insert(instance, lldecl);
+    }
 }