about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs1
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs76
2 files changed, 50 insertions, 27 deletions
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 9603b102cbc..a8455854ebb 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -229,6 +229,7 @@ pub fn build_dep_graph(
     }
 
     Some(DepGraph::new(
+        &sess.prof,
         prev_graph,
         prev_work_products,
         encoder,
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index cfae65abe83..9481da70f42 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -44,6 +44,7 @@ rustc_index::newtype_index! {
 
 impl DepNodeIndex {
     pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
+    pub const DUMMY_ANON: DepNodeIndex = DepNodeIndex::from_u32(0);
 }
 
 impl std::convert::From<DepNodeIndex> for QueryInvocationId {
@@ -108,6 +109,7 @@ where
 
 impl<K: DepKind> DepGraph<K> {
     pub fn new(
+        profiler: &SelfProfilerRef,
         prev_graph: SerializedDepGraph<K>,
         prev_work_products: FxHashMap<WorkProductId, WorkProduct>,
         encoder: FileEncoder,
@@ -116,16 +118,23 @@ impl<K: DepKind> DepGraph<K> {
     ) -> DepGraph<K> {
         let prev_graph_node_count = prev_graph.node_count();
 
+        let current =
+            CurrentDepGraph::new(prev_graph_node_count, encoder, record_graph, record_stats);
+
+        // Instantiate an *always green* node for dependency-less anonymous queries.
+        let _green_node_index = current.intern_new_node(
+            profiler,
+            DepNode { kind: DepKind::NULL, hash: current.anon_id_seed.into() },
+            smallvec![],
+            Fingerprint::ZERO,
+        );
+        debug_assert_eq!(_green_node_index, DepNodeIndex::DUMMY_ANON);
+
         DepGraph {
             data: Some(Lrc::new(DepGraphData {
                 previous_work_products: prev_work_products,
                 dep_node_debug: Default::default(),
-                current: CurrentDepGraph::new(
-                    prev_graph_node_count,
-                    encoder,
-                    record_graph,
-                    record_stats,
-                ),
+                current,
                 emitting_diagnostics: Default::default(),
                 emitting_diagnostics_cond_var: Condvar::new(),
                 previous: prev_graph,
@@ -287,29 +296,42 @@ impl<K: DepKind> DepGraph<K> {
             let task_deps = Lock::new(TaskDeps::default());
             let result = K::with_deps(Some(&task_deps), op);
             let task_deps = task_deps.into_inner();
+            let task_deps = task_deps.reads;
 
-            // The dep node indices are hashed here instead of hashing the dep nodes of the
-            // dependencies. These indices may refer to different nodes per session, but this isn't
-            // a problem here because we that ensure the final dep node hash is per session only by
-            // combining it with the per session random number `anon_id_seed`. This hash only need
-            // to map the dependencies to a single value on a per session basis.
-            let mut hasher = StableHasher::new();
-            task_deps.reads.hash(&mut hasher);
-
-            let target_dep_node = DepNode {
-                kind: dep_kind,
-                // Fingerprint::combine() is faster than sending Fingerprint
-                // through the StableHasher (at least as long as StableHasher
-                // is so slow).
-                hash: data.current.anon_id_seed.combine(hasher.finish()).into(),
-            };
+            let dep_node_index = match task_deps.len() {
+                0 => {
+                    // Dependency-less anonymous nodes can safely be replaced by a dummy node.
+                    DepNodeIndex::DUMMY_ANON
+                }
+                1 => {
+                    // When there is only one dependency, don't bother creating a node.
+                    task_deps[0]
+                }
+                _ => {
+                    // The dep node indices are hashed here instead of hashing the dep nodes of the
+                    // dependencies. These indices may refer to different nodes per session, but this isn't
+                    // a problem here because we that ensure the final dep node hash is per session only by
+                    // combining it with the per session random number `anon_id_seed`. This hash only need
+                    // to map the dependencies to a single value on a per session basis.
+                    let mut hasher = StableHasher::new();
+                    task_deps.hash(&mut hasher);
+
+                    let target_dep_node = DepNode {
+                        kind: dep_kind,
+                        // Fingerprint::combine() is faster than sending Fingerprint
+                        // through the StableHasher (at least as long as StableHasher
+                        // is so slow).
+                        hash: data.current.anon_id_seed.combine(hasher.finish()).into(),
+                    };
 
-            let dep_node_index = data.current.intern_new_node(
-                cx.profiler(),
-                target_dep_node,
-                task_deps.reads,
-                Fingerprint::ZERO,
-            );
+                    data.current.intern_new_node(
+                        cx.profiler(),
+                        target_dep_node,
+                        task_deps,
+                        Fingerprint::ZERO,
+                    )
+                }
+            };
 
             (result, dep_node_index)
         } else {