X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_trans%2Ftrans%2Fcontext.rs;h=38459c1ec3cb7df05d8db83eddcbfc76906107c8;hb=303892ee156e5c31222b10786e661abb24dcf241;hp=c6ca2e176aa58913985241843d4d80bd3a73d350;hpb=eb1d018c01f70bcfc38bc8365a3de71c1564f694;p=rust.git diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index c6ca2e176aa..38459c1ec3c 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -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, String>>, use_dll_storage_attrs: bool, + + translation_items: RefCell, 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, - trait_cache: RefCell, - traits::Vtable<'tcx, ()>>>, + trait_cache: RefCell>>, +} + +// 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, - traits::Vtable<'tcx, ()>>> { + pub fn trait_cache(&self) -> &RefCell>> { &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, 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.