X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_trans%2Ftrans%2Fcontext.rs;h=38459c1ec3cb7df05d8db83eddcbfc76906107c8;hb=303892ee156e5c31222b10786e661abb24dcf241;hp=a14663483a91bfe28383ec16b82f6689c146236e;hpb=427140f771828d5a2fce7a21d97359d2967c3239;p=rust.git diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index a14663483a9..38459c1ec3c 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -10,10 +10,12 @@ use llvm; use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef}; -use metadata::common::LinkMeta; +use rustc::dep_graph::{DepNode, DepTrackingMap, DepTrackingMapConfig}; +use middle::cstore::LinkMeta; use middle::def::ExportMap; use middle::def_id::DefId; use middle::traits; +use rustc_mir::mir_map::MirMap; use trans::adt; use trans::base; use trans::builder::Builder; @@ -22,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}; @@ -32,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; @@ -70,9 +74,12 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { stats: Stats, check_overflow: bool, check_drop_flag_for_sanity: bool, + mir_map: &'a MirMap<'tcx>, available_drop_glues: RefCell, String>>, use_dll_storage_attrs: bool, + + translation_items: RefCell, TransItemState>>, } /// The local portion of a `CrateContext`. There is one `LocalCrateContext` @@ -146,8 +153,8 @@ pub struct LocalCrateContext<'tcx> { dbg_cx: Option>, eh_personality: RefCell>, + eh_unwind_resume: RefCell>, rust_try_fn: RefCell>, - unwind_resume_hooked: Cell, intrinsics: RefCell>, @@ -159,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> { @@ -226,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(); @@ -251,6 +272,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { pub fn new(crate_name: &str, local_count: usize, tcx: &'b ty::ctxt<'tcx>, + mir_map: &'b MirMap<'tcx>, export_map: ExportMap, symbol_hasher: Sha256, link_meta: LinkMeta, @@ -317,6 +339,7 @@ pub fn new(crate_name: &str, link_meta: link_meta, symbol_hasher: RefCell::new(symbol_hasher), tcx: tcx, + mir_map: mir_map, stats: Stats { n_glues_created: Cell::new(0), n_null_glues: Cell::new(0), @@ -333,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 { @@ -372,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, @@ -469,12 +493,14 @@ fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>, closure_vals: RefCell::new(FnvHashMap()), dbg_cx: dbg_cx, eh_personality: RefCell::new(None), + eh_unwind_resume: RefCell::new(None), rust_try_fn: RefCell::new(None), - unwind_resume_hooked: Cell::new(false), 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)); @@ -732,12 +758,12 @@ pub fn eh_personality<'a>(&'a self) -> &'a RefCell> { &self.local.eh_personality } - pub fn rust_try_fn<'a>(&'a self) -> &'a RefCell> { - &self.local.rust_try_fn + pub fn eh_unwind_resume<'a>(&'a self) -> &'a RefCell> { + &self.local.eh_unwind_resume } - pub fn unwind_resume_hooked<'a>(&'a self) -> &'a Cell { - &self.local.unwind_resume_hooked + pub fn rust_try_fn<'a>(&'a self) -> &'a RefCell> { + &self.local.rust_try_fn } fn intrinsics<'a>(&'a self) -> &'a RefCell> { @@ -748,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 } @@ -803,6 +828,28 @@ pub fn check_drop_flag_for_sanity(&self) -> bool { pub fn use_dll_storage_attrs(&self) -> bool { self.shared.use_dll_storage_attrs() } + + 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>); @@ -825,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), @@ -833,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)) @@ -861,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); @@ -961,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.