1 use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
2 use super::{DepKind, DepNode};
3 use crate::dep_graph::DepContext;
4 use rustc_data_structures::fingerprint::Fingerprint;
5 use rustc_data_structures::fx::FxHashMap;
6 use rustc_span::def_id::DefPathHash;
8 #[derive(Debug, Encodable, Decodable)]
9 pub struct PreviousDepGraph<K: DepKind> {
10 data: SerializedDepGraph<K>,
11 index: FxHashMap<DepNode<K>, SerializedDepNodeIndex>,
14 impl<K: DepKind> Default for PreviousDepGraph<K> {
15 fn default() -> Self {
16 PreviousDepGraph { data: Default::default(), index: Default::default() }
20 impl<K: DepKind> PreviousDepGraph<K> {
21 pub fn new(data: SerializedDepGraph<K>) -> PreviousDepGraph<K> {
22 let index: FxHashMap<_, _> =
23 data.nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect();
24 PreviousDepGraph { data, index }
28 pub fn edge_targets_from(
30 dep_node_index: SerializedDepNodeIndex,
31 ) -> &[SerializedDepNodeIndex] {
32 self.data.edge_targets_from(dep_node_index)
36 pub fn index_to_node<CTX: DepContext<DepKind = K>>(
38 dep_node_index: SerializedDepNodeIndex,
41 let dep_node = self.data.nodes[dep_node_index];
42 // We have just loaded a deserialized `DepNode` from the previous
43 // compilation session into the current one. If this was a foreign `DefId`,
44 // then we stored additional information in the incr comp cache when we
45 // initially created its fingerprint (see `DepNodeParams::to_fingerprint`)
46 // We won't be calling `to_fingerprint` again for this `DepNode` (we no longer
47 // have the original value), so we need to copy over this additional information
48 // from the old incremental cache into the new cache that we serialize
49 // and the end of this compilation session.
50 if dep_node.kind.can_reconstruct_query_key() {
51 tcx.register_reused_dep_path_hash(DefPathHash(dep_node.hash.into()));
56 /// When debug assertions are enabled, asserts that the dep node at `dep_node_index` is equal to `dep_node`.
57 /// This method should be preferred over manually calling `index_to_node`.
58 /// Calls to `index_to_node` may affect global state, so gating a call
59 /// to `index_to_node` on debug assertions could cause behavior changes when debug assertions
62 pub fn debug_assert_eq(&self, dep_node_index: SerializedDepNodeIndex, dep_node: DepNode<K>) {
63 debug_assert_eq!(self.data.nodes[dep_node_index], dep_node);
66 /// Obtains a debug-printable version of the `DepNode`.
67 /// See `debug_assert_eq` for why this should be preferred over manually
68 /// calling `dep_node_index`
69 pub fn debug_dep_node(&self, dep_node_index: SerializedDepNodeIndex) -> impl std::fmt::Debug {
70 // We're returning the `DepNode` without calling `register_reused_dep_path_hash`,
71 // but `impl Debug` return type means that it can only be used for debug printing.
72 // So, there's no risk of calls trying to create new dep nodes that have this
73 // node as a dependency
74 self.data.nodes[dep_node_index]
78 pub fn node_to_index(&self, dep_node: &DepNode<K>) -> SerializedDepNodeIndex {
83 pub fn node_to_index_opt(&self, dep_node: &DepNode<K>) -> Option<SerializedDepNodeIndex> {
84 self.index.get(dep_node).cloned()
88 pub fn fingerprint_of(&self, dep_node: &DepNode<K>) -> Option<Fingerprint> {
89 self.index.get(dep_node).map(|&node_index| self.data.fingerprints[node_index])
93 pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint {
94 self.data.fingerprints[dep_node_index]
97 pub fn node_count(&self) -> usize {