Skip to content

Commit 3a6d5c2

Browse files
committed
Avoid creating anonymous nodes with zero or one dependency.
1 parent 7f9ab03 commit 3a6d5c2

File tree

2 files changed

+50
-27
lines changed
  • compiler
    • rustc_incremental/src/persist
    • rustc_query_system/src/dep_graph

2 files changed

+50
-27
lines changed

compiler/rustc_incremental/src/persist/save.rs

+1
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ pub fn build_dep_graph(
229229
}
230230

231231
Some(DepGraph::new(
232+
&sess.prof,
232233
prev_graph,
233234
prev_work_products,
234235
encoder,

compiler/rustc_query_system/src/dep_graph/graph.rs

+49-27
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ rustc_index::newtype_index! {
4444

4545
impl DepNodeIndex {
4646
pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
47+
pub const DUMMY_ANON: DepNodeIndex = DepNodeIndex::from_u32(0);
4748
}
4849

4950
impl std::convert::From<DepNodeIndex> for QueryInvocationId {
@@ -108,6 +109,7 @@ where
108109

109110
impl<K: DepKind> DepGraph<K> {
110111
pub fn new(
112+
profiler: &SelfProfilerRef,
111113
prev_graph: SerializedDepGraph<K>,
112114
prev_work_products: FxHashMap<WorkProductId, WorkProduct>,
113115
encoder: FileEncoder,
@@ -116,16 +118,23 @@ impl<K: DepKind> DepGraph<K> {
116118
) -> DepGraph<K> {
117119
let prev_graph_node_count = prev_graph.node_count();
118120

121+
let current =
122+
CurrentDepGraph::new(prev_graph_node_count, encoder, record_graph, record_stats);
123+
124+
// Instantiate an *always green* node for dependency-less anonymous queries.
125+
let _green_node_index = current.intern_new_node(
126+
profiler,
127+
DepNode { kind: DepKind::NULL, hash: current.anon_id_seed.into() },
128+
smallvec![],
129+
Fingerprint::ZERO,
130+
);
131+
debug_assert_eq!(_green_node_index, DepNodeIndex::DUMMY_ANON);
132+
119133
DepGraph {
120134
data: Some(Lrc::new(DepGraphData {
121135
previous_work_products: prev_work_products,
122136
dep_node_debug: Default::default(),
123-
current: CurrentDepGraph::new(
124-
prev_graph_node_count,
125-
encoder,
126-
record_graph,
127-
record_stats,
128-
),
137+
current,
129138
emitting_diagnostics: Default::default(),
130139
emitting_diagnostics_cond_var: Condvar::new(),
131140
previous: prev_graph,
@@ -287,29 +296,42 @@ impl<K: DepKind> DepGraph<K> {
287296
let task_deps = Lock::new(TaskDeps::default());
288297
let result = K::with_deps(Some(&task_deps), op);
289298
let task_deps = task_deps.into_inner();
299+
let task_deps = task_deps.reads;
290300

291-
// The dep node indices are hashed here instead of hashing the dep nodes of the
292-
// dependencies. These indices may refer to different nodes per session, but this isn't
293-
// a problem here because we that ensure the final dep node hash is per session only by
294-
// combining it with the per session random number `anon_id_seed`. This hash only need
295-
// to map the dependencies to a single value on a per session basis.
296-
let mut hasher = StableHasher::new();
297-
task_deps.reads.hash(&mut hasher);
298-
299-
let target_dep_node = DepNode {
300-
kind: dep_kind,
301-
// Fingerprint::combine() is faster than sending Fingerprint
302-
// through the StableHasher (at least as long as StableHasher
303-
// is so slow).
304-
hash: data.current.anon_id_seed.combine(hasher.finish()).into(),
305-
};
301+
let dep_node_index = match task_deps.len() {
302+
0 => {
303+
// Dependency-less anonymous nodes can safely be replaced by a dummy node.
304+
DepNodeIndex::DUMMY_ANON
305+
}
306+
1 => {
307+
// When there is only one dependency, don't bother creating a node.
308+
task_deps[0]
309+
}
310+
_ => {
311+
// The dep node indices are hashed here instead of hashing the dep nodes of the
312+
// dependencies. These indices may refer to different nodes per session, but this isn't
313+
// a problem here because we that ensure the final dep node hash is per session only by
314+
// combining it with the per session random number `anon_id_seed`. This hash only need
315+
// to map the dependencies to a single value on a per session basis.
316+
let mut hasher = StableHasher::new();
317+
task_deps.hash(&mut hasher);
318+
319+
let target_dep_node = DepNode {
320+
kind: dep_kind,
321+
// Fingerprint::combine() is faster than sending Fingerprint
322+
// through the StableHasher (at least as long as StableHasher
323+
// is so slow).
324+
hash: data.current.anon_id_seed.combine(hasher.finish()).into(),
325+
};
306326

307-
let dep_node_index = data.current.intern_new_node(
308-
cx.profiler(),
309-
target_dep_node,
310-
task_deps.reads,
311-
Fingerprint::ZERO,
312-
);
327+
data.current.intern_new_node(
328+
cx.profiler(),
329+
target_dep_node,
330+
task_deps,
331+
Fingerprint::ZERO,
332+
)
333+
}
334+
};
313335

314336
(result, dep_node_index)
315337
} else {

0 commit comments

Comments
 (0)