Skip to content

Commit 290912a

Browse files
committed
Make dep node indices persistent between sessions
1 parent fcd003f commit 290912a

File tree

12 files changed

+492
-324
lines changed

12 files changed

+492
-324
lines changed

src/librustc/dep_graph/graph.rs

+373-245
Large diffs are not rendered by default.

src/librustc/dep_graph/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ pub mod cgu_reuse_tracker;
1111
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
1212
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs};
1313
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
14-
pub use self::graph::WorkProductFileKind;
14+
pub use self::graph::{DepGraphArgs, WorkProductFileKind, CurrentDepGraph};
1515
pub use self::prev::PreviousDepGraph;
1616
pub use self::query::DepGraphQuery;
1717
pub use self::safe::AssertDepGraphSafe;
1818
pub use self::safe::DepGraphSafe;
19-
pub use self::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
19+
pub use self::serialized::SerializedDepGraph;

src/librustc/dep_graph/prev.rs

+41-14
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,70 @@
11
use crate::ich::Fingerprint;
22
use rustc_data_structures::fx::FxHashMap;
3-
use super::dep_node::DepNode;
4-
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
3+
use rustc_data_structures::indexed_vec::IndexVec;
4+
use rustc_data_structures::sync::AtomicCell;
5+
use super::dep_node::{DepNode, DepKind};
6+
use super::graph::{DepNodeIndex, DepNodeState};
7+
use super::serialized::SerializedDepGraph;
58

6-
#[derive(Debug, RustcEncodable, RustcDecodable, Default)]
9+
#[derive(Debug, Default)]
710
pub struct PreviousDepGraph {
811
data: SerializedDepGraph,
9-
index: FxHashMap<DepNode, SerializedDepNodeIndex>,
12+
pub(super) index: FxHashMap<DepNode, DepNodeIndex>,
13+
pub(super) unused: Vec<DepNodeIndex>,
1014
}
1115

