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;
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};
use std::ffi::CString;
use std::cell::{Cell, RefCell};
+use std::marker::PhantomData;
use std::ptr;
use std::rc::Rc;
use syntax::ast;
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`
/// 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> {
}
}
-
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();
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 {
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,
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));
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
}
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>);
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),
ccx.intrinsics().borrow_mut().insert($name, f.clone());
return Some(f);
}
- )
+ );
}
macro_rules! mk_struct {
($($field_ty:expr),*) => (Type::struct_(ccx, &[$($field_ty),*], false))
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);
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.