From 93a0fb190e9a781a36f9ab2faf02f2e3dc303234 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 11 Sep 2022 21:10:53 -0500 Subject: [PATCH] Move `DepKindStruct` from rustc_middle to rustc_query_system --- .../rustc_middle/src/dep_graph/dep_node.rs | 61 ------------------- compiler/rustc_middle/src/dep_graph/mod.rs | 4 +- .../src/dep_graph/dep_node.rs | 61 +++++++++++++++++++ .../rustc_query_system/src/dep_graph/mod.rs | 2 +- 4 files changed, 65 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index ac106764c02..32dacc25dcb 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -69,67 +69,6 @@ use std::hash::Hash; pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams}; -/// This struct stores metadata about each DepKind. -/// -/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value -/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual -/// jump table instead of large matches. -pub struct DepKindStruct<'tcx> { - /// Anonymous queries cannot be replayed from one compiler invocation to the next. - /// When their result is needed, it is recomputed. They are useful for fine-grained - /// dependency tracking, and caching within one compiler invocation. - pub is_anon: bool, - - /// Eval-always queries do not track their dependencies, and are always recomputed, even if - /// their inputs have not changed since the last compiler invocation. The result is still - /// cached within one compiler invocation. - pub is_eval_always: bool, - - /// Whether the query key can be recovered from the hashed fingerprint. - /// See [DepNodeParams] trait for the behaviour of each key type. - pub fingerprint_style: FingerprintStyle, - - /// 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 - /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` - /// where we don't know if it is red or green and we therefore actually have - /// to recompute its value in order to find out. Since the only piece of - /// information that we have at that point is the `DepNode` we are trying to - /// re-evaluate, we need some way to re-run a query from just that. This is what - /// `force_from_dep_node()` implements. - /// - /// In the general case, a `DepNode` consists of a `DepKind` and an opaque - /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint - /// 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 - /// back from hash to query-key (since hash functions are not reversible). For - /// this reason `force_from_dep_node()` is expected to fail from time to time - /// because we just cannot find out, from the `DepNode` alone, what the - /// corresponding query-key is and therefore cannot re-run the query. - /// - /// The system deals with this case letting `try_mark_green` fail which forces - /// the root query to be re-evaluated. - /// - /// 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 - /// 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 - /// valid `DefPathHash`. Since we also always build a huge table that maps every - /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have - /// everything we need to re-run the query. - /// - /// 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 - /// 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` - /// is actually a `DefPathHash`, and can therefore just look up the corresponding - /// `DefId` in `tcx.def_path_hash_to_def_id`. - pub force_from_dep_node: Option, dep_node: DepNode) -> bool>, - - /// Invoke a query to put the on-disk cached value in memory. - pub try_load_from_on_disk_cache: Option, DepNode)>, -} - impl DepKind { #[inline(always)] pub fn fingerprint_style(self, tcx: TyCtxt<'_>) -> FingerprintStyle { diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index c8b3b52b0fb..0e9955e2972 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -11,15 +11,17 @@ pub use rustc_query_system::dep_graph::{ SerializedDepNodeIndex, WorkProduct, WorkProductId, }; -pub use dep_node::{label_strs, DepKind, DepKindStruct, DepNode, DepNodeExt}; +pub use dep_node::{label_strs, DepKind, DepNode, DepNodeExt}; pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item}; pub type DepGraph = rustc_query_system::dep_graph::DepGraph; + pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps; pub type TaskDepsRef<'a> = rustc_query_system::dep_graph::TaskDepsRef<'a, DepKind>; pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery; pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph; pub type EdgeFilter = rustc_query_system::dep_graph::debug::EdgeFilter; +pub type DepKindStruct<'tcx> = rustc_query_system::dep_graph::DepKindStruct>; impl rustc_query_system::dep_graph::DepKind for DepKind { const NULL: Self = DepKind::Null; diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 162c274d8a2..2a3657780ec 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -149,6 +149,67 @@ where } } +/// This struct stores metadata about each DepKind. +/// +/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value +/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual +/// jump table instead of large matches. +pub struct DepKindStruct { + /// Anonymous queries cannot be replayed from one compiler invocation to the next. + /// When their result is needed, it is recomputed. They are useful for fine-grained + /// dependency tracking, and caching within one compiler invocation. + pub is_anon: bool, + + /// Eval-always queries do not track their dependencies, and are always recomputed, even if + /// their inputs have not changed since the last compiler invocation. The result is still + /// cached within one compiler invocation. + pub is_eval_always: bool, + + /// Whether the query key can be recovered from the hashed fingerprint. + /// See [DepNodeParams] trait for the behaviour of each key type. + pub fingerprint_style: FingerprintStyle, + + /// 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 + /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` + /// where we don't know if it is red or green and we therefore actually have + /// to recompute its value in order to find out. Since the only piece of + /// information that we have at that point is the `DepNode` we are trying to + /// re-evaluate, we need some way to re-run a query from just that. This is what + /// `force_from_dep_node()` implements. + /// + /// In the general case, a `DepNode` consists of a `DepKind` and an opaque + /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint + /// 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 + /// back from hash to query-key (since hash functions are not reversible). For + /// this reason `force_from_dep_node()` is expected to fail from time to time + /// because we just cannot find out, from the `DepNode` alone, what the + /// corresponding query-key is and therefore cannot re-run the query. + /// + /// The system deals with this case letting `try_mark_green` fail which forces + /// the root query to be re-evaluated. + /// + /// 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 + /// 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 + /// valid `DefPathHash`. Since we also always build a huge table that maps every + /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have + /// everything we need to re-run the query. + /// + /// 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 + /// 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` + /// is actually a `DefPathHash`, and can therefore just look up the corresponding + /// `DefId` in `tcx.def_path_hash_to_def_id`. + pub force_from_dep_node: Option) -> bool>, + + /// Invoke a query to put the on-disk cached value in memory. + pub try_load_from_on_disk_cache: Option)>, +} + /// A "work product" corresponds to a `.o` (or other) file that we /// save in between runs. These IDs do not have a `DefId` but rather /// some independent path or string that persists between runs without diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 342d95ca490..2b62a9ee42a 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -4,7 +4,7 @@ mod graph; mod query; mod serialized; -pub use dep_node::{DepNode, DepNodeParams, WorkProductId}; +pub use dep_node::{DepKindStruct, DepNode, DepNodeParams, WorkProductId}; pub use graph::{ hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, TaskDepsRef, WorkProduct, };