Skip to content

Commit 7312ac3

Browse files
authored
Rollup merge of #152751 - Zalathar:fingerprint, r=nnethercote
Rename dep node "fingerprints" to distinguish key and value hashes In the query system's dependency graph, each node is associated with two *fingerprints*: one that is typically a hash of the query key, and one that is typically a hash of the query's return value when called with that key. Unfortunately, many identifiers and comments fail to clearly distinguish between these two kinds of fingerprint, which have very different roles in dependency tracking. This is a frequent source of confusion. This PR therefore tries to establish a clear distinction between: - **Key fingerprints** that help to uniquely identify a node (along with its `DepKind`), and are typically a hash of the query key - **Value fingerprints** that help to determine whether a node can be marked green (despite having red dependencies), and are typically a hash of the query value There should be no change to compiler behaviour. r? nnethercote (or compiler)
2 parents dbc2193 + b015d57 commit 7312ac3

12 files changed

Lines changed: 207 additions & 175 deletions

File tree

compiler/rustc_incremental/src/persist/clean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ impl<'tcx> CleanVisitor<'tcx> {
322322
if let Some(def_id) = dep_node.extract_def_id(self.tcx) {
323323
format!("{:?}({})", dep_node.kind, self.tcx.def_path_str(def_id))
324324
} else {
325-
format!("{:?}({:?})", dep_node.kind, dep_node.hash)
325+
format!("{:?}({:?})", dep_node.kind, dep_node.key_fingerprint)
326326
}
327327
}
328328

compiler/rustc_middle/src/dep_graph/dep_node.rs

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
//! This module defines the [`DepNode`] type which the compiler uses to represent
22
//! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which
33
//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
4-
//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
5-
//! depends on the node's `DepKind`. Together, the kind and the fingerprint
4+
//! and a "key fingerprint", a 128-bit hash value, the exact meaning of which
5+
//! depends on the node's `DepKind`. Together, the kind and the key fingerprint
66
//! fully identify a dependency node, even across multiple compilation sessions.
7-
//! In other words, the value of the fingerprint does not depend on anything
7+
//! In other words, the value of the key fingerprint does not depend on anything
88
//! that is specific to a given compilation session, like an unpredictable
99
//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
1010
//! pointer. The concept behind this could be compared to how git commit hashes
@@ -41,17 +41,9 @@
4141
//! `DepNode`s could represent global concepts with only one value.
4242
//! * Whether it is possible, in principle, to reconstruct a query key from a
4343
//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
44-
//! in which case it is possible to map the node's fingerprint back to the
44+
//! in which case it is possible to map the node's key fingerprint back to the
4545
//! `DefId` it was computed from. In other cases, too much information gets
46-
//! lost during fingerprint computation.
47-
//!
48-
//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
49-
//! `DepNode::new()`, ensure that only valid `DepNode` instances can be
50-
//! constructed. For example, the API does not allow for constructing
51-
//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
52-
//! More generally speaking, it relieves the user of the `DepNode` API of
53-
//! having to know how to compute the expected fingerprint for a given set of
54-
//! node parameters.
46+
//! lost when computing a key fingerprint.
5547
//!
5648
//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
5749
@@ -65,7 +57,7 @@ use rustc_hir::definitions::DefPathHash;
6557
use rustc_macros::{Decodable, Encodable};
6658
use rustc_span::Symbol;
6759

68-
use super::{FingerprintStyle, SerializedDepNodeIndex};
60+
use super::{KeyFingerprintStyle, SerializedDepNodeIndex};
6961
use crate::ich::StableHashingContext;
7062
use crate::mir::mono::MonoItem;
7163
use crate::ty::{TyCtxt, tls};
@@ -125,35 +117,44 @@ impl fmt::Debug for DepKind {
125117
}
126118
}
127119

