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)
This commit is contained in:
commit
7312ac389f
12 changed files with 207 additions and 175 deletions
|
|
@ -322,7 +322,7 @@ impl<'tcx> CleanVisitor<'tcx> {
|
||||||
if let Some(def_id) = dep_node.extract_def_id(self.tcx) {
|
if let Some(def_id) = dep_node.extract_def_id(self.tcx) {
|
||||||
format!("{:?}({})", dep_node.kind, self.tcx.def_path_str(def_id))
|
format!("{:?}({})", dep_node.kind, self.tcx.def_path_str(def_id))
|
||||||
} else {
|
} else {
|
||||||
format!("{:?}({:?})", dep_node.kind, dep_node.hash)
|
format!("{:?}({:?})", dep_node.kind, dep_node.key_fingerprint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
//! This module defines the [`DepNode`] type which the compiler uses to represent
|
//! This module defines the [`DepNode`] type which the compiler uses to represent
|
||||||
//! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which
|
//! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which
|
||||||
//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
|
//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
|
||||||
//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
|
//! and a "key fingerprint", a 128-bit hash value, the exact meaning of which
|
||||||
//! depends on the node's `DepKind`. Together, the kind and the fingerprint
|
//! depends on the node's `DepKind`. Together, the kind and the key fingerprint
|
||||||
//! fully identify a dependency node, even across multiple compilation sessions.
|
//! fully identify a dependency node, even across multiple compilation sessions.
|
||||||
//! In other words, the value of the fingerprint does not depend on anything
|
//! In other words, the value of the key fingerprint does not depend on anything
|
||||||
//! that is specific to a given compilation session, like an unpredictable
|
//! that is specific to a given compilation session, like an unpredictable
|
||||||
//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
|
//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
|
||||||
//! pointer. The concept behind this could be compared to how git commit hashes
|
//! pointer. The concept behind this could be compared to how git commit hashes
|
||||||
|
|
@ -41,17 +41,9 @@
|
||||||
//! `DepNode`s could represent global concepts with only one value.
|
//! `DepNode`s could represent global concepts with only one value.
|
||||||
//! * Whether it is possible, in principle, to reconstruct a query key from a
|
//! * Whether it is possible, in principle, to reconstruct a query key from a
|
||||||
//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
|
//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
|
||||||
//! in which case it is possible to map the node's fingerprint back to the
|
//! in which case it is possible to map the node's key fingerprint back to the
|
||||||
//! `DefId` it was computed from. In other cases, too much information gets
|
//! `DefId` it was computed from. In other cases, too much information gets
|
||||||
//! lost during fingerprint computation.
|
//! lost when computing a key fingerprint.
|
||||||
//!
|
|
||||||
//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
|
|
||||||
//! `DepNode::new()`, ensure that only valid `DepNode` instances can be
|
|
||||||
//! constructed. For example, the API does not allow for constructing
|
|
||||||
//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
|
|
||||||
//! More generally speaking, it relieves the user of the `DepNode` API of
|
|
||||||
//! having to know how to compute the expected fingerprint for a given set of
|
|
||||||
//! node parameters.
|
|
||||||
//!
|
//!
|
||||||
//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
|
//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
|
||||||
|
|
||||||
|
|
@ -65,7 +57,7 @@ use rustc_hir::definitions::DefPathHash;
|
||||||
use rustc_macros::{Decodable, Encodable};
|
use rustc_macros::{Decodable, Encodable};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
|
|
||||||
use super::{FingerprintStyle, SerializedDepNodeIndex};
|
use super::{KeyFingerprintStyle, SerializedDepNodeIndex};
|
||||||
use crate::ich::StableHashingContext;
|
use crate::ich::StableHashingContext;
|
||||||
use crate::mir::mono::MonoItem;
|
use crate::mir::mono::MonoItem;
|
||||||
use crate::ty::{TyCtxt, tls};
|
use crate::ty::{TyCtxt, tls};
|
||||||
|
|
@ -125,10 +117,20 @@ impl fmt::Debug for DepKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Combination of a [`DepKind`] and a key fingerprint that uniquely identifies
|
||||||
|
/// a node in the dep graph.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct DepNode {
|
pub struct DepNode {
|
||||||
pub kind: DepKind,
|
pub kind: DepKind,
|
||||||
pub hash: PackedFingerprint,
|
|
||||||
|
/// This is _typically_ a hash of the query key, but sometimes not.
|
||||||
|
///
|
||||||
|
/// For example, `anon` nodes have a fingerprint that is derived from their
|
||||||
|
/// dependencies instead of a key.
|
||||||
|
///
|
||||||
|
/// In some cases the key value can be reconstructed from this fingerprint;
|
||||||
|
/// see [`KeyFingerprintStyle`].
|
||||||
|
pub key_fingerprint: PackedFingerprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DepNode {
|
impl DepNode {
|
||||||
|
|
@ -136,24 +138,23 @@ impl DepNode {
|
||||||
/// that the DepNode corresponding to the given DepKind actually
|
/// that the DepNode corresponding to the given DepKind actually
|
||||||
/// does not require any parameters.
|
/// does not require any parameters.
|
||||||
pub fn new_no_params<'tcx>(tcx: TyCtxt<'tcx>, kind: DepKind) -> DepNode {
|
pub fn new_no_params<'tcx>(tcx: TyCtxt<'tcx>, kind: DepKind) -> DepNode {
|
||||||
debug_assert_eq!(tcx.fingerprint_style(kind), FingerprintStyle::Unit);
|
debug_assert_eq!(tcx.key_fingerprint_style(kind), KeyFingerprintStyle::Unit);
|
||||||
DepNode { kind, hash: Fingerprint::ZERO.into() }
|
DepNode { kind, key_fingerprint: Fingerprint::ZERO.into() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, arg: &Key) -> DepNode
|
pub fn construct<'tcx, Key>(tcx: TyCtxt<'tcx>, kind: DepKind, key: &Key) -> DepNode
|
||||||
where
|
where
|
||||||
Key: DepNodeKey<'tcx>,
|
Key: DepNodeKey<'tcx>,
|
||||||
{
|
{
|
||||||
let hash = arg.to_fingerprint(tcx);
|
let dep_node = DepNode { kind, key_fingerprint: key.to_fingerprint(tcx).into() };
|
||||||
let dep_node = DepNode { kind, hash: hash.into() };
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
if !tcx.fingerprint_style(kind).reconstructible()
|
if !tcx.key_fingerprint_style(kind).reconstructible()
|
||||||
&& (tcx.sess.opts.unstable_opts.incremental_info
|
&& (tcx.sess.opts.unstable_opts.incremental_info
|
||||||
|| tcx.sess.opts.unstable_opts.query_dep_graph)
|
|| tcx.sess.opts.unstable_opts.query_dep_graph)
|
||||||
{
|
{
|
||||||
tcx.dep_graph.register_dep_node_debug_str(dep_node, || arg.to_debug_str(tcx));
|
tcx.dep_graph.register_dep_node_debug_str(dep_node, || key.to_debug_str(tcx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,8 +169,8 @@ impl DepNode {
|
||||||
def_path_hash: DefPathHash,
|
def_path_hash: DefPathHash,
|
||||||
kind: DepKind,
|
kind: DepKind,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
debug_assert!(tcx.fingerprint_style(kind) == FingerprintStyle::DefPathHash);
|
debug_assert!(tcx.key_fingerprint_style(kind) == KeyFingerprintStyle::DefPathHash);
|
||||||
DepNode { kind, hash: def_path_hash.0.into() }
|
DepNode { kind, key_fingerprint: def_path_hash.0.into() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,10 +185,10 @@ impl fmt::Debug for DepNode {
|
||||||
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
|
} else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
|
||||||
write!(f, "{s}")?;
|
write!(f, "{s}")?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", self.hash)?;
|
write!(f, "{}", self.key_fingerprint)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", self.hash)?;
|
write!(f, "{}", self.key_fingerprint)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -198,7 +199,7 @@ impl fmt::Debug for DepNode {
|
||||||
|
|
||||||
/// Trait for query keys as seen by dependency-node tracking.
|
/// Trait for query keys as seen by dependency-node tracking.
|
||||||
pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
|
pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
|
||||||
fn fingerprint_style() -> FingerprintStyle;
|
fn key_fingerprint_style() -> KeyFingerprintStyle;
|
||||||
|
|
||||||
/// This method turns a query key into an opaque `Fingerprint` to be used
|
/// This method turns a query key into an opaque `Fingerprint` to be used
|
||||||
/// in `DepNode`.
|
/// in `DepNode`.
|
||||||
|
|
@ -212,7 +213,7 @@ pub trait DepNodeKey<'tcx>: fmt::Debug + Sized {
|
||||||
/// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
|
/// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
|
||||||
/// It is always valid to return `None` here, in which case incremental
|
/// It is always valid to return `None` here, in which case incremental
|
||||||
/// compilation will treat the query as having changed instead of forcing it.
|
/// compilation will treat the query as having changed instead of forcing it.
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere.
|
// Blanket impl of `DepNodeKey`, which is specialized by other impls elsewhere.
|
||||||
|
|
@ -221,8 +222,8 @@ where
|
||||||
T: for<'a> HashStable<StableHashingContext<'a>> + fmt::Debug,
|
T: for<'a> HashStable<StableHashingContext<'a>> + fmt::Debug,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
default fn fingerprint_style() -> FingerprintStyle {
|
default fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::Opaque
|
KeyFingerprintStyle::Opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -243,7 +244,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
default fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
default fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -264,10 +265,11 @@ pub struct DepKindVTable<'tcx> {
|
||||||
/// cached within one compiler invocation.
|
/// cached within one compiler invocation.
|
||||||
pub is_eval_always: bool,
|
pub is_eval_always: bool,
|
||||||
|
|
||||||
/// Indicates whether and how the query key can be recovered from its hashed fingerprint.
|
/// Indicates whether and how a query key can be reconstructed from the
|
||||||
|
/// key fingerprint of a dep node with this [`DepKind`].
|
||||||
///
|
///
|
||||||
/// The [`DepNodeKey`] trait determines the fingerprint style for each key type.
|
/// The [`DepNodeKey`] trait determines the fingerprint style for each key type.
|
||||||
pub fingerprint_style: FingerprintStyle,
|
pub key_fingerprint_style: KeyFingerprintStyle,
|
||||||
|
|
||||||
/// The red/green evaluation system will try to mark a specific DepNode in the
|
/// The red/green evaluation system will try to mark a specific DepNode in the
|
||||||
/// dependency graph as green by recursively trying to mark the dependencies of
|
/// dependency graph as green by recursively trying to mark the dependencies of
|
||||||
|
|
@ -279,7 +281,7 @@ pub struct DepKindVTable<'tcx> {
|
||||||
/// `force_from_dep_node()` implements.
|
/// `force_from_dep_node()` implements.
|
||||||
///
|
///
|
||||||
/// In the general case, a `DepNode` consists of a `DepKind` and an opaque
|
/// In the general case, a `DepNode` consists of a `DepKind` and an opaque
|
||||||
/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
|
/// "key fingerprint" that will uniquely identify the node. This key fingerprint
|
||||||
/// is usually constructed by computing a stable hash of the query-key that the
|
/// is usually constructed by computing a stable hash of the query-key that the
|
||||||
/// `DepNode` corresponds to. Consequently, it is not in general possible to go
|
/// `DepNode` corresponds to. Consequently, it is not in general possible to go
|
||||||
/// back from hash to query-key (since hash functions are not reversible). For
|
/// back from hash to query-key (since hash functions are not reversible). For
|
||||||
|
|
@ -293,7 +295,7 @@ pub struct DepKindVTable<'tcx> {
|
||||||
/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
|
/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
|
||||||
/// Fortunately, we can use some contextual information that will allow us to
|
/// Fortunately, we can use some contextual information that will allow us to
|
||||||
/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
|
/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
|
||||||
/// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
|
/// enforce by construction that the key fingerprint of certain `DepNode`s is a
|
||||||
/// valid `DefPathHash`. Since we also always build a huge table that maps every
|
/// valid `DefPathHash`. Since we also always build a huge table that maps every
|
||||||
/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
|
/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
|
||||||
/// everything we need to re-run the query.
|
/// everything we need to re-run the query.
|
||||||
|
|
@ -301,7 +303,7 @@ pub struct DepKindVTable<'tcx> {
|
||||||
/// Take the `mir_promoted` query as an example. Like many other queries, it
|
/// Take the `mir_promoted` query as an example. Like many other queries, it
|
||||||
/// just has a single parameter: the `DefId` of the item it will compute the
|
/// just has a single parameter: the `DefId` of the item it will compute the
|
||||||
/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
|
/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
|
||||||
/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
|
/// with kind `mir_promoted`, we know that the key fingerprint of the `DepNode`
|
||||||
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
|
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
|
||||||
/// `DefId` in `tcx.def_path_hash_to_def_id`.
|
/// `DefId` in `tcx.def_path_hash_to_def_id`.
|
||||||
pub force_from_dep_node: Option<
|
pub force_from_dep_node: Option<
|
||||||
|
|
@ -472,8 +474,8 @@ impl DepNode {
|
||||||
/// refers to something from the previous compilation session that
|
/// refers to something from the previous compilation session that
|
||||||
/// has been removed.
|
/// has been removed.
|
||||||
pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
|
pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
|
||||||
if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
|
if tcx.key_fingerprint_style(self.kind) == KeyFingerprintStyle::DefPathHash {
|
||||||
tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()))
|
tcx.def_path_hash_to_def_id(DefPathHash(self.key_fingerprint.into()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -486,10 +488,10 @@ impl DepNode {
|
||||||
) -> Result<DepNode, ()> {
|
) -> Result<DepNode, ()> {
|
||||||
let kind = dep_kind_from_label_string(label)?;
|
let kind = dep_kind_from_label_string(label)?;
|
||||||
|
|
||||||
match tcx.fingerprint_style(kind) {
|
match tcx.key_fingerprint_style(kind) {
|
||||||
FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()),
|
KeyFingerprintStyle::Opaque | KeyFingerprintStyle::HirId => Err(()),
|
||||||
FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
|
KeyFingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
|
||||||
FingerprintStyle::DefPathHash => {
|
KeyFingerprintStyle::DefPathHash => {
|
||||||
Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind))
|
Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId,
|
||||||
use rustc_hir::definitions::DefPathHash;
|
use rustc_hir::definitions::DefPathHash;
|
||||||
use rustc_hir::{HirId, ItemLocalId, OwnerId};
|
use rustc_hir::{HirId, ItemLocalId, OwnerId};
|
||||||
|
|
||||||
use crate::dep_graph::{DepNode, DepNodeKey, FingerprintStyle};
|
use crate::dep_graph::{DepNode, DepNodeKey, KeyFingerprintStyle};
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for () {
|
impl<'tcx> DepNodeKey<'tcx> for () {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::Unit
|
KeyFingerprintStyle::Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -18,15 +18,15 @@ impl<'tcx> DepNodeKey<'tcx> for () {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for DefId {
|
impl<'tcx> DepNodeKey<'tcx> for DefId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::DefPathHash
|
KeyFingerprintStyle::DefPathHash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -40,15 +40,15 @@ impl<'tcx> DepNodeKey<'tcx> for DefId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
dep_node.extract_def_id(tcx)
|
dep_node.extract_def_id(tcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for LocalDefId {
|
impl<'tcx> DepNodeKey<'tcx> for LocalDefId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::DefPathHash
|
KeyFingerprintStyle::DefPathHash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -62,15 +62,15 @@ impl<'tcx> DepNodeKey<'tcx> for LocalDefId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
dep_node.extract_def_id(tcx).map(|id| id.expect_local())
|
dep_node.extract_def_id(tcx).map(|id| id.expect_local())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for OwnerId {
|
impl<'tcx> DepNodeKey<'tcx> for OwnerId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::DefPathHash
|
KeyFingerprintStyle::DefPathHash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -84,15 +84,15 @@ impl<'tcx> DepNodeKey<'tcx> for OwnerId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
|
dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for CrateNum {
|
impl<'tcx> DepNodeKey<'tcx> for CrateNum {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::DefPathHash
|
KeyFingerprintStyle::DefPathHash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -107,15 +107,15 @@ impl<'tcx> DepNodeKey<'tcx> for CrateNum {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
dep_node.extract_def_id(tcx).map(|id| id.krate)
|
dep_node.extract_def_id(tcx).map(|id| id.krate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for (DefId, DefId) {
|
impl<'tcx> DepNodeKey<'tcx> for (DefId, DefId) {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::Opaque
|
KeyFingerprintStyle::Opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
// We actually would not need to specialize the implementation of this
|
// We actually would not need to specialize the implementation of this
|
||||||
|
|
@ -141,8 +141,8 @@ impl<'tcx> DepNodeKey<'tcx> for (DefId, DefId) {
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for HirId {
|
impl<'tcx> DepNodeKey<'tcx> for HirId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::HirId
|
KeyFingerprintStyle::HirId
|
||||||
}
|
}
|
||||||
|
|
||||||
// We actually would not need to specialize the implementation of this
|
// We actually would not need to specialize the implementation of this
|
||||||
|
|
@ -166,9 +166,9 @@ impl<'tcx> DepNodeKey<'tcx> for HirId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
|
if tcx.key_fingerprint_style(dep_node.kind) == KeyFingerprintStyle::HirId {
|
||||||
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
|
let (local_hash, local_id) = Fingerprint::from(dep_node.key_fingerprint).split();
|
||||||
let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
|
let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
|
||||||
let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
|
let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
|
||||||
let local_id = local_id
|
let local_id = local_id
|
||||||
|
|
@ -184,8 +184,8 @@ impl<'tcx> DepNodeKey<'tcx> for HirId {
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for ModDefId {
|
impl<'tcx> DepNodeKey<'tcx> for ModDefId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::DefPathHash
|
KeyFingerprintStyle::DefPathHash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -199,15 +199,15 @@ impl<'tcx> DepNodeKey<'tcx> for ModDefId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
|
DefId::try_recover_key(tcx, dep_node).map(ModDefId::new_unchecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DepNodeKey<'tcx> for LocalModDefId {
|
impl<'tcx> DepNodeKey<'tcx> for LocalModDefId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fingerprint_style() -> FingerprintStyle {
|
fn key_fingerprint_style() -> KeyFingerprintStyle {
|
||||||
FingerprintStyle::DefPathHash
|
KeyFingerprintStyle::DefPathHash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -221,7 +221,7 @@ impl<'tcx> DepNodeKey<'tcx> for LocalModDefId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn try_recover_key(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
|
LocalDefId::try_recover_key(tcx, dep_node).map(LocalModDefId::new_unchecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,15 +142,17 @@ impl DepGraph {
|
||||||
|
|
||||||
// Instantiate a node with zero dependencies only once for anonymous queries.
|
// Instantiate a node with zero dependencies only once for anonymous queries.
|
||||||
let _green_node_index = current.alloc_new_node(
|
let _green_node_index = current.alloc_new_node(
|
||||||
DepNode { kind: DepKind::ANON_ZERO_DEPS, hash: current.anon_id_seed.into() },
|
DepNode { kind: DepKind::ANON_ZERO_DEPS, key_fingerprint: current.anon_id_seed.into() },
|
||||||
EdgesVec::new(),
|
EdgesVec::new(),
|
||||||
Fingerprint::ZERO,
|
Fingerprint::ZERO,
|
||||||
);
|
);
|
||||||
assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_ZERO_DEPS_ANON_NODE);
|
assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_ZERO_DEPS_ANON_NODE);
|
||||||
|
|
||||||
// Instantiate a dependy-less red node only once for anonymous queries.
|
// Create a single always-red node, with no dependencies of its own.
|
||||||
|
// Other nodes can use the always-red node as a fake dependency, to
|
||||||
|
// ensure that their dependency list will never be all-green.
|
||||||
let red_node_index = current.alloc_new_node(
|
let red_node_index = current.alloc_new_node(
|
||||||
DepNode { kind: DepKind::RED, hash: Fingerprint::ZERO.into() },
|
DepNode { kind: DepKind::RED, key_fingerprint: Fingerprint::ZERO.into() },
|
||||||
EdgesVec::new(),
|
EdgesVec::new(),
|
||||||
Fingerprint::ZERO,
|
Fingerprint::ZERO,
|
||||||
);
|
);
|
||||||
|
|
@ -418,7 +420,7 @@ impl DepGraphData {
|
||||||
// Fingerprint::combine() is faster than sending Fingerprint
|
// Fingerprint::combine() is faster than sending Fingerprint
|
||||||
// through the StableHasher (at least as long as StableHasher
|
// through the StableHasher (at least as long as StableHasher
|
||||||
// is so slow).
|
// is so slow).
|
||||||
hash: self.current.anon_id_seed.combine(hasher.finish()).into(),
|
key_fingerprint: self.current.anon_id_seed.combine(hasher.finish()).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// The DepNodes generated by the process above are not unique. 2 queries could
|
// The DepNodes generated by the process above are not unique. 2 queries could
|
||||||
|
|
@ -585,7 +587,7 @@ impl DepGraph {
|
||||||
data.current.record_edge(
|
data.current.record_edge(
|
||||||
dep_node_index,
|
dep_node_index,
|
||||||
node,
|
node,
|
||||||
data.prev_fingerprint_of(prev_index),
|
data.prev_value_fingerprint_of(prev_index),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -658,8 +660,8 @@ impl DepGraphData {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn prev_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint {
|
pub fn prev_value_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint {
|
||||||
self.previous.fingerprint_by_index(prev_index)
|
self.previous.value_fingerprint_for_index(prev_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -679,7 +681,7 @@ impl DepGraphData {
|
||||||
let dep_node_index = self.current.encoder.send_new(
|
let dep_node_index = self.current.encoder.send_new(
|
||||||
DepNode {
|
DepNode {
|
||||||
kind: DepKind::SIDE_EFFECT,
|
kind: DepKind::SIDE_EFFECT,
|
||||||
hash: PackedFingerprint::from(Fingerprint::ZERO),
|
key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO),
|
||||||
},
|
},
|
||||||
Fingerprint::ZERO,
|
Fingerprint::ZERO,
|
||||||
// We want the side effect node to always be red so it will be forced and emit the
|
// We want the side effect node to always be red so it will be forced and emit the
|
||||||
|
|
@ -712,7 +714,7 @@ impl DepGraphData {
|
||||||
&self.colors,
|
&self.colors,
|
||||||
DepNode {
|
DepNode {
|
||||||
kind: DepKind::SIDE_EFFECT,
|
kind: DepKind::SIDE_EFFECT,
|
||||||
hash: PackedFingerprint::from(Fingerprint::ZERO),
|
key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO),
|
||||||
},
|
},
|
||||||
Fingerprint::ZERO,
|
Fingerprint::ZERO,
|
||||||
std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(),
|
std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(),
|
||||||
|
|
@ -727,12 +729,12 @@ impl DepGraphData {
|
||||||
&self,
|
&self,
|
||||||
key: DepNode,
|
key: DepNode,
|
||||||
edges: EdgesVec,
|
edges: EdgesVec,
|
||||||
fingerprint: Option<Fingerprint>,
|
value_fingerprint: Option<Fingerprint>,
|
||||||
) -> DepNodeIndex {
|
) -> DepNodeIndex {
|
||||||
if let Some(prev_index) = self.previous.node_to_index_opt(&key) {
|
if let Some(prev_index) = self.previous.node_to_index_opt(&key) {
|
||||||
// Determine the color and index of the new `DepNode`.
|
// Determine the color and index of the new `DepNode`.
|
||||||
let is_green = if let Some(fingerprint) = fingerprint {
|
let is_green = if let Some(value_fingerprint) = value_fingerprint {
|
||||||
if fingerprint == self.previous.fingerprint_by_index(prev_index) {
|
if value_fingerprint == self.previous.value_fingerprint_for_index(prev_index) {
|
||||||
// This is a green node: it existed in the previous compilation,
|
// This is a green node: it existed in the previous compilation,
|
||||||
// its query was re-executed, and it has the same result as before.
|
// its query was re-executed, and it has the same result as before.
|
||||||
true
|
true
|
||||||
|
|
@ -749,22 +751,22 @@ impl DepGraphData {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO);
|
let value_fingerprint = value_fingerprint.unwrap_or(Fingerprint::ZERO);
|
||||||
|
|
||||||
let dep_node_index = self.current.encoder.send_and_color(
|
let dep_node_index = self.current.encoder.send_and_color(
|
||||||
prev_index,
|
prev_index,
|
||||||
&self.colors,
|
&self.colors,
|
||||||
key,
|
key,
|
||||||
fingerprint,
|
value_fingerprint,
|
||||||
edges,
|
edges,
|
||||||
is_green,
|
is_green,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.current.record_node(dep_node_index, key, fingerprint);
|
self.current.record_node(dep_node_index, key, value_fingerprint);
|
||||||
|
|
||||||
dep_node_index
|
dep_node_index
|
||||||
} else {
|
} else {
|
||||||
self.current.alloc_new_node(key, edges, fingerprint.unwrap_or(Fingerprint::ZERO))
|
self.current.alloc_new_node(key, edges, value_fingerprint.unwrap_or(Fingerprint::ZERO))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -781,7 +783,7 @@ impl DepGraphData {
|
||||||
self.current.record_edge(
|
self.current.record_edge(
|
||||||
dep_node_index,
|
dep_node_index,
|
||||||
*self.previous.index_to_node(prev_index),
|
*self.previous.index_to_node(prev_index),
|
||||||
self.previous.fingerprint_by_index(prev_index),
|
self.previous.value_fingerprint_for_index(prev_index),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -925,7 +927,7 @@ impl DepGraphData {
|
||||||
if !tcx.is_eval_always(dep_dep_node.kind) {
|
if !tcx.is_eval_always(dep_dep_node.kind) {
|
||||||
debug!(
|
debug!(
|
||||||
"state of dependency {:?} ({}) is unknown, trying to mark it green",
|
"state of dependency {:?} ({}) is unknown, trying to mark it green",
|
||||||
dep_dep_node, dep_dep_node.hash,
|
dep_dep_node, dep_dep_node.key_fingerprint,
|
||||||
);
|
);
|
||||||
|
|
||||||
let node_index = self.try_mark_previous_green(tcx, parent_dep_node_index, Some(frame));
|
let node_index = self.try_mark_previous_green(tcx, parent_dep_node_index, Some(frame));
|
||||||
|
|
@ -1154,10 +1156,10 @@ pub(super) struct CurrentDepGraph {
|
||||||
encoder: GraphEncoder,
|
encoder: GraphEncoder,
|
||||||
anon_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>,
|
anon_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>,
|
||||||
|
|
||||||
/// This is used to verify that fingerprints do not change between the creation of a node
|
/// This is used to verify that value fingerprints do not change between the
|
||||||
/// and its recomputation.
|
/// creation of a node and its recomputation.
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
fingerprints: Lock<IndexVec<DepNodeIndex, Option<Fingerprint>>>,
|
value_fingerprints: Lock<IndexVec<DepNodeIndex, Option<Fingerprint>>>,
|
||||||
|
|
||||||
/// Used to trap when a specific edge is added to the graph.
|
/// Used to trap when a specific edge is added to the graph.
|
||||||
/// This is used for debug purposes and is only active with `debug_assertions`.
|
/// This is used for debug purposes and is only active with `debug_assertions`.
|
||||||
|
|
@ -1224,7 +1226,7 @@ impl CurrentDepGraph {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
forbidden_edge,
|
forbidden_edge,
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)),
|
value_fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)),
|
||||||
nodes_in_current_session: new_node_dbg.then(|| {
|
nodes_in_current_session: new_node_dbg.then(|| {
|
||||||
Lock::new(FxHashMap::with_capacity_and_hasher(
|
Lock::new(FxHashMap::with_capacity_and_hasher(
|
||||||
new_node_count_estimate,
|
new_node_count_estimate,
|
||||||
|
|
@ -1237,12 +1239,20 @@ impl CurrentDepGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
fn record_edge(&self, dep_node_index: DepNodeIndex, key: DepNode, fingerprint: Fingerprint) {
|
fn record_edge(
|
||||||
|
&self,
|
||||||
|
dep_node_index: DepNodeIndex,
|
||||||
|
key: DepNode,
|
||||||
|
value_fingerprint: Fingerprint,
|
||||||
|
) {
|
||||||
if let Some(forbidden_edge) = &self.forbidden_edge {
|
if let Some(forbidden_edge) = &self.forbidden_edge {
|
||||||
forbidden_edge.index_to_node.lock().insert(dep_node_index, key);
|
forbidden_edge.index_to_node.lock().insert(dep_node_index, key);
|
||||||
}
|
}
|
||||||
let previous = *self.fingerprints.lock().get_or_insert_with(dep_node_index, || fingerprint);
|
let prior_value_fingerprint = *self
|
||||||
assert_eq!(previous, fingerprint, "Unstable fingerprints for {:?}", key);
|
.value_fingerprints
|
||||||
|
.lock()
|
||||||
|
.get_or_insert_with(dep_node_index, || value_fingerprint);
|
||||||
|
assert_eq!(prior_value_fingerprint, value_fingerprint, "Unstable fingerprints for {key:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -1250,10 +1260,10 @@ impl CurrentDepGraph {
|
||||||
&self,
|
&self,
|
||||||
dep_node_index: DepNodeIndex,
|
dep_node_index: DepNodeIndex,
|
||||||
key: DepNode,
|
key: DepNode,
|
||||||
_current_fingerprint: Fingerprint,
|
_value_fingerprint: Fingerprint,
|
||||||
) {
|
) {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
self.record_edge(dep_node_index, key, _current_fingerprint);
|
self.record_edge(dep_node_index, key, _value_fingerprint);
|
||||||
|
|
||||||
if let Some(ref nodes_in_current_session) = self.nodes_in_current_session {
|
if let Some(ref nodes_in_current_session) = self.nodes_in_current_session {
|
||||||
outline(|| {
|
outline(|| {
|
||||||
|
|
@ -1271,11 +1281,11 @@ impl CurrentDepGraph {
|
||||||
&self,
|
&self,
|
||||||
key: DepNode,
|
key: DepNode,
|
||||||
edges: EdgesVec,
|
edges: EdgesVec,
|
||||||
current_fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
) -> DepNodeIndex {
|
) -> DepNodeIndex {
|
||||||
let dep_node_index = self.encoder.send_new(key, current_fingerprint, edges);
|
let dep_node_index = self.encoder.send_new(key, value_fingerprint, edges);
|
||||||
|
|
||||||
self.record_node(dep_node_index, key, current_fingerprint);
|
self.record_node(dep_node_index, key, value_fingerprint);
|
||||||
|
|
||||||
dep_node_index
|
dep_node_index
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ mod serialized;
|
||||||
/// This is mainly for determining whether and how we can reconstruct a key
|
/// This is mainly for determining whether and how we can reconstruct a key
|
||||||
/// from the fingerprint.
|
/// from the fingerprint.
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum FingerprintStyle {
|
pub enum KeyFingerprintStyle {
|
||||||
/// The fingerprint is actually a DefPathHash.
|
/// The fingerprint is actually a DefPathHash.
|
||||||
DefPathHash,
|
DefPathHash,
|
||||||
/// The fingerprint is actually a HirId.
|
/// The fingerprint is actually a HirId.
|
||||||
|
|
@ -41,14 +41,14 @@ pub enum FingerprintStyle {
|
||||||
Opaque,
|
Opaque,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FingerprintStyle {
|
impl KeyFingerprintStyle {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn reconstructible(self) -> bool {
|
pub const fn reconstructible(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => {
|
KeyFingerprintStyle::DefPathHash
|
||||||
true
|
| KeyFingerprintStyle::Unit
|
||||||
}
|
| KeyFingerprintStyle::HirId => true,
|
||||||
FingerprintStyle::Opaque => false,
|
KeyFingerprintStyle::Opaque => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,8 +86,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn fingerprint_style(self, kind: DepKind) -> FingerprintStyle {
|
pub fn key_fingerprint_style(self, kind: DepKind) -> KeyFingerprintStyle {
|
||||||
self.dep_kind_vtable(kind).fingerprint_style
|
self.dep_kind_vtable(kind).key_fingerprint_style
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to force a dep node to execute and see if it's green.
|
/// Try to force a dep node to execute and see if it's green.
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,13 @@ const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2;
|
||||||
pub struct SerializedDepGraph {
|
pub struct SerializedDepGraph {
|
||||||
/// The set of all DepNodes in the graph
|
/// The set of all DepNodes in the graph
|
||||||
nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
|
nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
|
||||||
/// The set of all Fingerprints in the graph. Each Fingerprint corresponds to
|
/// A value fingerprint associated with each [`DepNode`] in [`Self::nodes`],
|
||||||
/// the DepNode at the same index in the nodes vector.
|
/// typically a hash of the value returned by the node's query in the
|
||||||
fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
|
/// previous incremental-compilation session.
|
||||||
|
///
|
||||||
|
/// Some nodes don't have a meaningful value hash (e.g. queries with `no_hash`),
|
||||||
|
/// so they store a dummy value here instead (e.g. [`Fingerprint::ZERO`]).
|
||||||
|
value_fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
|
||||||
/// For each DepNode, stores the list of edges originating from that
|
/// For each DepNode, stores the list of edges originating from that
|
||||||
/// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
|
/// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
|
||||||
/// which holds the actual DepNodeIndices of the target nodes.
|
/// which holds the actual DepNodeIndices of the target nodes.
|
||||||
|
|
@ -100,8 +104,8 @@ pub struct SerializedDepGraph {
|
||||||
/// A flattened list of all edge targets in the graph, stored in the same
|
/// A flattened list of all edge targets in the graph, stored in the same
|
||||||
/// varint encoding that we use on disk. Edge sources are implicit in edge_list_indices.
|
/// varint encoding that we use on disk. Edge sources are implicit in edge_list_indices.
|
||||||
edge_list_data: Vec<u8>,
|
edge_list_data: Vec<u8>,
|
||||||
/// Stores a map from fingerprints to nodes per dep node kind.
|
/// For each dep kind, stores a map from key fingerprints back to the index
|
||||||
/// This is the reciprocal of `nodes`.
|
/// of the corresponding node. This is the inverse of `nodes`.
|
||||||
index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
|
index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
|
||||||
/// The number of previous compilation sessions. This is used to generate
|
/// The number of previous compilation sessions. This is used to generate
|
||||||
/// unique anon dep nodes per session.
|
/// unique anon dep nodes per session.
|
||||||
|
|
@ -138,12 +142,15 @@ impl SerializedDepGraph {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
|
pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
|
||||||
self.index.get(dep_node.kind.as_usize())?.get(&dep_node.hash).cloned()
|
self.index.get(dep_node.kind.as_usize())?.get(&dep_node.key_fingerprint).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint {
|
pub fn value_fingerprint_for_index(
|
||||||
self.fingerprints[dep_node_index]
|
&self,
|
||||||
|
dep_node_index: SerializedDepNodeIndex,
|
||||||
|
) -> Fingerprint {
|
||||||
|
self.value_fingerprints[dep_node_index]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -212,10 +219,13 @@ impl SerializedDepGraph {
|
||||||
let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
|
let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
|
||||||
|
|
||||||
let mut nodes = IndexVec::from_elem_n(
|
let mut nodes = IndexVec::from_elem_n(
|
||||||
DepNode { kind: DepKind::NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
|
DepNode {
|
||||||
|
kind: DepKind::NULL,
|
||||||
|
key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO),
|
||||||
|
},
|
||||||
node_max,
|
node_max,
|
||||||
);
|
);
|
||||||
let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max);
|
let mut value_fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max);
|
||||||
let mut edge_list_indices =
|
let mut edge_list_indices =
|
||||||
IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max);
|
IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max);
|
||||||
|
|
||||||
|
|
@ -243,7 +253,7 @@ impl SerializedDepGraph {
|
||||||
assert!(node_header.node().kind != DepKind::NULL && node.kind == DepKind::NULL);
|
assert!(node_header.node().kind != DepKind::NULL && node.kind == DepKind::NULL);
|
||||||
*node = node_header.node();
|
*node = node_header.node();
|
||||||
|
|
||||||
fingerprints[index] = node_header.fingerprint();
|
value_fingerprints[index] = node_header.value_fingerprint();
|
||||||
|
|
||||||
// If the length of this node's edge list is small, the length is stored in the header.
|
// If the length of this node's edge list is small, the length is stored in the header.
|
||||||
// If it is not, we fall back to another decoder call.
|
// If it is not, we fall back to another decoder call.
|
||||||
|
|
@ -275,7 +285,7 @@ impl SerializedDepGraph {
|
||||||
let session_count = d.read_u64();
|
let session_count = d.read_u64();
|
||||||
|
|
||||||
for (idx, node) in nodes.iter_enumerated() {
|
for (idx, node) in nodes.iter_enumerated() {
|
||||||
if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
|
if index[node.kind.as_usize()].insert(node.key_fingerprint, idx).is_some() {
|
||||||
// Empty nodes and side effect nodes can have duplicates
|
// Empty nodes and side effect nodes can have duplicates
|
||||||
if node.kind != DepKind::NULL && node.kind != DepKind::SIDE_EFFECT {
|
if node.kind != DepKind::NULL && node.kind != DepKind::SIDE_EFFECT {
|
||||||
let name = node.kind.name();
|
let name = node.kind.name();
|
||||||
|
|
@ -291,7 +301,7 @@ impl SerializedDepGraph {
|
||||||
|
|
||||||
Arc::new(SerializedDepGraph {
|
Arc::new(SerializedDepGraph {
|
||||||
nodes,
|
nodes,
|
||||||
fingerprints,
|
value_fingerprints,
|
||||||
edge_list_indices,
|
edge_list_indices,
|
||||||
edge_list_data,
|
edge_list_data,
|
||||||
index,
|
index,
|
||||||
|
|
@ -303,8 +313,8 @@ impl SerializedDepGraph {
|
||||||
/// A packed representation of all the fixed-size fields in a `NodeInfo`.
|
/// A packed representation of all the fixed-size fields in a `NodeInfo`.
|
||||||
///
|
///
|
||||||
/// This stores in one byte array:
|
/// This stores in one byte array:
|
||||||
/// * The `Fingerprint` in the `NodeInfo`
|
/// * The value `Fingerprint` in the `NodeInfo`
|
||||||
/// * The `Fingerprint` in `DepNode` that is in this `NodeInfo`
|
/// * The key `Fingerprint` in `DepNode` that is in this `NodeInfo`
|
||||||
/// * The `DepKind`'s discriminant (a u16, but not all bits are used...)
|
/// * The `DepKind`'s discriminant (a u16, but not all bits are used...)
|
||||||
/// * The byte width of the encoded edges for this node
|
/// * The byte width of the encoded edges for this node
|
||||||
/// * In whatever bits remain, the length of the edge list for this node, if it fits
|
/// * In whatever bits remain, the length of the edge list for this node, if it fits
|
||||||
|
|
@ -323,8 +333,8 @@ struct Unpacked {
|
||||||
bytes_per_index: usize,
|
bytes_per_index: usize,
|
||||||
kind: DepKind,
|
kind: DepKind,
|
||||||
index: SerializedDepNodeIndex,
|
index: SerializedDepNodeIndex,
|
||||||
hash: PackedFingerprint,
|
key_fingerprint: PackedFingerprint,
|
||||||
fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bit fields, where
|
// Bit fields, where
|
||||||
|
|
@ -345,7 +355,7 @@ impl SerializedNodeHeader {
|
||||||
fn new(
|
fn new(
|
||||||
node: &DepNode,
|
node: &DepNode,
|
||||||
index: DepNodeIndex,
|
index: DepNodeIndex,
|
||||||
fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
edge_max_index: u32,
|
edge_max_index: u32,
|
||||||
edge_count: usize,
|
edge_count: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -363,19 +373,19 @@ impl SerializedNodeHeader {
|
||||||
head |= (edge_count as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
|
head |= (edge_count as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash: Fingerprint = node.hash.into();
|
let hash: Fingerprint = node.key_fingerprint.into();
|
||||||
|
|
||||||
// Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong.
|
// Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong.
|
||||||
let mut bytes = [0u8; 38];
|
let mut bytes = [0u8; 38];
|
||||||
bytes[..2].copy_from_slice(&head.to_le_bytes());
|
bytes[..2].copy_from_slice(&head.to_le_bytes());
|
||||||
bytes[2..6].copy_from_slice(&index.as_u32().to_le_bytes());
|
bytes[2..6].copy_from_slice(&index.as_u32().to_le_bytes());
|
||||||
bytes[6..22].copy_from_slice(&hash.to_le_bytes());
|
bytes[6..22].copy_from_slice(&hash.to_le_bytes());
|
||||||
bytes[22..].copy_from_slice(&fingerprint.to_le_bytes());
|
bytes[22..].copy_from_slice(&value_fingerprint.to_le_bytes());
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let res = Self { bytes };
|
let res = Self { bytes };
|
||||||
assert_eq!(fingerprint, res.fingerprint());
|
assert_eq!(value_fingerprint, res.value_fingerprint());
|
||||||
assert_eq!(*node, res.node());
|
assert_eq!(*node, res.node());
|
||||||
if let Some(len) = res.len() {
|
if let Some(len) = res.len() {
|
||||||
assert_eq!(edge_count, len as usize);
|
assert_eq!(edge_count, len as usize);
|
||||||
|
|
@ -388,8 +398,8 @@ impl SerializedNodeHeader {
|
||||||
fn unpack(&self) -> Unpacked {
|
fn unpack(&self) -> Unpacked {
|
||||||
let head = u16::from_le_bytes(self.bytes[..2].try_into().unwrap());
|
let head = u16::from_le_bytes(self.bytes[..2].try_into().unwrap());
|
||||||
let index = u32::from_le_bytes(self.bytes[2..6].try_into().unwrap());
|
let index = u32::from_le_bytes(self.bytes[2..6].try_into().unwrap());
|
||||||
let hash = self.bytes[6..22].try_into().unwrap();
|
let key_fingerprint = self.bytes[6..22].try_into().unwrap();
|
||||||
let fingerprint = self.bytes[22..].try_into().unwrap();
|
let value_fingerprint = self.bytes[22..].try_into().unwrap();
|
||||||
|
|
||||||
let kind = head & mask(Self::KIND_BITS) as u16;
|
let kind = head & mask(Self::KIND_BITS) as u16;
|
||||||
let bytes_per_index = (head >> Self::KIND_BITS) & mask(Self::WIDTH_BITS) as u16;
|
let bytes_per_index = (head >> Self::KIND_BITS) & mask(Self::WIDTH_BITS) as u16;
|
||||||
|
|
@ -400,8 +410,8 @@ impl SerializedNodeHeader {
|
||||||
bytes_per_index: bytes_per_index as usize + 1,
|
bytes_per_index: bytes_per_index as usize + 1,
|
||||||
kind: DepKind::new(kind),
|
kind: DepKind::new(kind),
|
||||||
index: SerializedDepNodeIndex::from_u32(index),
|
index: SerializedDepNodeIndex::from_u32(index),
|
||||||
hash: Fingerprint::from_le_bytes(hash).into(),
|
key_fingerprint: Fingerprint::from_le_bytes(key_fingerprint).into(),
|
||||||
fingerprint: Fingerprint::from_le_bytes(fingerprint),
|
value_fingerprint: Fingerprint::from_le_bytes(value_fingerprint),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -421,14 +431,14 @@ impl SerializedNodeHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fingerprint(&self) -> Fingerprint {
|
fn value_fingerprint(&self) -> Fingerprint {
|
||||||
self.unpack().fingerprint
|
self.unpack().value_fingerprint
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn node(&self) -> DepNode {
|
fn node(&self) -> DepNode {
|
||||||
let Unpacked { kind, hash, .. } = self.unpack();
|
let Unpacked { kind, key_fingerprint, .. } = self.unpack();
|
||||||
DepNode { kind, hash }
|
DepNode { kind, key_fingerprint }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -443,15 +453,20 @@ impl SerializedNodeHeader {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct NodeInfo {
|
struct NodeInfo {
|
||||||
node: DepNode,
|
node: DepNode,
|
||||||
fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
edges: EdgesVec,
|
edges: EdgesVec,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeInfo {
|
impl NodeInfo {
|
||||||
fn encode(&self, e: &mut MemEncoder, index: DepNodeIndex) {
|
fn encode(&self, e: &mut MemEncoder, index: DepNodeIndex) {
|
||||||
let NodeInfo { ref node, fingerprint, ref edges } = *self;
|
let NodeInfo { ref node, value_fingerprint, ref edges } = *self;
|
||||||
let header =
|
let header = SerializedNodeHeader::new(
|
||||||
SerializedNodeHeader::new(node, index, fingerprint, edges.max_index(), edges.len());
|
node,
|
||||||
|
index,
|
||||||
|
value_fingerprint,
|
||||||
|
edges.max_index(),
|
||||||
|
edges.len(),
|
||||||
|
);
|
||||||
e.write_array(header.bytes);
|
e.write_array(header.bytes);
|
||||||
|
|
||||||
if header.len().is_none() {
|
if header.len().is_none() {
|
||||||
|
|
@ -476,7 +491,7 @@ impl NodeInfo {
|
||||||
e: &mut MemEncoder,
|
e: &mut MemEncoder,
|
||||||
node: &DepNode,
|
node: &DepNode,
|
||||||
index: DepNodeIndex,
|
index: DepNodeIndex,
|
||||||
fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
prev_index: SerializedDepNodeIndex,
|
prev_index: SerializedDepNodeIndex,
|
||||||
colors: &DepNodeColorMap,
|
colors: &DepNodeColorMap,
|
||||||
previous: &SerializedDepGraph,
|
previous: &SerializedDepGraph,
|
||||||
|
|
@ -488,7 +503,8 @@ impl NodeInfo {
|
||||||
let edge_max =
|
let edge_max =
|
||||||
edges.clone().map(|i| colors.current(i).unwrap().as_u32()).max().unwrap_or(0);
|
edges.clone().map(|i| colors.current(i).unwrap().as_u32()).max().unwrap_or(0);
|
||||||
|
|
||||||
let header = SerializedNodeHeader::new(node, index, fingerprint, edge_max, edge_count);
|
let header =
|
||||||
|
SerializedNodeHeader::new(node, index, value_fingerprint, edge_max, edge_count);
|
||||||
e.write_array(header.bytes);
|
e.write_array(header.bytes);
|
||||||
|
|
||||||
if header.len().is_none() {
|
if header.len().is_none() {
|
||||||
|
|
@ -676,12 +692,12 @@ impl EncoderState {
|
||||||
local: &mut LocalEncoderState,
|
local: &mut LocalEncoderState,
|
||||||
) {
|
) {
|
||||||
let node = self.previous.index_to_node(prev_index);
|
let node = self.previous.index_to_node(prev_index);
|
||||||
let fingerprint = self.previous.fingerprint_by_index(prev_index);
|
let value_fingerprint = self.previous.value_fingerprint_for_index(prev_index);
|
||||||
let edge_count = NodeInfo::encode_promoted(
|
let edge_count = NodeInfo::encode_promoted(
|
||||||
&mut local.encoder,
|
&mut local.encoder,
|
||||||
node,
|
node,
|
||||||
index,
|
index,
|
||||||
fingerprint,
|
value_fingerprint,
|
||||||
prev_index,
|
prev_index,
|
||||||
colors,
|
colors,
|
||||||
&self.previous,
|
&self.previous,
|
||||||
|
|
@ -857,11 +873,11 @@ impl GraphEncoder {
|
||||||
pub(crate) fn send_new(
|
pub(crate) fn send_new(
|
||||||
&self,
|
&self,
|
||||||
node: DepNode,
|
node: DepNode,
|
||||||
fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
edges: EdgesVec,
|
edges: EdgesVec,
|
||||||
) -> DepNodeIndex {
|
) -> DepNodeIndex {
|
||||||
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
|
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
|
||||||
let node = NodeInfo { node, fingerprint, edges };
|
let node = NodeInfo { node, value_fingerprint, edges };
|
||||||
let mut local = self.status.local.borrow_mut();
|
let mut local = self.status.local.borrow_mut();
|
||||||
let index = self.status.next_index(&mut *local);
|
let index = self.status.next_index(&mut *local);
|
||||||
self.status.bump_index(&mut *local);
|
self.status.bump_index(&mut *local);
|
||||||
|
|
@ -877,12 +893,12 @@ impl GraphEncoder {
|
||||||
prev_index: SerializedDepNodeIndex,
|
prev_index: SerializedDepNodeIndex,
|
||||||
colors: &DepNodeColorMap,
|
colors: &DepNodeColorMap,
|
||||||
node: DepNode,
|
node: DepNode,
|
||||||
fingerprint: Fingerprint,
|
value_fingerprint: Fingerprint,
|
||||||
edges: EdgesVec,
|
edges: EdgesVec,
|
||||||
is_green: bool,
|
is_green: bool,
|
||||||
) -> DepNodeIndex {
|
) -> DepNodeIndex {
|
||||||
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
|
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
|
||||||
let node = NodeInfo { node, fingerprint, edges };
|
let node = NodeInfo { node, value_fingerprint, edges };
|
||||||
|
|
||||||
let mut local = self.status.local.borrow_mut();
|
let mut local = self.status.local.borrow_mut();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn complete(&self, key: K, value: V, index: DepNodeIndex) {
|
fn complete(&self, key: K, value: V, index: DepNodeIndex) {
|
||||||
// We may be overwriting another value. This is all right, since the dep-graph
|
// We may be overwriting another value. This is all right, since the dep-graph
|
||||||
// will check that the fingerprint matches.
|
// will check that the value fingerprint matches.
|
||||||
self.cache.insert(key, (value, index));
|
self.cache.insert(key, (value, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ pub fn incremental_verify_ich<'tcx, V>(
|
||||||
tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result))
|
tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result))
|
||||||
});
|
});
|
||||||
|
|
||||||
let old_hash = dep_graph_data.prev_fingerprint_of(prev_index);
|
let old_hash = dep_graph_data.prev_value_fingerprint_of(prev_index);
|
||||||
|
|
||||||
if new_hash != old_hash {
|
if new_hash != old_hash {
|
||||||
incremental_verify_ich_failed(tcx, prev_index, &|| format_value(result));
|
incremental_verify_ich_failed(tcx, prev_index, &|| format_value(result));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, FingerprintStyle};
|
use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, KeyFingerprintStyle};
|
||||||
use rustc_middle::query::QueryCache;
|
use rustc_middle::query::QueryCache;
|
||||||
|
|
||||||
use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner};
|
use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner};
|
||||||
|
|
@ -15,7 +15,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: false,
|
is_anon: false,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Unit,
|
key_fingerprint_style: KeyFingerprintStyle::Unit,
|
||||||
force_from_dep_node: Some(|_, dep_node, _| {
|
force_from_dep_node: Some(|_, dep_node, _| {
|
||||||
bug!("force_from_dep_node: encountered {dep_node:?}")
|
bug!("force_from_dep_node: encountered {dep_node:?}")
|
||||||
}),
|
}),
|
||||||
|
|
@ -29,7 +29,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: false,
|
is_anon: false,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Unit,
|
key_fingerprint_style: KeyFingerprintStyle::Unit,
|
||||||
force_from_dep_node: Some(|_, dep_node, _| {
|
force_from_dep_node: Some(|_, dep_node, _| {
|
||||||
bug!("force_from_dep_node: encountered {dep_node:?}")
|
bug!("force_from_dep_node: encountered {dep_node:?}")
|
||||||
}),
|
}),
|
||||||
|
|
@ -42,7 +42,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: false,
|
is_anon: false,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Unit,
|
key_fingerprint_style: KeyFingerprintStyle::Unit,
|
||||||
force_from_dep_node: Some(|tcx, _, prev_index| {
|
force_from_dep_node: Some(|tcx, _, prev_index| {
|
||||||
tcx.dep_graph.force_diagnostic_node(tcx, prev_index);
|
tcx.dep_graph.force_diagnostic_node(tcx, prev_index);
|
||||||
true
|
true
|
||||||
|
|
@ -56,7 +56,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: true,
|
is_anon: true,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Opaque,
|
key_fingerprint_style: KeyFingerprintStyle::Opaque,
|
||||||
force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")),
|
force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")),
|
||||||
try_load_from_on_disk_cache: None,
|
try_load_from_on_disk_cache: None,
|
||||||
name: &"AnonZeroDeps",
|
name: &"AnonZeroDeps",
|
||||||
|
|
@ -67,7 +67,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: true,
|
is_anon: true,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Unit,
|
key_fingerprint_style: KeyFingerprintStyle::Unit,
|
||||||
force_from_dep_node: None,
|
force_from_dep_node: None,
|
||||||
try_load_from_on_disk_cache: None,
|
try_load_from_on_disk_cache: None,
|
||||||
name: &"TraitSelect",
|
name: &"TraitSelect",
|
||||||
|
|
@ -78,7 +78,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: false,
|
is_anon: false,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Opaque,
|
key_fingerprint_style: KeyFingerprintStyle::Opaque,
|
||||||
force_from_dep_node: None,
|
force_from_dep_node: None,
|
||||||
try_load_from_on_disk_cache: None,
|
try_load_from_on_disk_cache: None,
|
||||||
name: &"CompileCodegenUnit",
|
name: &"CompileCodegenUnit",
|
||||||
|
|
@ -89,7 +89,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: false,
|
is_anon: false,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Opaque,
|
key_fingerprint_style: KeyFingerprintStyle::Opaque,
|
||||||
force_from_dep_node: None,
|
force_from_dep_node: None,
|
||||||
try_load_from_on_disk_cache: None,
|
try_load_from_on_disk_cache: None,
|
||||||
name: &"CompileMonoItem",
|
name: &"CompileMonoItem",
|
||||||
|
|
@ -100,7 +100,7 @@ mod non_query {
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon: false,
|
is_anon: false,
|
||||||
is_eval_always: false,
|
is_eval_always: false,
|
||||||
fingerprint_style: FingerprintStyle::Unit,
|
key_fingerprint_style: KeyFingerprintStyle::Unit,
|
||||||
force_from_dep_node: None,
|
force_from_dep_node: None,
|
||||||
try_load_from_on_disk_cache: None,
|
try_load_from_on_disk_cache: None,
|
||||||
name: &"Metadata",
|
name: &"Metadata",
|
||||||
|
|
@ -118,17 +118,17 @@ where
|
||||||
Cache: QueryCache + 'tcx,
|
Cache: QueryCache + 'tcx,
|
||||||
{
|
{
|
||||||
let is_anon = FLAGS.is_anon;
|
let is_anon = FLAGS.is_anon;
|
||||||
let fingerprint_style = if is_anon {
|
let key_fingerprint_style = if is_anon {
|
||||||
FingerprintStyle::Opaque
|
KeyFingerprintStyle::Opaque
|
||||||
} else {
|
} else {
|
||||||
<Cache::Key as DepNodeKey<'tcx>>::fingerprint_style()
|
<Cache::Key as DepNodeKey<'tcx>>::key_fingerprint_style()
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_anon || !fingerprint_style.reconstructible() {
|
if is_anon || !key_fingerprint_style.reconstructible() {
|
||||||
return DepKindVTable {
|
return DepKindVTable {
|
||||||
is_anon,
|
is_anon,
|
||||||
is_eval_always,
|
is_eval_always,
|
||||||
fingerprint_style,
|
key_fingerprint_style,
|
||||||
force_from_dep_node: None,
|
force_from_dep_node: None,
|
||||||
try_load_from_on_disk_cache: None,
|
try_load_from_on_disk_cache: None,
|
||||||
name: Q::NAME,
|
name: Q::NAME,
|
||||||
|
|
@ -138,7 +138,7 @@ where
|
||||||
DepKindVTable {
|
DepKindVTable {
|
||||||
is_anon,
|
is_anon,
|
||||||
is_eval_always,
|
is_eval_always,
|
||||||
fingerprint_style,
|
key_fingerprint_style,
|
||||||
force_from_dep_node: Some(|tcx, dep_node, _| {
|
force_from_dep_node: Some(|tcx, dep_node, _| {
|
||||||
force_from_dep_node_inner(Q::query_dispatcher(tcx), tcx, dep_node)
|
force_from_dep_node_inner(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer
|
||||||
dep_graph_data.mark_debug_loaded_from_disk(*dep_node)
|
dep_graph_data.mark_debug_loaded_from_disk(*dep_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index);
|
let prev_fingerprint = dep_graph_data.prev_value_fingerprint_of(prev_dep_node_index);
|
||||||
// If `-Zincremental-verify-ich` is specified, re-hash results from
|
// If `-Zincremental-verify-ich` is specified, re-hash results from
|
||||||
// the cache and make sure that they have the expected fingerprint.
|
// the cache and make sure that they have the expected fingerprint.
|
||||||
//
|
//
|
||||||
|
|
@ -538,7 +538,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer
|
||||||
// can be forced from `DepNode`.
|
// can be forced from `DepNode`.
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
!query.will_cache_on_disk_for_key(tcx, key)
|
!query.will_cache_on_disk_for_key(tcx, key)
|
||||||
|| !tcx.fingerprint_style(dep_node.kind).reconstructible(),
|
|| !tcx.key_fingerprint_style(dep_node.kind).reconstructible(),
|
||||||
"missing on-disk cache entry for {dep_node:?}"
|
"missing on-disk cache entry for {dep_node:?}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -396,8 +396,11 @@ pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache, const FLAGS
|
||||||
) {
|
) {
|
||||||
debug_assert!(tcx.dep_graph.is_green(&dep_node));
|
debug_assert!(tcx.dep_graph.is_green(&dep_node));
|
||||||
|
|
||||||
let key = C::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
|
let key = C::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| {
|
||||||
panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
|
panic!(
|
||||||
|
"Failed to recover key for {dep_node:?} with key fingerprint {}",
|
||||||
|
dep_node.key_fingerprint
|
||||||
|
)
|
||||||
});
|
});
|
||||||
if query.will_cache_on_disk_for_key(tcx, &key) {
|
if query.will_cache_on_disk_for_key(tcx, &key) {
|
||||||
// Call `tcx.$query(key)` for its side-effect of loading the disk-cached
|
// Call `tcx.$query(key)` for its side-effect of loading the disk-cached
|
||||||
|
|
@ -462,7 +465,7 @@ pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache, const FLAGS: QueryF
|
||||||
"calling force_from_dep_node() on dep_kinds::codegen_unit"
|
"calling force_from_dep_node() on dep_kinds::codegen_unit"
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(key) = C::Key::recover(tcx, &dep_node) {
|
if let Some(key) = C::Key::try_recover_key(tcx, &dep_node) {
|
||||||
force_query(query, tcx, key, dep_node);
|
force_query(query, tcx, key, dep_node);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ unstalled = "unstalled" # short for un-stalled
|
||||||
#
|
#
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
definitinon = "definition"
|
definitinon = "definition"
|
||||||
|
dependy = ""
|
||||||
similarlty = "similarity"
|
similarlty = "similarity"
|
||||||
# tidy-alphabetical-end
|
# tidy-alphabetical-end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue