]> git.lizzy.rs Git - rust.git/commitdiff
incr.comp.: Use red/green tracking for CGU re-use.
authorMichael Woerister <michaelwoerister@posteo>
Thu, 28 Sep 2017 09:58:45 +0000 (11:58 +0200)
committerMichael Woerister <michaelwoerister@posteo>
Mon, 2 Oct 2017 13:45:46 +0000 (15:45 +0200)
30 files changed:
src/librustc/dep_graph/graph.rs
src/librustc/ty/maps/plumbing.rs
src/librustc_incremental/lib.rs
src/librustc_incremental/persist/load.rs
src/librustc_incremental/persist/mod.rs
src/librustc_incremental/persist/work_product.rs
src/librustc_trans/assert_module_sources.rs
src/librustc_trans/back/symbol_export.rs
src/librustc_trans/back/write.rs
src/librustc_trans/base.rs
src/librustc_trans/callee.rs
src/librustc_trans/collector.rs
src/librustc_trans/consts.rs
src/librustc_trans/lib.rs
src/librustc_trans/partitioning.rs
src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs
src/test/incremental/cache_file_headers.rs
src/test/incremental/callee_caller_cross_crate/b.rs
src/test/incremental/change_private_fn_cc/struct_point.rs
src/test/incremental/change_private_impl_method_cc/struct_point.rs
src/test/incremental/change_symbol_export_status.rs
src/test/incremental/commandline-args.rs
src/test/incremental/issue-35593.rs
src/test/incremental/issue-38222.rs
src/test/incremental/remapped_paths_cc/main.rs
src/test/incremental/remove-private-item-cross-crate/main.rs
src/test/incremental/rlib_cross_crate/b.rs
src/test/incremental/spike.rs
src/test/incremental/struct_change_field_type_cross_crate/b.rs
src/test/incremental/type_alias_cross_crate/b.rs

index 1fccde12d18ab713b9d8639a23759e0bd6f64720..cc15922bc2ea83e20cc57b9fa172cf5ad6ef9461 100644 (file)
@@ -67,6 +67,15 @@ pub enum DepNodeColor {
     Green(DepNodeIndex)
 }
 
+impl DepNodeColor {
+    pub fn is_green(self) -> bool {
+        match self {
+            DepNodeColor::Red => false,
+            DepNodeColor::Green(_) => true,
+        }
+    }
+}
+
 struct DepGraphData {
     /// The old, initial encoding of the dependency graph. This will soon go
     /// away.
@@ -94,6 +103,9 @@ struct DepGraphData {
     work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,
 
     dep_node_debug: RefCell<FxHashMap<DepNode, String>>,
+
+    // Used for testing, only populated when -Zquery-dep-graph is specified.
+    loaded_from_cache: RefCell<FxHashMap<DepNodeIndexNew, bool>>,
 }
 
 impl DepGraph {
@@ -108,6 +120,7 @@ pub fn new(prev_graph: PreviousDepGraph) -> DepGraph {
                 current: RefCell::new(CurrentDepGraph::new()),
                 previous: prev_graph,
                 colors: RefCell::new(FxHashMap()),
+                loaded_from_cache: RefCell::new(FxHashMap()),
             })),
             fingerprints: Rc::new(RefCell::new(FxHashMap())),
         }
@@ -256,16 +269,9 @@ pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeInde
             data.current.borrow_mut().push_anon_task();
             let result = op();
             let dep_node_index_legacy = data.edges.borrow_mut().pop_anon_task(dep_kind);
-            let (new_dep_node, dep_node_index_new) = data.current
-                                                         .borrow_mut()
-                                                         .pop_anon_task(dep_kind);
-            if let Some(new_dep_node) = new_dep_node {
-                assert!(data.colors
-                            .borrow_mut()
-                            .insert(new_dep_node, DepNodeColor::Red)
-                            .is_none());
-            }
-
+            let dep_node_index_new = data.current
+                                         .borrow_mut()
+                                         .pop_anon_task(dep_kind);
             (result, DepNodeIndex {
                 legacy: dep_node_index_legacy,
                 new: dep_node_index_new,
@@ -594,6 +600,25 @@ pub fn is_green(&self, dep_node_index: DepNodeIndex) -> bool {
             }
         }).unwrap_or(false)
     }
+
+    pub fn mark_loaded_from_cache(&self, dep_node: DepNodeIndex, state: bool) {
+        debug!("mark_loaded_from_cache({:?}, {})",
+               self.data.as_ref().unwrap().current.borrow().nodes[dep_node.new],
+               state);
+
+        self.data
+            .as_ref()
+            .unwrap()
+            .loaded_from_cache
+            .borrow_mut()
+            .insert(dep_node.new, state);
+    }
+
+    pub fn was_loaded_from_cache(&self, dep_node: &DepNode) -> Option<bool> {
+        let data = self.data.as_ref().unwrap();
+        let dep_node_index = data.current.borrow().node_to_node_index[dep_node];
+        data.loaded_from_cache.borrow().get(&dep_node_index).cloned()
+    }
 }
 
 /// A "work product" is an intermediate result that we save into the
@@ -630,11 +655,6 @@ pub fn is_green(&self, dep_node_index: DepNodeIndex) -> bool {
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct WorkProduct {
     pub cgu_name: String,
-    /// Extra hash used to decide if work-product is still suitable;
-    /// note that this is *not* a hash of the work-product itself.
-    /// See documentation on `WorkProduct` type for an example.
-    pub input_hash: u64,
-
     /// Saved files associated with this CGU
     pub saved_files: Vec<(OutputType, String)>,
 }
@@ -644,15 +664,26 @@ pub(super) struct CurrentDepGraph {
     edges: IndexVec<DepNodeIndexNew, Vec<DepNodeIndexNew>>,
     node_to_node_index: FxHashMap<DepNode, DepNodeIndexNew>,
 
+    anon_id_seed: Fingerprint,
+
     task_stack: Vec<OpenTask>,
 }
 
 impl CurrentDepGraph {
     fn new() -> CurrentDepGraph {
+        use std::time::{SystemTime, UNIX_EPOCH};
+
+        let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
+        let nanos = duration.as_secs() * 1_000_000_000 +
+                    duration.subsec_nanos() as u64;
+        let mut stable_hasher = StableHasher::new();
+        nanos.hash(&mut stable_hasher);
+
         CurrentDepGraph {
             nodes: IndexVec::new(),
             edges: IndexVec::new(),
             node_to_node_index: FxHashMap(),
+            anon_id_seed: stable_hasher.finish(),
             task_stack: Vec::new(),
         }
     }
@@ -696,14 +727,14 @@ fn push_anon_task(&mut self) {
         });
     }
 
-    fn pop_anon_task(&mut self, kind: DepKind) -> (Option<DepNode>, DepNodeIndexNew) {
+    fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndexNew {
         let popped_node = self.task_stack.pop().unwrap();
 
         if let OpenTask::Anon {
             read_set: _,
             reads
         } = popped_node {
-            let mut fingerprint = Fingerprint::zero();
+            let mut fingerprint = self.anon_id_seed;
             let mut hasher = StableHasher::new();
 
             for &read in reads.iter() {
@@ -725,9 +756,9 @@ fn pop_anon_task(&mut self, kind: DepKind) -> (Option<DepNode>, DepNodeIndexNew)
             };
 
             if let Some(&index) = self.node_to_node_index.get(&target_dep_node) {
-                (None, index)
+                index
             } else {
-                (Some(target_dep_node), self.alloc_node(target_dep_node, reads))
+                self.alloc_node(target_dep_node, reads)
             }
         } else {
             bug!("pop_anon_task() - Expected anonymous task to be popped")
index 959f11a89bd01586447f89fcea009fa305988a2e..d65fbb8f6cfb4550e5d1d1d48e637223f6162a04 100644 (file)
@@ -320,6 +320,10 @@ fn try_get_with(tcx: TyCtxt<'a, $tcx, 'lcx>,
                                                                         dep_node_index)
                     }
 
+                    debug!("ty::queries::{}::try_get_with(key={:?}) - running try_mark_green",
+                           stringify!($name),
+                           key);
+
                     if let Some(dep_node_index) = tcx.dep_graph.try_mark_green(tcx, &dep_node) {
                         debug_assert!(tcx.dep_graph.is_green(dep_node_index));
                         profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
@@ -363,6 +367,10 @@ fn load_from_disk_and_cache_in_memory(tcx: TyCtxt<'a, $tcx, 'lcx>,
                     })
                 })?;
 
+                if tcx.sess.opts.debugging_opts.query_dep_graph {
+                    tcx.dep_graph.mark_loaded_from_cache(dep_node_index, true);
+                }
+
                 let value = QueryValue::new(result, dep_node_index, diagnostics);
 
                 Ok((&tcx.maps
@@ -394,6 +402,10 @@ fn force(tcx: TyCtxt<'a, $tcx, 'lcx>,
 
                 let ((result, dep_node_index), diagnostics) = res;
 
+                if tcx.sess.opts.debugging_opts.query_dep_graph {
+                    tcx.dep_graph.mark_loaded_from_cache(dep_node_index, false);
+                }
+
                 let value = QueryValue::new(result, dep_node_index, diagnostics);
 
                 Ok(((&tcx.maps
@@ -406,8 +418,6 @@ fn force(tcx: TyCtxt<'a, $tcx, 'lcx>,
                    dep_node_index))
             }
 
-
-
             pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
                            -> Result<$V, DiagnosticBuilder<'a>> {
                 match Self::try_get_with(tcx, span, key) {
index 0fba6d8e9c67d13403e03f1d8d2807cc90cf8922..f04b9bd925c0d44f7b7c1e205b677db6acb023bd 100644 (file)
@@ -39,3 +39,4 @@
 pub use persist::in_incr_comp_dir;
 pub use persist::prepare_session_directory;
 pub use persist::finalize_session_directory;
+pub use persist::delete_workproduct_files;
index 6d019a25ed3ec4cc83ba4d2132a78b032ae005fc..0388d950cdf324c553930475c19a6260115aa63c 100644 (file)
@@ -99,6 +99,7 @@ fn load_data(sess: &Session, path: &Path) -> Option<Vec<u8>> {
 /// variants that represent inputs (HIR and imported Metadata).
 fn does_still_exist(tcx: TyCtxt, dep_node: &DepNode) -> bool {
     match dep_node.kind {
+        DepKind::Krate |
         DepKind::Hir |
         DepKind::HirBody |
         DepKind::InScopeTraits |
@@ -258,33 +259,28 @@ fn transitive_dirty_nodes(serialized_dep_graph: &SerializedDepGraph,
 /// otherwise no longer applicable.
 fn reconcile_work_products<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      work_products: Vec<SerializedWorkProduct>,
-                                     clean_work_products: &FxHashSet<WorkProductId>) {
+                                     _clean_work_products: &FxHashSet<WorkProductId>) {
     debug!("reconcile_work_products({:?})", work_products);
     for swp in work_products {
-        if !clean_work_products.contains(&swp.id) {
-            debug!("reconcile_work_products: dep-node for {:?} is dirty", swp);
-            delete_dirty_work_product(tcx, swp);
-        } else {
-            let mut all_files_exist = true;
-            for &(_, ref file_name) in swp.work_product.saved_files.iter() {
-                let path = in_incr_comp_dir_sess(tcx.sess, file_name);
-                if !path.exists() {
-                    all_files_exist = false;
-
-                    if tcx.sess.opts.debugging_opts.incremental_info {
-                        eprintln!("incremental: could not find file for \
-                                   up-to-date work product: {}", path.display());
-                    }
+        let mut all_files_exist = true;
+        for &(_, ref file_name) in swp.work_product.saved_files.iter() {
+            let path = in_incr_comp_dir_sess(tcx.sess, file_name);
+            if !path.exists() {
+                all_files_exist = false;
+
+                if tcx.sess.opts.debugging_opts.incremental_info {
+                    eprintln!("incremental: could not find file for \
+                               up-to-date work product: {}", path.display());
                 }
             }
+        }
 
-            if all_files_exist {
-                debug!("reconcile_work_products: all files for {:?} exist", swp);
-                tcx.dep_graph.insert_previous_work_product(&swp.id, swp.work_product);
-            } else {
-                debug!("reconcile_work_products: some file for {:?} does not exist", swp);
-                delete_dirty_work_product(tcx, swp);
-            }
+        if all_files_exist {
+            debug!("reconcile_work_products: all files for {:?} exist", swp);
+            tcx.dep_graph.insert_previous_work_product(&swp.id, swp.work_product);
+        } else {
+            debug!("reconcile_work_products: some file for {:?} does not exist", swp);
+            delete_dirty_work_product(tcx, swp);
         }
     }
 }
index 688d8add57e3fd49f38dc67ebe317f3433ccd2f1..0d81a1865665d5bdf3eb84767f0be1b0c0178529 100644 (file)
@@ -29,3 +29,4 @@
 pub use self::save::save_dep_graph;
 pub use self::save::save_work_products;
 pub use self::work_product::save_trans_partition;
+pub use self::work_product::delete_workproduct_files;
index 70d96e3a83d376bed6bd6dbd219e299b7f2960b9..9865e8fb1734a08bd1ce14731709af9e987642bf 100644 (file)
 pub fn save_trans_partition(sess: &Session,
                             dep_graph: &DepGraph,
                             cgu_name: &str,
-                            partition_hash: u64,
                             files: &[(OutputType, PathBuf)]) {
-    debug!("save_trans_partition({:?},{},{:?})",
+    debug!("save_trans_partition({:?},{:?})",
            cgu_name,
-           partition_hash,
            files);
     if sess.opts.incremental.is_none() {
         return;
@@ -57,7 +55,6 @@ pub fn save_trans_partition(sess: &Session,
 
     let work_product = WorkProduct {
         cgu_name: cgu_name.to_string(),
-        input_hash: partition_hash,
         saved_files,
     };
 
index 6e661a5a8c6a4c278d2e15ffe44dea3bfd4ed757..c891bd8aaf44f06d499dc68bbe2c51e769ad37fd 100644 (file)
 //! the HIR doesn't change as a result of the annotations, which might
 //! perturb the reuse results.
 
+use rustc::dep_graph::{DepNode, DepConstructor};
 use rustc::ty::TyCtxt;
 use syntax::ast;
-
-use {ModuleSource, ModuleTranslation};
-
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_TRANSLATED};
 
 const MODULE: &'static str = "module";
 const CFG: &'static str = "cfg";
 
 #[derive(Debug, PartialEq, Clone, Copy)]
-pub enum Disposition { Reused, Translated }
-
-impl ModuleTranslation {
-    pub fn disposition(&self) -> (String, Disposition) {
-        let disposition = match self.source {
-            ModuleSource::Preexisting(_) => Disposition::Reused,
-            ModuleSource::Translated(_) => Disposition::Translated,
-        };
+enum Disposition { Reused, Translated }
 
-        (self.name.clone(), disposition)
-    }
-}
-
-pub(crate) fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                              modules: &[(String, Disposition)]) {
+pub(crate) fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let _ignore = tcx.dep_graph.in_ignore();
 
     if tcx.sess.opts.incremental.is_none() {
         return;
     }
 
-    let ams = AssertModuleSource { tcx: tcx, modules: modules };
+    let ams = AssertModuleSource { tcx };
     for attr in &tcx.hir.krate().attrs {
         ams.check_attr(attr);
     }
 }
 
 struct AssertModuleSource<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    modules: &'a [(String, Disposition)],
+    tcx: TyCtxt<'a, 'tcx, 'tcx>
 }
 
 impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
@@ -86,32 +71,31 @@ fn check_attr(&self, attr: &ast::Attribute) {
         }
 
         let mname = self.field(attr, MODULE);
-        let mtrans = self.modules.iter().find(|&&(ref name, _)| name == mname.as_str());
-        let mtrans = match mtrans {
-            Some(m) => m,
-            None => {
-                debug!("module name `{}` not found amongst:", mname);
-                for &(ref name, ref disposition) in self.modules {
-                    debug!("module named `{}` with disposition {:?}",
-                           name,
-                           disposition);
-                }
 
-                self.tcx.sess.span_err(
-                    attr.span,
-                    &format!("no module named `{}`", mname));
-                return;
-            }
-        };
+        let dep_node = DepNode::new(self.tcx,
+                                    DepConstructor::CompileCodegenUnit(mname.as_str()));
 
-        let mtrans_disposition = mtrans.1;
-        if disposition != mtrans_disposition {
-            self.tcx.sess.span_err(
-                attr.span,
-                &format!("expected module named `{}` to be {:?} but is {:?}",
-                         mname,
-                         disposition,
-                         mtrans_disposition));
+        if let Some(loaded_from_cache) = self.tcx.dep_graph.was_loaded_from_cache(&dep_node) {
+            match (disposition, loaded_from_cache) {
+                (Disposition::Reused, false) => {
+                    self.tcx.sess.span_err(
+                        attr.span,
+                        &format!("expected module named `{}` to be Reused but is Translated",
+                                 mname));
+                }
+                (Disposition::Translated, true) => {
+                    self.tcx.sess.span_err(
+                        attr.span,
+                        &format!("expected module named `{}` to be Translated but is Reused",
+                                 mname));
+                }
+                (Disposition::Reused, true) |
+                (Disposition::Translated, false) => {
+                    // These are what we would expect.
+                }
+            }
+        } else {
+            self.tcx.sess.span_err(attr.span, &format!("no module named `{}`", mname));
         }
     }
 
index e1f97e2c923db17d42ce32aab2a4be64fdc7363d..d79fbf77465a363032dffd217f994effe847f5a7 100644 (file)
@@ -79,9 +79,7 @@ pub fn provide_local(providers: &mut Providers) {
     providers.is_exported_symbol = |tcx, id| {
         // FIXME(#42293) needs red/green to not break a bunch of incremental
         // tests
-        tcx.dep_graph.with_ignore(|| {
-            tcx.exported_symbol_ids(id.krate).contains(&id)
-        })
+        tcx.exported_symbol_ids(id.krate).contains(&id)
     };
 
     providers.exported_symbols = |tcx, cnum| {
index c39bdcf25cd51b528d22749ba9d92ed2bb4a8794..c238c68c4718da604816c152dddf02879fbaca0e 100644 (file)
@@ -884,7 +884,6 @@ fn copy_module_artifacts_into_incr_comp_cache(sess: &Session,
         save_trans_partition(sess,
                              dep_graph,
                              &module.name,
-                             module.symbol_name_hash,
                              &files);
     }
 }
@@ -1134,7 +1133,6 @@ fn execute_work_item(cgcx: &CodegenContext, work_item: WorkItem)
             name: module_name,
             kind: ModuleKind::Regular,
             pre_existing: true,
-            symbol_name_hash: mtrans.symbol_name_hash,
             emit_bc: config.emit_bc,
             emit_obj: config.emit_obj,
         }))
index 56b20047808ccd05c86fb4912b707bcbc51d658d..c9ed17bfaf03b579a5a05a2dba35c8663d766ceb 100644 (file)
@@ -28,7 +28,7 @@
 use super::ModuleTranslation;
 use super::ModuleKind;
 
-use assert_module_sources::{self, Disposition};
+use assert_module_sources;
 use back::link;
 use back::symbol_export;
 use back::write::{self, OngoingCrateTranslation, create_target_machine};
@@ -41,7 +41,7 @@
 use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::maps::Providers;
-use rustc::dep_graph::{DepNode, DepKind};
+use rustc::dep_graph::{DepNode, DepKind, DepConstructor};
 use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
 use rustc::util::common::{time, print_time_passes_entry};
 use rustc::session::config::{self, NoDebugInfo};
@@ -78,7 +78,6 @@
 use CrateInfo;
 
 use std::any::Any;
-use std::cell::RefCell;
 use std::ffi::{CStr, CString};
 use std::str;
 use std::sync::Arc;
@@ -904,7 +903,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let metadata_module = ModuleTranslation {
         name: link::METADATA_MODULE_NAME.to_string(),
         llmod_id: llmod_id.to_string(),
-        symbol_name_hash: 0, // we always rebuild metadata, at least for now
         source: ModuleSource::Translated(ModuleLlvm {
             llcx: metadata_llcx,
             llmod: metadata_llmod,
@@ -985,7 +983,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             Some(ModuleTranslation {
                 name: link::ALLOCATOR_MODULE_NAME.to_string(),
                 llmod_id: llmod_id.to_string(),
-                symbol_name_hash: 0, // we always rebuild allocator shims
                 source: ModuleSource::Translated(modules),
                 kind: ModuleKind::Allocator,
             })
@@ -1017,6 +1014,50 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         ongoing_translation.wait_for_signal_to_translate_item();
         ongoing_translation.check_for_errors(tcx.sess);
 
+        // First, if incremental compilation is enabled, we try to re-use the
+        // codegen unit from the cache.
+        if tcx.dep_graph.is_fully_enabled() {
+            let cgu_id = cgu.work_product_id();
+
+            // 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.
+            if let Some(buf) = tcx.dep_graph.previous_work_product(&cgu_id) {
+                let dep_node = &DepNode::new(tcx,
+                    DepConstructor::CompileCodegenUnit(cgu.name().clone()));
+
+                // We try to mark the DepNode::CompileCodegenUnit green. If we
+                // succeed it means that none of the dependencies has changed
+                // and we can safely re-use.
+                if let Some(dep_node_index) = tcx.dep_graph.try_mark_green(tcx, dep_node) {
+                    // Append ".rs" to LLVM module identifier.
+                    //
+                    // LLVM code generator emits a ".file filename" directive
+                    // for ELF backends. Value of the "filename" is set as the
+                    // LLVM module identifier.  Due to a LLVM MC bug[1], LLVM
+                    // crashes if the module identifier is same as other symbols
+                    // such as a function name in the module.
+                    // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
+                    let llmod_id = format!("{}.rs", cgu.name());
+
+                    let module = ModuleTranslation {
+                        name: cgu.name().to_string(),
+                        source: ModuleSource::Preexisting(buf),
+                        kind: ModuleKind::Regular,
+                        llmod_id,
+                    };
+                    tcx.dep_graph.mark_loaded_from_cache(dep_node_index, true);
+                    write::submit_translated_module_to_llvm(tcx, module, 0);
+                    // Continue to next cgu, this one is done.
+                    continue
+                }
+            } else {
+                // This can happen if files were  deleted from the cache
+                // directory for some reason. We just re-compile then.
+            }
+        }
+
         let _timing_guard = time_graph.as_ref().map(|time_graph| {
             time_graph.start(write::TRANS_WORKER_TIMELINE,
                              write::TRANS_WORK_PACKAGE_KIND,
@@ -1037,9 +1078,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             total_trans_time);
 
     if tcx.sess.opts.incremental.is_some() {
-        DISPOSITIONS.with(|d| {
-            assert_module_sources::assert_module_sources(tcx, &d.borrow());
-        });
+        assert_module_sources::assert_module_sources(tcx);
     }
 
     symbol_names_test::report_symbol_names(tcx);
@@ -1074,10 +1113,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     ongoing_translation
 }
 
-// FIXME(#42293) hopefully once red/green is enabled we're testing everything
-// via a method that doesn't require this!
-thread_local!(static DISPOSITIONS: RefCell<Vec<(String, Disposition)>> = Default::default());
-
 fn assert_and_save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        metadata_incr_hashes: EncodedMetadataHashes,
                                        link_meta: LinkMeta) {
@@ -1301,38 +1336,19 @@ pub fn new(tcx: TyCtxt) -> CrateInfo {
 }
 
 fn is_translated_function(tcx: TyCtxt, id: DefId) -> bool {
-    // FIXME(#42293) needs red/green tracking to avoid failing a bunch of
-    // existing tests
-    tcx.dep_graph.with_ignore(|| {
-        let (all_trans_items, _) =
-            tcx.collect_and_partition_translation_items(LOCAL_CRATE);
-        all_trans_items.contains(&id)
-    })
+    let (all_trans_items, _) =
+        tcx.collect_and_partition_translation_items(LOCAL_CRATE);
+    all_trans_items.contains(&id)
 }
 
 fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                   cgu: InternedString) -> Stats {
-    // FIXME(#42293) needs red/green tracking to avoid failing a bunch of
-    // existing tests
-    let cgu = tcx.dep_graph.with_ignore(|| {
-        tcx.codegen_unit(cgu)
-    });
+    let cgu = tcx.codegen_unit(cgu);
 
     let start_time = Instant::now();
-    let dep_node = cgu.work_product_dep_node();
-    let ((stats, module), _) =
-        tcx.dep_graph.with_task(dep_node,
-                                tcx,
-                                cgu,
-                                module_translation);
+    let (stats, module) = module_translation(tcx, cgu);
     let time_to_translate = start_time.elapsed();
 
-    if tcx.sess.opts.incremental.is_some() {
-        DISPOSITIONS.with(|d| {
-            d.borrow_mut().push(module.disposition());
-        });
-    }
-
     // We assume that the cost to run LLVM on a CGU is proportional to
     // the time we needed for translating it.
     let cost = time_to_translate.as_secs() * 1_000_000_000 +
@@ -1349,8 +1365,6 @@ fn module_translation<'a, 'tcx>(
         -> (Stats, ModuleTranslation)
     {
         let cgu_name = cgu.name().to_string();
-        let cgu_id = cgu.work_product_id();
-        let symbol_name_hash = cgu.compute_symbol_name_hash(tcx);
 
         // Append ".rs" to LLVM module identifier.
         //
@@ -1362,40 +1376,6 @@ fn module_translation<'a, 'tcx>(
         // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
         let llmod_id = format!("{}.rs", cgu.name());
 
-        // 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 =
-            tcx.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 tcx.sess.opts.debugging_opts.incremental_info {
-                        eprintln!("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
-                }
-            });
-
-        if let Some(buf) = previous_work_product {
-            // Don't need to translate this module.
-            let module = ModuleTranslation {
-                llmod_id: llmod_id,
-                name: cgu_name,
-                symbol_name_hash,
-                source: ModuleSource::Preexisting(buf.clone()),
-                kind: ModuleKind::Regular,
-            };
-            return (Stats::default(), module);
-        }
-
         // Instantiate translation items without filling out definitions yet...
         let scx = SharedCrateContext::new(tcx);
         let lcx = LocalCrateContext::new(&scx, cgu, &llmod_id);
@@ -1461,7 +1441,6 @@ fn module_translation<'a, 'tcx>(
 
             ModuleTranslation {
                 name: cgu_name,
-                symbol_name_hash,
                 source: ModuleSource::Translated(llvm_module),
                 kind: ModuleKind::Regular,
                 llmod_id,
index 52e6dce24ed929337af2a1308c37d5b0fd081e1f..3cd26e49818bbb49ca5b07fbbaf38936a5eae93e 100644 (file)
@@ -155,17 +155,14 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             }
         }
 
-        // FIXME(#42293) we should actually track this, but fails too many tests
-        // today.
-        tcx.dep_graph.with_ignore(|| {
-            if ccx.use_dll_storage_attrs() &&
-                tcx.is_dllimport_foreign_item(instance_def_id)
-            {
-                unsafe {
-                    llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
-                }
+        if ccx.use_dll_storage_attrs() &&
+            tcx.is_dllimport_foreign_item(instance_def_id)
+        {
+            unsafe {
+                llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
             }
-        });
+        }
+
         llfn
     };
 
index 6fa69de74b0a1560b7858706401a63a5da8704f3..4263a553f8b43304a67dbb0e10ea86dc3c9f95e5 100644 (file)
@@ -296,26 +296,22 @@ pub fn collect_crate_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                  mode: TransItemCollectionMode)
                                                  -> (FxHashSet<TransItem<'tcx>>,
                                                      InliningMap<'tcx>) {
-    // We are not tracking dependencies of this pass as it has to be re-executed
-    // every time no matter what.
-    tcx.dep_graph.with_ignore(|| {
-        let roots = collect_roots(tcx, mode);
-
-        debug!("Building translation item graph, beginning at roots");
-        let mut visited = FxHashSet();
-        let mut recursion_depths = DefIdMap();
-        let mut inlining_map = InliningMap::new();
-
-        for root in roots {
-            collect_items_rec(tcx,
-                              root,
-                              &mut visited,
-                              &mut recursion_depths,
-                              &mut inlining_map);
-        }
+    let roots = collect_roots(tcx, mode);
+
+    debug!("Building translation item graph, beginning at roots");
+    let mut visited = FxHashSet();
+    let mut recursion_depths = DefIdMap();
+    let mut inlining_map = InliningMap::new();
+
+    for root in roots {
+        collect_items_rec(tcx,
+                          root,
+                          &mut visited,
+                          &mut recursion_depths,
+                          &mut inlining_map);
+    }
 
-        (visited, inlining_map)
-    })
+    (visited, inlining_map)
 }
 
 // Find all non-generic items by walking the HIR. These items serve as roots to
index 78ece020d1d6b8a2999c8cb6fb4283811cf07af6..eaf7392aab5b4f6d95a2ca635c4fb0bd8db8b3e6 100644 (file)
@@ -231,17 +231,13 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
         g
     };
 
-
-    // FIXME(#42293) we should actually track this, but fails too many tests
-    // today.
-    ccx.tcx().dep_graph.with_ignore(|| {
-        if ccx.use_dll_storage_attrs() && ccx.tcx().is_dllimport_foreign_item(def_id) {
-            // For foreign (native) libs we know the exact storage type to use.
-            unsafe {
-                llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
-            }
+    if ccx.use_dll_storage_attrs() && ccx.tcx().is_dllimport_foreign_item(def_id) {
+        // For foreign (native) libs we know the exact storage type to use.
+        unsafe {
+            llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
         }
-    });
+    }
+
     ccx.instances().borrow_mut().insert(instance, g);
     ccx.statics().borrow_mut().insert(g, def_id);
     g
index c38b90dcf4f62dabbc72e709f7f1b2e100aa19cf..2b1c62c7f1c768cded788224bb50c96c233cac48 100644 (file)
@@ -204,7 +204,6 @@ pub struct ModuleTranslation {
     /// as the crate name and disambiguator.
     name: String,
     llmod_id: String,
-    symbol_name_hash: u64,
     pub source: ModuleSource,
     pub kind: ModuleKind,
 }
@@ -238,7 +237,6 @@ pub fn into_compiled_module(self,
             llmod_id: self.llmod_id,
             name: self.name.clone(),
             kind: self.kind,
-            symbol_name_hash: self.symbol_name_hash,
             pre_existing,
             emit_obj,
             emit_bc,
@@ -253,7 +251,6 @@ pub struct CompiledModule {
     pub llmod_id: String,
     pub object: PathBuf,
     pub kind: ModuleKind,
-    pub symbol_name_hash: u64,
     pub pre_existing: bool,
     pub emit_obj: bool,
     pub emit_bc: bool,
index 7c29186f4657f721a5424d5c1c9c736569dc76bf..7b6daa7d13328c9c2f312fdca294674ea9109cae 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::DefPathData;
 use rustc::middle::trans::{Linkage, Visibility};
-use rustc::ich::Fingerprint;
 use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
 use rustc::ty::{self, TyCtxt, InstanceDef};
 use rustc::ty::item_path::characteristic_def_id_of_type;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use rustc_data_structures::stable_hasher::StableHasher;
 use std::collections::hash_map::Entry;
-use std::hash::Hash;
 use syntax::ast::NodeId;
 use syntax::symbol::{Symbol, InternedString};
 use trans_item::{TransItem, TransItemExt, InstantiationMode};
@@ -155,19 +152,6 @@ fn work_product_dep_node(&self) -> DepNode {
         self.work_product_id().to_dep_node()
     }
 
-    fn compute_symbol_name_hash<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> u64 {
-        let mut state: StableHasher<Fingerprint> = StableHasher::new();
-        let all_items = self.items_in_deterministic_order(tcx);
-        for (item, (linkage, visibility)) in all_items {
-            let symbol_name = item.symbol_name(tcx);
-            symbol_name.len().hash(&mut state);
-            symbol_name.hash(&mut state);
-            linkage.hash(&mut state);
-            visibility.hash(&mut state);
-        }
-        state.finish().to_smaller_hash()
-    }
-
     fn items_in_deterministic_order<'a>(&self,
                                         tcx: TyCtxt<'a, 'tcx, 'tcx>)
                                         -> Vec<(TransItem<'tcx>,
index 875aa3293650823d554b9a3e89f00ec5c4dc7fa9..40067efd57595973a13dc00676ee0347c5681eeb 100644 (file)
@@ -15,7 +15,6 @@
 // revisions:rpass1 rpass2
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
-// ignore-test FIXME(#42293) this regressed in #44142 but should get fixed with red/green
 
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
index 274a3920be8d4ad54d02499fa713cb37690a0641..feecfecd0b85368a137ffb543cd6ccf1a09bf6ab 100644 (file)
@@ -20,6 +20,7 @@
 //[rpass1] rustc-env:RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER="l33t haxx0r rustc 2.1 LTS"
 
 // revisions:rpass1 rpass2
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![rustc_partition_translated(module="cache_file_headers", cfg="rpass2")]
index 355983e9ca1b9e53f3a8795d64087732ba458b41..9e56d34636ff0083b4dc53a91809aef0a13c8eb0 100644 (file)
@@ -12,8 +12,6 @@
 // revisions:rpass1 rpass2
 // compile-flags:-Z query-dep-graph
 
-// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
-
 #![feature(rustc_attrs)]
 
 extern crate a;
index d58a9bacdb53ca4c7ed10f500ea7b65257cc8815..a6d029515d74263d23cbeb295eb101fb68618967 100644 (file)
@@ -15,8 +15,6 @@
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
 
-// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
-
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
 #![allow(dead_code)]
index 3f665f5c82052da07458916a2a5231583c5bec64..05c076b9f4bc3b47dd286d658a3221024fef4ef3 100644 (file)
@@ -15,8 +15,6 @@
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
 
-// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
-
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
 #![allow(dead_code)]
index 71f46c641bf8f72fd1ab4123c137ea5640b52768..ab91a941a1663aa62006a6aefbea4556d60e517f 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 // revisions: rpass1 rpass2
+// compile-flags: -Zquery-dep-graph
 
 #![feature(rustc_attrs)]
 #![allow(private_no_mangle_fns)]
 
-#![rustc_partition_reused(module="change_symbol_export_status", cfg="rpass2")]
 #![rustc_partition_translated(module="change_symbol_export_status-mod1", cfg="rpass2")]
-
+#![rustc_partition_reused(module="change_symbol_export_status-mod2", cfg="rpass2")]
 
 // This test case makes sure that a change in symbol visibility is detected by
 // our dependency tracking. We do this by changing a module's visibility to
@@ -37,6 +37,11 @@ mod mod1 {
     pub fn foo() {}
 }
 
+pub mod mod2 {
+    #[no_mangle]
+    pub fn bar() {}
+}
+
 fn main() {
     mod1::foo();
 }
index 95187b825be9f2c9d385c9eceb277ba5f33fbd9e..e29f2ec2a1345682a33d3604984c91187c4fff54 100644 (file)
@@ -12,6 +12,7 @@
 // the cache while changing an untracked one doesn't.
 
 // revisions:rpass1 rpass2 rpass3
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 
index 51e04dd7b2ce0bab674b66b27418b36f606eff07..52a601ac1e87bd447afa3cc6745b931437201757 100644 (file)
@@ -12,6 +12,7 @@
 // equal example.
 
 // revisions:rpass1 rpass2
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 #![rustc_partition_reused(module="issue_35593", cfg="rpass2")]
index d14b1cfd6c9ac041202e4645286bffbb6b9b5234..410ff69bf69c5391169c13de2c775d876d2847f8 100644 (file)
@@ -12,6 +12,8 @@
 // dep-node.
 
 // revisions:rpass1 rpass2
+// compile-flags: -Z query-dep-graph
+
 
 #![feature(rustc_attrs)]
 
index 58fb8bc3c889f4f4f6550ff93bbad4288891ff80..432d8a1b444f3eb1708b050e7d304c306a4e8c81 100644 (file)
@@ -11,8 +11,6 @@
 // revisions:rpass1 rpass2 rpass3
 // compile-flags: -Z query-dep-graph -g -Zincremental-cc
 // aux-build:extern_crate.rs
-// ignore-test FIXME(#42293) this regressed in #44142 but should get fixed with red/green
-
 
 // This test case makes sure that we detect if paths emitted into debuginfo
 // are changed, even when the change happens in an external crate.
index 24fa1502b9224e5138868a4ded92a41cbf19e658..d94cb403da8a5209c02ad382d0f55f61d882f296 100644 (file)
@@ -17,8 +17,7 @@
 #![feature(rustc_attrs)]
 #![crate_type = "bin"]
 
-// FIXME(#42293) this regressed in #44142 but should get fixed with red/green
-// #![rustc_partition_reused(module="main", cfg="rpass2")]
+#![rustc_partition_reused(module="main", cfg="rpass2")]
 
 extern crate a;
 
index 39065d9671ace089b3736c11403e75b6835faf48..9849e93d3ff9ef4e0de1eb6aea01f9bd5c9d89a1 100644 (file)
@@ -18,8 +18,6 @@
 // no-prefer-dynamic
 // compile-flags: -Z query-dep-graph
 
-// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
-
 #![feature(rustc_attrs)]
 
 extern crate a;
index 257699cd3fce15b53a2d61ec02271eb1584858d8..a820471b7d55baf1dfea4d1a54278cbeb9cf5851 100644 (file)
@@ -13,6 +13,7 @@
 // `y` module entirely (but not the `x` module).
 
 // revisions:rpass1 rpass2
+// compile-flags: -Z query-dep-graph
 
 #![feature(rustc_attrs)]
 
index e5ec9784847f0b4c5882a04441f0974aed7dda62..9660f47da35c1ef6de5ad5a6b3dac243cd563000 100644 (file)
@@ -12,8 +12,6 @@
 // revisions:rpass1 rpass2
 // compile-flags: -Z query-dep-graph
 
-// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
-
 #![feature(rustc_attrs)]
 
 extern crate a;
index 63e1437f0687be4398da2d6805e111ed77afac69..ee35a4d9b9c6e9f0c96af2a5ba000fb32168da90 100644 (file)
@@ -12,8 +12,6 @@
 // revisions:rpass1 rpass2 rpass3
 // compile-flags: -Z query-dep-graph
 
-// ignore-test -- ignored until red/green restores cross-crate tracking fidelity
-
 #![feature(rustc_attrs)]
 
 extern crate a;