120+
/// Combination of a [`DepKind`] and a key fingerprint that uniquely identifies
121+
/// a node in the dep graph.
128122
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
129123
pub struct DepNode {
130124
pub kind: DepKind,
131-
pub hash: PackedFingerprint,
125+
126+
/// This is _typically_ a hash of the query key, but sometimes not.
127+
///
128+
/// For example, `anon` nodes have a fingerprint that is derived from their
129+
/// dependencies instead of a key.
130+
///
131+
/// In some cases the key value can be reconstructed from this fingerprint;
132+
/// see [`KeyFingerprintStyle`].
133+
pub key_fingerprint: PackedFingerprint,
132134
}
133135

134136
impl DepNode {
135137
/// Creates a new, parameterless DepNode. This method will assert
136138
/// that the DepNode corresponding to the given DepKind actually
137139
/// does not require any parameters.
138140
pub fn new_no_params<'tcx>(tcx: TyCtxt<'tcx>, kind: DepKind) -> DepNode {
139-
debug_assert_eq!(tcx.fingerprint_style(kind), FingerprintStyle::Unit);
140-
DepNode { kind, hash: Fingerprint::ZERO.into() }
141+
debug_assert_eq!(tcx.key_fingerprint_style(kind), KeyFingerprintStyle::Unit);
142+
DepNode { kind, key_fingerprint: Fingerprint::ZERO.into() }
141143
}
142144

143-
pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, arg: &Key) -> DepNode
145+
pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, key: &Key) -> DepNode
144146
where
145147
Key: DepNodeKey<'tcx>,
146148
{
147-
let hash = arg.to_fingerprint(tcx);
148-
let dep_node = DepNode { kind, hash: hash.into() };
149+
let dep_node = DepNode { kind, key_fingerprint: key.to_fingerprint(tcx).into() };
149150

150151
#[cfg(debug_assertions)]
151152
{
152-
if !tcx.fingerprint_style(kind).reconstructible()
153+
if !tcx.key_fingerprint_style(kind).reconstructible()
153154
&& (tcx.sess.opts.unstable_opts.incremental_info
154155
|| tcx.sess.opts.unstable_opts.query_dep_graph)
155156
{
156-
tcx.dep_graph.register_dep_node_debug_str(dep_node, || arg.to_debug_str(tcx));
157+
tcx.dep_graph.register_dep_node_debug_str(dep_node, || key.to_debug_str(tcx));
157158
}
158159
}
159160

@@ -168,8 +169,8 @@ impl DepNode {
168169
def_path_hash: DefPathHash,
169170
kind: DepKind,
170171
) -> Self {
171-
debug_assert!(tcx.fingerprint_style(kind) == FingerprintStyle::DefPathHash);
172-
DepNode { kind, hash: def_path_hash.0.into() }
172+
debug_assert!(tcx.key_fingerprint_style(kind) == KeyFingerprintStyle::DefPathHash);
173+
DepNode { kind, key_fingerprint: def_path_hash.0.into() }
173174
}
174175
}
175176

@@ -184,10 +185,10 @@ impl fmt::Debug for DepNode {
184185
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
185186
write!(f, "{s}")?;
186187
} else {
187-
write!(f, "{}", self.hash)?;
188+
write!(f, "{}", self.key_fingerprint)?;
188189
}
189190
} else {
190-
write!(f, "{}", self.hash)?;
191+
write!(f, "{}", self.key_fingerprint)?;
191192
}
192193
Ok(())
193194
})?;
@@ -198,7 +199,7 @@ impl fmt::Debug for DepNode {
198199

199200
/// Trait for query keys as seen by dependency-node tracking.
200201
pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
201-
fn fingerprint_style() -> FingerprintStyle;
202+
fn key_fingerprint_style() -> KeyFingerprintStyle;
202203

203204
/// This method turns a query key into an opaque `Fingerprint` to be used
204205
/// in `DepNode`.
@@ -212,7 +213,7 @@ pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
212213
/// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
213214
/// It is always valid to return `None` here, in which case incremental
214215
/// compilation will treat the query as having changed instead of forcing it.
215-
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
216+
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
216217
}
217218

