about summary refs log tree commit diff
path: root/compiler/rustc_query_system/src/dep_graph/mod.rs
diff options
context:
space:
mode:
authorJoshua Nelson <jnelson@cloudflare.com>2022-09-11 23:18:08 -0500
committerJoshua Nelson <jnelson@cloudflare.com>2022-09-25 12:07:17 -0500
commitf3f91bb51477084cdff194d8908053844fc6d9ea (patch)
treec59213cd056b2b448911e69b79892a245189ed8f /compiler/rustc_query_system/src/dep_graph/mod.rs
parent93a0fb190e9a781a36f9ab2faf02f2e3dc303234 (diff)
downloadrust-f3f91bb51477084cdff194d8908053844fc6d9ea.tar.gz
rust-f3f91bb51477084cdff194d8908053844fc6d9ea.zip
Move functions on `DepKindStruct` from rustc_middle to rustc_query_system
Diffstat (limited to 'compiler/rustc_query_system/src/dep_graph/mod.rs')
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs57
1 files changed, 52 insertions, 5 deletions
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 2b62a9ee42a..a5c27479126 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -34,16 +34,61 @@ pub trait DepContext: Copy {
     /// Access the compiler session.
     fn sess(&self) -> &Session;
 
-    /// Return whether this kind always require evaluation.
-    fn is_eval_always(&self, kind: Self::DepKind) -> bool;
+    fn dep_kind_info(&self, dep_node: Self::DepKind) -> &DepKindStruct<Self>;
+
+    #[inline(always)]
+    fn fingerprint_style(&self, kind: Self::DepKind) -> FingerprintStyle {
+        let data = self.dep_kind_info(kind);
+        if data.is_anon {
+            return FingerprintStyle::Opaque;
+        }
+        data.fingerprint_style
+    }
 
-    fn fingerprint_style(&self, kind: Self::DepKind) -> FingerprintStyle;
+    #[inline(always)]
+    /// Return whether this kind always require evaluation.
+    fn is_eval_always(&self, kind: Self::DepKind) -> bool {
+        self.dep_kind_info(kind).is_eval_always
+    }
 
     /// Try to force a dep node to execute and see if it's green.
-    fn try_force_from_dep_node(&self, dep_node: DepNode<Self::DepKind>) -> bool;
+    fn try_force_from_dep_node(self, dep_node: DepNode<Self::DepKind>) -> bool {
+        debug!("try_force_from_dep_node({:?}) --- trying to force", dep_node);
+
+        // We must avoid ever having to call `force_from_dep_node()` for a
+        // `DepNode::codegen_unit`:
+        // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
+        // would always end up having to evaluate the first caller of the
+        // `codegen_unit` query that *is* reconstructible. This might very well be
+        // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
+        // to re-trigger calling the `codegen_unit` query with the right key. At
+        // that point we would already have re-done all the work we are trying to
+        // avoid doing in the first place.
+        // The solution is simple: Just explicitly call the `codegen_unit` query for
+        // each CGU, right after partitioning. This way `try_mark_green` will always
+        // hit the cache instead of having to go through `force_from_dep_node`.
+        // This assertion makes sure, we actually keep applying the solution above.
+        debug_assert!(
+            !dep_node.kind.is_codegen_unit_query(),
+            "calling force_from_dep_node() on DepKind::codegen_unit"
+        );
+
+        let cb = self.dep_kind_info(dep_node.kind);
+        if let Some(f) = cb.force_from_dep_node {
+            f(self, dep_node);
+            true
+        } else {
+            false
+        }
+    }
 
     /// Load data from the on-disk cache.
-    fn try_load_from_on_disk_cache(&self, dep_node: DepNode<Self::DepKind>);
+    fn try_load_from_on_disk_cache(self, dep_node: DepNode<Self::DepKind>) {
+        let cb = self.dep_kind_info(dep_node.kind);
+        if let Some(f) = cb.try_load_from_on_disk_cache {
+            f(self, dep_node)
+        }
+    }
 }
 
 pub trait HasDepContext: Copy {
@@ -91,6 +136,8 @@ pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder>
     /// DepKind to use to create the initial forever-red node.
     const RED: Self;
 
+    fn is_codegen_unit_query(self) -> bool;
+
     /// Implementation of `std::fmt::Debug` for `DepNode`.
     fn debug_node(node: &DepNode<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result;