1216
impl PreviousDepGraph {
13-
pub fn new(data: SerializedDepGraph) -> PreviousDepGraph {
17+
pub fn new_and_state(
18+
data: SerializedDepGraph
19+
) -> (PreviousDepGraph, IndexVec<DepNodeIndex, AtomicCell<DepNodeState>>) {
20+
let mut unused = Vec::new();
21+
22+
let state: IndexVec<_, _> = data.nodes.iter_enumerated().map(|(index, node)| {
23+
if node.kind == DepKind::Null {
24+
// There might be `DepKind::Null` nodes due to thread-local dep node indices
25+
// that didn't get assigned anything.
26+
// We also changed outdated nodes to `DepKind::Null`.
27+
unused.push(index);
28+
AtomicCell::new(DepNodeState::Invalid)
29+
} else {
30+
AtomicCell::new(DepNodeState::Unknown)
31+
}
32+
}).collect();
33+
1434
let index: FxHashMap<_, _> = data.nodes
1535
.iter_enumerated()
16-
.map(|(idx, &dep_node)| (dep_node, idx))
36+
.filter_map(|(idx, &dep_node)| {
37+
if dep_node.kind == DepKind::Null {
38+
None
39+
} else {
40+
Some((dep_node, idx))
41+
}
42+
})
1743
.collect();
18-
PreviousDepGraph { data, index }
44+
45+
(PreviousDepGraph { data, index, unused }, state)
1946
}
2047

2148
#[inline]
2249
pub fn edge_targets_from(
2350
&self,
24-
dep_node_index: SerializedDepNodeIndex
25-
) -> &[SerializedDepNodeIndex] {
51+
dep_node_index: DepNodeIndex
52+
) -> &[DepNodeIndex] {
2653
self.data.edge_targets_from(dep_node_index)
2754
}
2855

2956
#[inline]
30-
pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
57+
pub fn index_to_node(&self, dep_node_index: DepNodeIndex) -> DepNode {
3158
self.data.nodes[dep_node_index]
3259
}
3360

3461
#[inline]
35-
pub fn node_to_index(&self, dep_node: &DepNode) -> SerializedDepNodeIndex {
62+
pub fn node_to_index(&self, dep_node: &DepNode) -> DepNodeIndex {
3663
self.index[dep_node]
3764
}
3865

3966
#[inline]
40-
pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
67+
pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<DepNodeIndex> {
4168
self.index.get(dep_node).cloned()
4269
}
4370

@@ -50,12 +77,12 @@ impl PreviousDepGraph {
5077

5178
#[inline]
5279
pub fn fingerprint_by_index(&self,
53-
dep_node_index: SerializedDepNodeIndex)
80+
dep_node_index: DepNodeIndex)
5481
-> Fingerprint {
5582
self.data.fingerprints[dep_node_index]
5683
}
5784

5885
pub fn node_count(&self) -> usize {
59-
self.index.len()
86+
self.data.nodes.len()
6087
}
6188
}

src/librustc/dep_graph/serialized.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,31 @@
22
33
use crate::dep_graph::DepNode;
44
use crate::ich::Fingerprint;
5-
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
6-
7-
newtype_index! {
8-
pub struct SerializedDepNodeIndex { .. }
9-
}
5+
use rustc_data_structures::indexed_vec::IndexVec;
6+
use super::graph::DepNodeIndex;
107

118
/// Data for use when recompiling the **current crate**.
129
#[derive(Debug, RustcEncodable, RustcDecodable, Default)]
1310
pub struct SerializedDepGraph {
1411
/// The set of all DepNodes in the graph
15-
pub nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
12+
pub nodes: IndexVec<DepNodeIndex, DepNode>,
1613
/// The set of all Fingerprints in the graph. Each Fingerprint corresponds to
1714
/// the DepNode at the same index in the nodes vector.
18-
pub fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
15+
pub fingerprints: IndexVec<DepNodeIndex, Fingerprint>,
1916
/// For each DepNode, stores the list of edges originating from that
2017
/// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
2118
/// which holds the actual DepNodeIndices of the target nodes.
22-
pub edge_list_indices: IndexVec<SerializedDepNodeIndex, (u32, u32)>,
19+
pub edge_list_indices: IndexVec<DepNodeIndex, (u32, u32)>,
2320
/// A flattened list of all edge targets in the graph. Edge sources are
2421
/// implicit in edge_list_indices.
25-
pub edge_list_data: Vec<SerializedDepNodeIndex>,
22+
pub edge_list_data: Vec<DepNodeIndex>,
2623
}
2724

2825
impl SerializedDepGraph {
2926
#[inline]
3027
pub fn edge_targets_from(&self,
31-
source: SerializedDepNodeIndex)
32-
-> &[SerializedDepNodeIndex] {
28+
source: DepNodeIndex)
29+
-> &[DepNodeIndex] {
3330
let targets = self.edge_list_indices[source];
3431
&self.edge_list_data[targets.0 as usize..targets.1 as usize]
3532
}

src/librustc/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use crate::ty::query::QueryDescription;
22
use crate::ty::query::queries;
33
use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
44
use crate::ty::subst::SubstsRef;
5-
use crate::dep_graph::SerializedDepNodeIndex;
65
use crate::hir::def_id::{CrateNum, DefId, DefIndex};
76
use crate::mir;
87
use crate::mir::interpret::GlobalId;
8+
use crate::dep_graph::DepNodeIndex;
99
use crate::traits;
1010
use crate::traits::query::{
1111
CanonicalPredicateGoal, CanonicalProjectionGoal,

src/librustc/ty/query/config.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::dep_graph::SerializedDepNodeIndex;
2-
use crate::dep_graph::DepNode;
1+
use crate::dep_graph::{DepNode, DepNodeIndex};
32
use crate::hir::def_id::{CrateNum, DefId};
43
use crate::ty::TyCtxt;
54
use crate::ty::query::queries;
@@ -54,7 +53,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
5453
false
5554
}
5655

57-
fn try_load_from_disk(_: TyCtxt<'tcx>, _: SerializedDepNodeIndex) -> Option<Self::Value> {
56+
fn try_load_from_disk(_: TyCtxt<'tcx>, _: DepNodeIndex) -> Option<Self::Value> {
5857
bug!("QueryDescription::load_from_disk() called for an unsupported query.")
5958
}
6059
}
@@ -86,7 +85,7 @@ macro_rules! impl_disk_cacheable_query(
8685

8786
#[inline]
8887
fn try_load_from_disk(tcx: TyCtxt<'tcx>,
89-
id: SerializedDepNodeIndex)
88+
id: DepNodeIndex)
9089
-> Option<Self::Value> {
9190
tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
9291
}

src/librustc/ty/query/on_disk_cache.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
1+
use crate::dep_graph::DepNodeIndex;
22
use crate::hir;
33
use crate::hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
44
use crate::hir::map::definitions::DefPathHash;
@@ -62,11 +62,11 @@ pub struct OnDiskCache<'sess> {
6262

6363
// A map from dep-node to the position of the cached query result in
6464
// `serialized_data`.
65-
query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
65+
query_result_index: FxHashMap<DepNodeIndex, AbsoluteBytePos>,
6666

6767
// A map from dep-node to the position of any associated diagnostics in
6868
// `serialized_data`.
69-
prev_diagnostics_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
69+
prev_diagnostics_index: FxHashMap<DepNodeIndex, AbsoluteBytePos>,
7070

7171
alloc_decoding_state: AllocDecodingState,
7272
}
@@ -82,8 +82,8 @@ struct Footer {
8282
interpret_alloc_index: Vec<u32>,
8383
}
8484

85-
type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
86-
type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
85+
type EncodedQueryResultIndex = Vec<(DepNodeIndex, AbsoluteBytePos)>;
86+
type EncodedDiagnosticsIndex = Vec<(DepNodeIndex, AbsoluteBytePos)>;
8787
type EncodedDiagnostics = Vec<Diagnostic>;
8888

8989
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
@@ -230,12 +230,12 @@ impl<'sess> OnDiskCache<'sess> {
230230
use crate::ty::query::config::QueryDescription;
231231
if const_eval::cache_on_disk(tcx, key.clone()) {
232232
if let Ok(ref value) = entry.value {
233-
let dep_node = SerializedDepNodeIndex::new(entry.index.index());
233+
let dep_node = DepNodeIndex::new(entry.index.index());
234234

235235
// Record position of the cache entry
236236
qri.push((dep_node, AbsoluteBytePos::new(enc.position())));
237237

238-
// Encode the type check tables with the SerializedDepNodeIndex
238+
// Encode the type check tables with the DepNodeIndex
239239
// as tag.
240240
enc.encode_tagged(dep_node, value)?;
241241
}
@@ -253,7 +253,7 @@ impl<'sess> OnDiskCache<'sess> {
253253
let pos = AbsoluteBytePos::new(encoder.position());
254254
// Let's make sure we get the expected type here:
255255
let diagnostics: &EncodedDiagnostics = diagnostics;
256-
let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
256+
let dep_node_index = DepNodeIndex::new(dep_node_index.index());
257257
encoder.encode_tagged(dep_node_index, diagnostics)?;
258258

259259
Ok((dep_node_index, pos))
@@ -327,7 +327,7 @@ impl<'sess> OnDiskCache<'sess> {
327327
pub fn load_diagnostics<'tcx>(
328328
&self,
329329
tcx: TyCtxt<'tcx>,
330-
dep_node_index: SerializedDepNodeIndex,
330+
dep_node_index: DepNodeIndex,
331331
) -> Vec<Diagnostic> {
332332
let diagnostics: Option<EncodedDiagnostics> = self.load_indexed(
333333
tcx,
@@ -352,11 +352,11 @@ impl<'sess> OnDiskCache<'sess> {
352352
}
353353

354354
/// Returns the cached query result if there is something in the cache for
355-
/// the given `SerializedDepNodeIndex`; otherwise returns `None`.
355+
/// the given `DepNodeIndex`; otherwise returns `None`.
356356
pub fn try_load_query_result<'tcx, T>(
357357
&self,
358358
tcx: TyCtxt<'tcx>,
359-
dep_node_index: SerializedDepNodeIndex,
359+
dep_node_index: DepNodeIndex,
360360
) -> Option<T>
361361
where
362362
T: Decodable,
@@ -386,8 +386,8 @@ impl<'sess> OnDiskCache<'sess> {
386386
fn load_indexed<'tcx, T>(
387387
&self,
388388
tcx: TyCtxt<'tcx>,
389-
dep_node_index: SerializedDepNodeIndex,
390-
index: &FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
389+
dep_node_index: DepNodeIndex,
390+
index: &FxHashMap<DepNodeIndex, AbsoluteBytePos>,
391391
debug_tag: &'static str,
392392
) -> Option<T>
393393
where
@@ -1091,12 +1091,12 @@ where
10911091
assert!(shards.iter().all(|shard| shard.active.is_empty()));
10921092
for (key, entry) in shards.iter().flat_map(|shard| shard.results.iter()) {
10931093
if Q::cache_on_disk(tcx, key.clone()) {
1094-
let dep_node = SerializedDepNodeIndex::new(entry.index.index());
1094+
let dep_node = DepNodeIndex::new(entry.index.index());
10951095

10961096
// Record position of the cache entry
10971097
query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
10981098

1099-
// Encode the type check tables with the SerializedDepNodeIndex
1099+
// Encode the type check tables with the DepNodeIndex
11001100
// as tag.
11011101
encoder.encode_tagged(dep_node, &entry.value)?;
11021102
}

src/librustc/ty/query/plumbing.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! generate the actual methods on tcx which find and execute the provider,
33
//! manage the caches, and so forth.
44
5-
use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex};
5+
use crate::dep_graph::{DepNodeIndex, DepNode, DepKind};
66
use crate::ty::tls;
77
use crate::ty::{self, TyCtxt};
88
use crate::ty::query::Query;
@@ -413,10 +413,9 @@ impl<'tcx> TyCtxt<'tcx> {
413413
// try_mark_green(), so we can ignore them here.
414414
let loaded = self.start_query(job.job.clone(), None, |tcx| {
415415
let marked = tcx.dep_graph.try_mark_green_and_read(tcx, &dep_node);
416-
marked.map(|(prev_dep_node_index, dep_node_index)| {
416+
marked.map(|dep_node_index| {
417417
(tcx.load_from_disk_and_cache_in_memory::<Q>(
418418
key.clone(),
419-
prev_dep_node_index,
420419
dep_node_index,
421420
&dep_node
422421
), dep_node_index)
@@ -436,7 +435,6 @@ impl<'tcx> TyCtxt<'tcx> {
436435
fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'tcx>>(
437436
self,
438437
key: Q::Key,
439-
prev_dep_node_index: SerializedDepNodeIndex,
440438
dep_node_index: DepNodeIndex,
441439
dep_node: &DepNode,
442440
) -> Q::Value {
@@ -449,7 +447,7 @@ impl<'tcx> TyCtxt<'tcx> {
449447
let result = if Q::cache_on_disk(self.global_tcx(), key.clone()) &&
450448
self.sess.opts.debugging_opts.incremental_queries {
451449
self.sess.profiler(|p| p.incremental_load_result_start(Q::NAME));
452-
let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index);
450+
let result = Q::try_load_from_disk(self.global_tcx(), dep_node_index);
453451
self.sess.profiler(|p| p.incremental_load_result_end(Q::NAME));
454452

455453
// We always expect to find a cached result for things that
@@ -488,7 +486,7 @@ impl<'tcx> TyCtxt<'tcx> {
488486
// If -Zincremental-verify-ich is specified, re-hash results from
489487
// the cache and make sure that they have the expected fingerprint.
490488
if unlikely!(self.sess.opts.debugging_opts.incremental_verify_ich) {
491-
self.incremental_verify_ich::<Q>(&result, dep_node, dep_node_index);
489+
self.incremental_verify_ich::<Q>(&result, dep_node);
492490
}
493491

494492
if unlikely!(self.sess.opts.debugging_opts.query_dep_graph) {
@@ -504,24 +502,18 @@ impl<'tcx> TyCtxt<'tcx> {
504502
self,
505503
result: &Q::Value,
506504
dep_node: &DepNode,
507-
dep_node_index: DepNodeIndex,
508505
) {
509506
use crate::ich::Fingerprint;
510507

511-
assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
512-
self.dep_graph.prev_fingerprint_of(dep_node),
513-
"Fingerprint for green query instance not loaded \
514-
from cache: {:?}", dep_node);
515-
516508
debug!("BEGIN verify_ich({:?})", dep_node);
517509
let mut hcx = self.create_stable_hashing_context();
518510

519511
let new_hash = Q::hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO);
520512
debug!("END verify_ich({:?})", dep_node);
521513

522-
let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
514+
let old_hash = self.dep_graph.prev_fingerprint_of(dep_node);
523515

524-
assert!(new_hash == old_hash, "Found unstable fingerprints \
516+
assert!(Some(new_hash) == old_hash, "Found unstable fingerprints \
525517
for {:?}", dep_node);
526518
}
527519

0 commit comments

Comments
 (0)