]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/trans/context.rs
Auto merge of #30448 - alexcrichton:llvmup, r=nikomatsakis
[rust.git] / src / librustc_trans / trans / context.rs
index c6ca2e176aa58913985241843d4d80bd3a73d350..38459c1ec3cb7df05d8db83eddcbfc76906107c8 100644 (file)
@@ -10,6 +10,7 @@
 
 use llvm;
 use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
+use rustc::dep_graph::{DepNode, DepTrackingMap, DepTrackingMapConfig};
 use middle::cstore::LinkMeta;
 use middle::def::ExportMap;
 use middle::def_id::DefId;
@@ -23,6 +24,7 @@
 use trans::declare;
 use trans::glue::DropGlueKind;
 use trans::monomorphize::MonoId;
+use trans::collector::{TransItem, TransItemState};
 use trans::type_::{Type, TypeNames};
 use middle::subst::Substs;
 use middle::ty::{self, Ty};
@@ -33,6 +35,7 @@
 
 use std::ffi::CString;
 use std::cell::{Cell, RefCell};
+use std::marker::PhantomData;
 use std::ptr;
 use std::rc::Rc;
 use syntax::ast;
@@ -75,6 +78,8 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
 
     available_drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, String>>,
     use_dll_storage_attrs: bool,
+
+    translation_items: RefCell<FnvHashMap<TransItem<'tcx>, TransItemState>>,
 }
 
 /// The local portion of a `CrateContext`.  There is one `LocalCrateContext`
@@ -161,8 +166,23 @@ pub struct LocalCrateContext<'tcx> {
     /// Depth of the current type-of computation - used to bail out
     type_of_depth: Cell<usize>,
 
-    trait_cache: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>,
-                                    traits::Vtable<'tcx, ()>>>,
+    trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
+}
+
+// Implement DepTrackingMapConfig for `trait_cache`
+pub struct TraitSelectionCache<'tcx> {
+    data: PhantomData<&'tcx ()>
+}
+
+impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
+    type Key = ty::PolyTraitRef<'tcx>;
+    type Value = traits::Vtable<'tcx, ()>;
+    fn to_dep_node(key: &ty::PolyTraitRef<'tcx>) -> DepNode {
+        ty::tls::with(|tcx| {
+            let lifted_key = tcx.lift(key).unwrap();
+            lifted_key.to_poly_trait_predicate().dep_node()
+        })
+    }
 }
 
 pub struct CrateContext<'a, 'tcx: 'a> {
@@ -228,7 +248,6 @@ fn next(&mut self) -> Option<(CrateContext<'a, 'tcx>, bool)> {
     }
 }
 
-
 unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
     let llcx = llvm::LLVMContextCreate();
     let mod_name = CString::new(mod_name).unwrap();
@@ -337,6 +356,7 @@ pub fn new(crate_name: &str,
             check_drop_flag_for_sanity: check_drop_flag_for_sanity,
             available_drop_glues: RefCell::new(FnvHashMap()),
             use_dll_storage_attrs: use_dll_storage_attrs,
+            translation_items: RefCell::new(FnvHashMap()),
         };
 
         for i in 0..local_count {
@@ -376,7 +396,7 @@ fn get_smallest_ccx<'a>(&'a self) -> CrateContext<'a, 'tcx> {
             self.local_ccxs
                 .iter()
                 .zip(0..self.local_ccxs.len())
-                .min_by(|&(local_ccx, _idx)| local_ccx.n_llvm_insns.get())
+                .min_by_key(|&(local_ccx, _idx)| local_ccx.n_llvm_insns.get())
                 .unwrap();
         CrateContext {
             shared: self,
@@ -478,7 +498,9 @@ fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
                 intrinsics: RefCell::new(FnvHashMap()),
                 n_llvm_insns: Cell::new(0),
                 type_of_depth: Cell::new(0),
-                trait_cache: RefCell::new(FnvHashMap()),
+                trait_cache: RefCell::new(DepTrackingMap::new(shared.tcx
+                                                                    .dep_graph
+                                                                    .clone())),
             };
 
             local_ccx.int_type = Type::int(&local_ccx.dummy_ccx(shared));
@@ -752,8 +774,7 @@ pub fn count_llvm_insn(&self) {
         self.local.n_llvm_insns.set(self.local.n_llvm_insns.get() + 1);
     }
 
-    pub fn trait_cache(&self) -> &RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>,
-                                                     traits::Vtable<'tcx, ()>>> {
+    pub fn trait_cache(&self) -> &RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>> {
         &self.local.trait_cache
     }
 
@@ -811,6 +832,24 @@ pub fn use_dll_storage_attrs(&self) -> bool {
     pub fn mir_map(&self) -> &'b MirMap<'tcx> {
         self.shared.mir_map
     }
+
+    pub fn translation_items(&self) -> &RefCell<FnvHashMap<TransItem<'tcx>, TransItemState>> {
+        &self.shared.translation_items
+    }
+
+    pub fn record_translation_item_as_generated(&self, cgi: TransItem<'tcx>) {
+        if self.sess().opts.debugging_opts.print_trans_items.is_none() {
+            return;
+        }
+
+        let mut codegen_items = self.translation_items().borrow_mut();
+
+        if codegen_items.contains_key(&cgi) {
+            codegen_items.insert(cgi, TransItemState::PredictedAndGenerated);
+        } else {
+            codegen_items.insert(cgi, TransItemState::NotPredictedButGenerated);
+        }
+    }
 }
 
 pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);
@@ -833,6 +872,16 @@ macro_rules! ifn {
                 return Some(f);
             }
         );
+        ($name:expr, fn(...) -> $ret:expr) => (
+            if key == $name {
+                let f = declare::declare_cfn(ccx, $name,
+                                             Type::variadic_func(&[], &$ret),
+                                             ccx.tcx().mk_nil());
+                llvm::SetUnnamedAddr(f, false);
+                ccx.intrinsics().borrow_mut().insert($name, f.clone());
+                return Some(f);
+            }
+        );
         ($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
             if key == $name {
                 let f = declare::declare_cfn(ccx, $name, Type::func(&[$($arg),*], &$ret),
@@ -841,7 +890,7 @@ macro_rules! ifn {
                 ccx.intrinsics().borrow_mut().insert($name, f.clone());
                 return Some(f);
             }
-        )
+        );
     }
     macro_rules! mk_struct {
         ($($field_ty:expr),*) => (Type::struct_(ccx, &[$($field_ty),*], false))
@@ -869,6 +918,7 @@ macro_rules! mk_struct {
 
     ifn!("llvm.trap", fn() -> void);
     ifn!("llvm.debugtrap", fn() -> void);
+    ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
 
     ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
     ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
@@ -969,6 +1019,9 @@ macro_rules! mk_struct {
 
     ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
     ifn!("llvm.eh.typeid.for", fn(i8p) -> t_i32);
+    ifn!("llvm.localescape", fn(...) -> void);
+    ifn!("llvm.localrecover", fn(i8p, i8p, t_i32) -> i8p);
+    ifn!("llvm.x86.seh.recoverfp", fn(i8p, i8p) -> i8p);
 
     // Some intrinsics were introduced in later versions of LLVM, but they have
     // fallbacks in libc or libm and such.