218219
// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere.
@@ -221,8 +222,8 @@ where
221222
T: for<'a> HashStable<StableHashingContext<'a>> + fmt::Debug,
222223
{
223224
#[inline(always)]
224-
default fn fingerprint_style() -> FingerprintStyle {
225-
FingerprintStyle::Opaque
225+
default fn key_fingerprint_style() -> KeyFingerprintStyle {
226+
KeyFingerprintStyle::Opaque
226227
}
227228

228229
#[inline(always)]
@@ -243,7 +244,7 @@ where
243244
}
244245

245246
#[inline(always)]
246-
default fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
247+
default fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
247248
None
248249
}
249250
}
@@ -264,10 +265,11 @@ pub struct DepKindVTable<'tcx> {
264265
/// cached within one compiler invocation.
265266
pub is_eval_always: bool,
266267

267-
/// Indicates whether and how the query key can be recovered from its hashed fingerprint.
268+
/// Indicates whether and how a query key can be reconstructed from the
269+
/// key fingerprint of a dep node with this [`DepKind`].
268270
///
269271
/// The [`DepNodeKey`] trait determines the fingerprint style for each key type.
270-
pub fingerprint_style: FingerprintStyle,
272+
pub key_fingerprint_style: KeyFingerprintStyle,
271273

272274
/// The red/green evaluation system will try to mark a specific DepNode in the
273275
/// dependency graph as green by recursively trying to mark the dependencies of
@@ -279,7 +281,7 @@ pub struct DepKindVTable<'tcx> {
279281
/// `force_from_dep_node()` implements.
280282
///
281283
/// In the general case, a `DepNode` consists of a `DepKind` and an opaque
282-
/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
284+
/// "key fingerprint" that will uniquely identify the node. This key fingerprint
283285
/// is usually constructed by computing a stable hash of the query-key that the
284286
/// `DepNode` corresponds to. Consequently, it is not in general possible to go
285287
/// back from hash to query-key (since hash functions are not reversible). For
@@ -293,15 +295,15 @@ pub struct DepKindVTable<'tcx> {
293295
/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
294296
/// Fortunately, we can use some contextual information that will allow us to
295297
/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
296-
/// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
298+
/// enforce by construction that the key fingerprint of certain `DepNode`s is a
297299
/// valid `DefPathHash`. Since we also always build a huge table that maps every
298300
/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
299301
/// everything we need to re-run the query.
300302
///
301303
/// Take the `mir_promoted` query as an example. Like many other queries, it
302304
/// just has a single parameter: the `DefId` of the item it will compute the
303305
/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
304-
/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
306+
/// with kind `mir_promoted`, we know that the key fingerprint of the `DepNode`
305307
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
306308
/// `DefId` in `tcx.def_path_hash_to_def_id`.
307309
pub force_from_dep_node: Option<
@@ -472,8 +474,8 @@ impl DepNode {
472474
/// refers to something from the previous compilation session that
473475
/// has been removed.
474476
pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
475-
if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
476-
tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()))
477+
if tcx.key_fingerprint_style(self.kind) == KeyFingerprintStyle::DefPathHash {
478+
tcx.def_path_hash_to_def_id(DefPathHash(self.key_fingerprint.into()))
477479
} else {
478480
None
479481
}
@@ -486,10 +488,10 @@ impl DepNode {
486488
) -> Result<DepNode, ()> {
487489
let kind = dep_kind_from_label_string(label)?;
488490

489-
match tcx.fingerprint_style(kind) {
490-
FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()),
491-
FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
492-
FingerprintStyle::DefPathHash => {
491+
match tcx.key_fingerprint_style(kind) {
492+
KeyFingerprintStyle::Opaque | KeyFingerprintStyle::HirId => Err(()),
493+
KeyFingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
494+
KeyFingerprintStyle::DefPathHash => {
493495
Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind))
494496
}
495497
}

0 commit comments

Comments
 (0)