@@ -34,16 +34,61 @@ pub trait DepContext: Copy {
3434 /// Access the compiler session.
3535 fn sess ( & self ) -> & Session ;
3636
37- /// Return whether this kind always require evaluation.
38- fn is_eval_always ( & self , kind : Self :: DepKind ) -> bool ;
37+ fn dep_kind_info ( & self , dep_node : Self :: DepKind ) -> & DepKindStruct < Self > ;
38+
39+ #[ inline( always) ]
40+ fn fingerprint_style ( & self , kind : Self :: DepKind ) -> FingerprintStyle {
41+ let data = self . dep_kind_info ( kind) ;
42+ if data. is_anon {
43+ return FingerprintStyle :: Opaque ;
44+ }
45+ data. fingerprint_style
46+ }
3947
40- fn fingerprint_style ( & self , kind : Self :: DepKind ) -> FingerprintStyle ;
48+ #[ inline( always) ]
49+ /// Return whether this kind always require evaluation.
50+ fn is_eval_always ( & self , kind : Self :: DepKind ) -> bool {
51+ self . dep_kind_info ( kind) . is_eval_always
52+ }
4153
4254 /// Try to force a dep node to execute and see if it's green.
43- fn try_force_from_dep_node ( & self , dep_node : DepNode < Self :: DepKind > ) -> bool ;
55+ fn try_force_from_dep_node ( self , dep_node : DepNode < Self :: DepKind > ) -> bool {
56+ debug ! ( "try_force_from_dep_node({:?}) --- trying to force" , dep_node) ;
57+
58+ // We must avoid ever having to call `force_from_dep_node()` for a
59+ // `DepNode::codegen_unit`:
60+ // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
61+ // would always end up having to evaluate the first caller of the
62+ // `codegen_unit` query that *is* reconstructible. This might very well be
63+ // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
64+ // to re-trigger calling the `codegen_unit` query with the right key. At
65+ // that point we would already have re-done all the work we are trying to
66+ // avoid doing in the first place.
67+ // The solution is simple: Just explicitly call the `codegen_unit` query for
68+ // each CGU, right after partitioning. This way `try_mark_green` will always
69+ // hit the cache instead of having to go through `force_from_dep_node`.
70+ // This assertion makes sure, we actually keep applying the solution above.
71+ debug_assert ! (
72+ !dep_node. kind. is_codegen_unit_query( ) ,
73+ "calling force_from_dep_node() on DepKind::codegen_unit"
74+ ) ;
75+
76+ let cb = self . dep_kind_info ( dep_node. kind ) ;
77+ if let Some ( f) = cb. force_from_dep_node {
78+ f ( self , dep_node) ;
79+ true
80+ } else {
81+ false
82+ }
83+ }
4484
4585 /// Load data from the on-disk cache.
46- fn try_load_from_on_disk_cache ( & self , dep_node : DepNode < Self :: DepKind > ) ;
86+ fn try_load_from_on_disk_cache ( self , dep_node : DepNode < Self :: DepKind > ) {
87+ let cb = self . dep_kind_info ( dep_node. kind ) ;
88+ if let Some ( f) = cb. try_load_from_on_disk_cache {
89+ f ( self , dep_node)
90+ }
91+ }
4792}
4893
4994pub trait HasDepContext : Copy {
@@ -91,6 +136,8 @@ pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder>
91136 /// DepKind to use to create the initial forever-red node.
92137 const RED : Self ;
93138
139+ fn is_codegen_unit_query ( self ) -> bool ;
140+
94141 /// Implementation of `std::fmt::Debug` for `DepNode`.
95142 fn debug_node ( node : & DepNode < Self > , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result ;
96143
0 commit comments