diff options
| -rw-r--r-- | src/librustc_trans/base.rs | 119 | ||||
| -rw-r--r-- | src/librustc_trans/context.rs | 97 |
2 files changed, 62 insertions, 154 deletions
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index a034974cb13..30916167621 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -38,7 +38,7 @@ use rustc::hir::def_id::LOCAL_CRATE; use middle::lang_items::StartFnLangItem; use middle::cstore::EncodedMetadata; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::dep_graph::{AssertDepGraphSafe, DepNode, WorkProduct}; +use rustc::dep_graph::{AssertDepGraphSafe, DepNode}; use rustc::hir::map as hir_map; use rustc::util::common::time; use session::config::{self, NoDebugInfo}; @@ -56,7 +56,7 @@ use common::CrateContext; use common::{type_is_zero_size, val_ty}; use common; use consts; -use context::{self, SharedCrateContext, CrateContextList}; +use context::{self, LocalCrateContext, SharedCrateContext}; use debuginfo; use declare; use machine; @@ -1113,41 +1113,61 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let symbol_map = Rc::new(symbol_map); - let previous_work_products = trans_reuse_previous_work_products(&shared_ccx, - &codegen_units, - &symbol_map); - - let crate_context_list = CrateContextList::new(&shared_ccx, - codegen_units, - previous_work_products, - symbol_map.clone()); - - let modules: Vec<ModuleTranslation> = crate_context_list - .iter_all() - .map(|ccx| { - let dep_node = ccx.codegen_unit().work_product_dep_node(); + let modules: Vec<ModuleTranslation> = codegen_units + .into_iter() + .map(|cgu| { + let dep_node = cgu.work_product_dep_node(); tcx.dep_graph.with_task(dep_node, - ccx, - AssertDepGraphSafe(symbol_map.clone()), + AssertDepGraphSafe(&shared_ccx), + AssertDepGraphSafe((cgu, symbol_map.clone())), module_translation) }) .collect(); - fn module_translation<'a, 'tcx>(ccx: CrateContext<'a, 'tcx>, - symbol_map: AssertDepGraphSafe<Rc<SymbolMap<'tcx>>>) - -> ModuleTranslation { - // FIXME(#40304): Instead of this, the symbol-map should be an - // on-demand thing that we compute. - let AssertDepGraphSafe(symbol_map) = symbol_map; + fn module_translation<'a, 'tcx>( + scx: AssertDepGraphSafe<&SharedCrateContext<'a, 'tcx>>, + args: AssertDepGraphSafe<(CodegenUnit<'tcx>, Rc<SymbolMap<'tcx>>)>) + -> ModuleTranslation + { + // FIXME(#40304): We ought to be using the id as a key and some queries, I think. + let AssertDepGraphSafe(scx) = scx; + let AssertDepGraphSafe((cgu, symbol_map)) = args; + + let cgu_name = String::from(cgu.name()); + let cgu_id = cgu.work_product_id(); + let symbol_name_hash = cgu.compute_symbol_name_hash(scx, &symbol_map); + + // Check whether there is a previous work-product we can + // re-use. Not only must the file exist, and the inputs not + // be dirty, but the hash of the symbols we will generate must + // be the same. + let previous_work_product = + scx.dep_graph().previous_work_product(&cgu_id).and_then(|work_product| { + if work_product.input_hash == symbol_name_hash { + debug!("trans_reuse_previous_work_products: reusing {:?}", work_product); + Some(work_product) + } else { + if scx.sess().opts.debugging_opts.incremental_info { + println!("incremental: CGU `{}` invalidated because of \ + changed partitioning hash.", + cgu.name()); + } + debug!("trans_reuse_previous_work_products: \ + not reusing {:?} because hash changed to {:?}", + work_product, symbol_name_hash); + None + } + }); - let source = if let Some(buf) = ccx.previous_work_product() { + let source = if let Some(buf) = previous_work_product { // Don't need to translate this module. ModuleSource::Preexisting(buf.clone()) } else { // Instantiate translation items without filling out definitions yet... - - let cgu = ccx.codegen_unit(); - let trans_items = cgu.items_in_deterministic_order(ccx.tcx(), &symbol_map); + let lcx = LocalCrateContext::new(scx, cgu, symbol_map.clone()); + let ccx = CrateContext::new(scx, &lcx); + let trans_items = ccx.codegen_unit() + .items_in_deterministic_order(ccx.tcx(), &symbol_map); for &(trans_item, linkage) in &trans_items { trans_item.predefine(&ccx, linkage); } @@ -1199,11 +1219,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; ModuleTranslation { - name: String::from(ccx.codegen_unit().name()), - symbol_name_hash: ccx.codegen_unit() - .compute_symbol_name_hash(ccx.shared(), - &symbol_map), - source: source, + name: cgu_name, + symbol_name_hash, + source, } } @@ -1487,43 +1505,6 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { } } -/// For each CGU, identify if we can reuse an existing object file (or -/// maybe other context). -fn trans_reuse_previous_work_products(scx: &SharedCrateContext, - codegen_units: &[CodegenUnit], - symbol_map: &SymbolMap) - -> Vec<Option<WorkProduct>> { - debug!("trans_reuse_previous_work_products()"); - codegen_units - .iter() - .map(|cgu| { - let id = cgu.work_product_id(); - - let hash = cgu.compute_symbol_name_hash(scx, symbol_map); - - debug!("trans_reuse_previous_work_products: id={:?} hash={}", id, hash); - - if let Some(work_product) = scx.dep_graph().previous_work_product(&id) { - if work_product.input_hash == hash { - debug!("trans_reuse_previous_work_products: reusing {:?}", work_product); - return Some(work_product); - } else { - if scx.sess().opts.debugging_opts.incremental_info { - println!("incremental: CGU `{}` invalidated because of \ - changed partitioning hash.", - cgu.name()); - } - debug!("trans_reuse_previous_work_products: \ - not reusing {:?} because hash changed to {:?}", - work_product, hash); - } - } - - None - }) - .collect() -} - fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>) -> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) { let time_passes = scx.sess().time_passes(); diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index e3b1e04c530..80d6f15518f 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -10,8 +10,7 @@ use llvm; use llvm::{ContextRef, ModuleRef, ValueRef}; -use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap, - DepTrackingMapConfig, WorkProduct}; +use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap, DepTrackingMapConfig}; use middle::cstore::LinkMeta; use rustc::hir; use rustc::hir::def_id::DefId; @@ -86,7 +85,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { pub struct LocalCrateContext<'tcx> { llmod: ModuleRef, llcx: ContextRef, - previous_work_product: Option<WorkProduct>, codegen_unit: CodegenUnit<'tcx>, needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>, /// Cache instances of monomorphic and polymorphic items @@ -211,41 +209,6 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> { } } -/// This list owns a number of LocalCrateContexts and binds them to their common -/// SharedCrateContext. This type just exists as a convenience, something to -/// pass around all LocalCrateContexts with and get an iterator over them. -pub struct CrateContextList<'a, 'tcx: 'a> { - shared: &'a SharedCrateContext<'a, 'tcx>, - local_ccxs: Vec<LocalCrateContext<'tcx>>, -} - -impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> { - pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>, - codegen_units: Vec<CodegenUnit<'tcx>>, - previous_work_products: Vec<Option<WorkProduct>>, - symbol_map: Rc<SymbolMap<'tcx>>) - -> CrateContextList<'a, 'tcx> { - CrateContextList { - shared: shared_ccx, - local_ccxs: codegen_units.into_iter().zip(previous_work_products).map(|(cgu, wp)| { - LocalCrateContext::new(shared_ccx, cgu, wp, symbol_map.clone()) - }).collect() - } - } - - /// Iterate over all crate contexts, whether or not they need - /// translation. That is, whether or not a `.o` file is available - /// for re-use from a previous incr. comp.). - pub fn iter_all<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> { - CrateContextIterator { - shared: self.shared, - index: 0, - local_ccxs: &self.local_ccxs[..], - filter_to_previous_work_product_unavail: false, - } - } -} - /// A CrateContext value binds together one LocalCrateContext with the /// SharedCrateContext. It exists as a convenience wrapper, so we don't have to /// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans. @@ -254,45 +217,15 @@ pub struct CrateContext<'a, 'tcx: 'a> { local_ccx: &'a LocalCrateContext<'tcx>, } -impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> { -} - -pub struct CrateContextIterator<'a, 'tcx: 'a> { - shared: &'a SharedCrateContext<'a, 'tcx>, - local_ccxs: &'a [LocalCrateContext<'tcx>], - index: usize, - - /// if true, only return results where `previous_work_product` is none - filter_to_previous_work_product_unavail: bool, +impl<'a, 'tcx> CrateContext<'a, 'tcx> { + pub fn new(shared: &'a SharedCrateContext<'a, 'tcx>, + local_ccx: &'a LocalCrateContext<'tcx>) + -> Self { + CrateContext { shared, local_ccx } + } } -impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> { - type Item = CrateContext<'a, 'tcx>; - - fn next(&mut self) -> Option<CrateContext<'a, 'tcx>> { - loop { - if self.index >= self.local_ccxs.len() { - return None; - } - - let index = self.index; - self.index += 1; - - let ccx = CrateContext { - shared: self.shared, - local_ccx: &self.local_ccxs[index], - }; - - if - self.filter_to_previous_work_product_unavail && - ccx.previous_work_product().is_some() - { - continue; - } - - return Some(ccx); - } - } +impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> { } pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode { @@ -512,11 +445,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { } impl<'tcx> LocalCrateContext<'tcx> { - fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>, - codegen_unit: CodegenUnit<'tcx>, - previous_work_product: Option<WorkProduct>, - symbol_map: Rc<SymbolMap<'tcx>>) - -> LocalCrateContext<'tcx> { + pub fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>, + codegen_unit: CodegenUnit<'tcx>, + symbol_map: Rc<SymbolMap<'tcx>>) + -> LocalCrateContext<'tcx> { unsafe { // Append ".rs" to LLVM module identifier. // @@ -542,7 +474,6 @@ impl<'tcx> LocalCrateContext<'tcx> { let local_ccx = LocalCrateContext { llmod: llmod, llcx: llcx, - previous_work_product: previous_work_product, codegen_unit: codegen_unit, needs_unwind_cleanup_cache: RefCell::new(FxHashMap()), instances: RefCell::new(FxHashMap()), @@ -651,10 +582,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.local().llcx } - pub fn previous_work_product(&self) -> Option<&WorkProduct> { - self.local().previous_work_product.as_ref() - } - pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> { &self.local().codegen_unit } |
