Skip to content

Commit 28b5c1c

Browse files
committed
Auto merge of #153122 - Zalathar:dep-kind-vtable, r=nnethercote
Improve the forcing/promotion functions in `DepKindVTable` This is a bundle of changes to the two function pointers in `DepKindVTable` that are responsible for forcing dep nodes, or promoting disk-cached values from the previous session into memory. The perf improvements to incr-unchanged and incr-patched are likely from skipping more of the “promotion” plumbing for queries that never cache to disk.
2 parents 024757f + 08df254 commit 28b5c1c

6 files changed

Lines changed: 54 additions & 54 deletions

File tree

compiler/rustc_middle/src/dep_graph/dep_node.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl DepNode {
121121

122122
#[cfg(debug_assertions)]
123123
{
124-
if !tcx.key_fingerprint_style(kind).reconstructible()
124+
if !tcx.key_fingerprint_style(kind).is_maybe_recoverable()
125125
&& (tcx.sess.opts.unstable_opts.incremental_info
126126
|| tcx.sess.opts.unstable_opts.query_dep_graph)
127127
{
@@ -225,12 +225,12 @@ pub struct DepKindVTable<'tcx> {
225225
/// with kind `mir_promoted`, we know that the key fingerprint of the `DepNode`
226226
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
227227
/// `DefId` in `tcx.def_path_hash_to_def_id`.
228-
pub force_from_dep_node: Option<
228+
pub force_from_dep_node_fn: Option<
229229
fn(tcx: TyCtxt<'tcx>, dep_node: DepNode, prev_index: SerializedDepNodeIndex) -> bool,
230230
>,
231231

232232
/// Invoke a query to put the on-disk cached value in memory.
233-
pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'tcx>, DepNode)>,
233+
pub promote_from_disk_fn: Option<fn(TyCtxt<'tcx>, DepNode)>,
234234
}
235235

236236
/// A "work product" corresponds to a `.o` (or other) file that we

compiler/rustc_middle/src/dep_graph/graph.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,11 @@ impl DepGraph {
10641064
match data.colors.get(prev_index) {
10651065
DepNodeColor::Green(_) => {
10661066
let dep_node = data.previous.index_to_node(prev_index);
1067-
tcx.try_load_from_on_disk_cache(dep_node);
1067+
if let Some(promote_fn) =
1068+
tcx.dep_kind_vtable(dep_node.kind).promote_from_disk_fn
1069+
{
1070+
promote_fn(tcx, *dep_node)
1071+
};
10681072
}
10691073
DepNodeColor::Unknown | DepNodeColor::Red => {
10701074
// We can skip red nodes because a node can only be marked

compiler/rustc_middle/src/dep_graph/mod.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ pub enum KeyFingerprintStyle {
4242
}
4343

4444
impl KeyFingerprintStyle {
45+
/// True if a key can _potentially_ be recovered from a key fingerprint
46+
/// with this style.
47+
///
48+
/// For some key types, recovery is possible but not guaranteed.
4549
#[inline]
46-
pub const fn reconstructible(self) -> bool {
50+
pub const fn is_maybe_recoverable(self) -> bool {
4751
match self {
4852
KeyFingerprintStyle::DefPathHash
4953
| KeyFingerprintStyle::Unit
@@ -103,7 +107,7 @@ impl<'tcx> TyCtxt<'tcx> {
103107
prev_index: SerializedDepNodeIndex,
104108
frame: &MarkFrame<'_>,
105109
) -> bool {
106-
if let Some(force_fn) = self.dep_kind_vtable(dep_node.kind).force_from_dep_node {
110+
if let Some(force_fn) = self.dep_kind_vtable(dep_node.kind).force_from_dep_node_fn {
107111
match panic::catch_unwind(panic::AssertUnwindSafe(|| {
108112
force_fn(self, dep_node, prev_index)
109113
})) {
@@ -119,11 +123,4 @@ impl<'tcx> TyCtxt<'tcx> {
119123
false
120124
}
121125
}
122-
123-
/// Load data from the on-disk cache.
124-
fn try_load_from_on_disk_cache(self, dep_node: &DepNode) {
125-
if let Some(try_load_fn) = self.dep_kind_vtable(dep_node.kind).try_load_from_on_disk_cache {
126-
try_load_fn(self, *dep_node)
127-
}
128-
}
129126
}

compiler/rustc_query_impl/src/dep_kind_vtables.rs

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, KeyFingerprintStyle};
33
use rustc_middle::query::QueryCache;
44

55
use crate::GetQueryVTable;
6-
use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner};
6+
use crate::plumbing::{force_from_dep_node_inner, promote_from_disk_inner};
77

88
/// [`DepKindVTable`] constructors for special dep kinds that aren't queries.
99
#[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")]
@@ -16,10 +16,10 @@ mod non_query {
1616
is_anon: false,
1717
is_eval_always: false,
1818
key_fingerprint_style: KeyFingerprintStyle::Unit,
19-
force_from_dep_node: Some(|_, dep_node, _| {
19+
force_from_dep_node_fn: Some(|_, dep_node, _| {
2020
bug!("force_from_dep_node: encountered {dep_node:?}")
2121
}),
22-
try_load_from_on_disk_cache: None,
22+
promote_from_disk_fn: None,
2323
}
2424
}
2525

@@ -29,10 +29,10 @@ mod non_query {
2929
is_anon: false,
3030
is_eval_always: false,
3131
key_fingerprint_style: KeyFingerprintStyle::Unit,
32-
force_from_dep_node: Some(|_, dep_node, _| {
32+
force_from_dep_node_fn: Some(|_, dep_node, _| {
3333
bug!("force_from_dep_node: encountered {dep_node:?}")
3434
}),
35-
try_load_from_on_disk_cache: None,
35+
promote_from_disk_fn: None,
3636
}
3737
}
3838

@@ -41,11 +41,11 @@ mod non_query {
4141
is_anon: false,
4242
is_eval_always: false,
4343
key_fingerprint_style: KeyFingerprintStyle::Unit,
44-
force_from_dep_node: Some(|tcx, _, prev_index| {
44+
force_from_dep_node_fn: Some(|tcx, _, prev_index| {
4545
tcx.dep_graph.force_diagnostic_node(tcx, prev_index);
4646
true
4747
}),
48-
try_load_from_on_disk_cache: None,
48+
promote_from_disk_fn: None,
4949
}
5050
}
5151

@@ -54,8 +54,8 @@ mod non_query {
5454
is_anon: true,
5555
is_eval_always: false,
5656
key_fingerprint_style: KeyFingerprintStyle::Opaque,
57-
force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")),
58-
try_load_from_on_disk_cache: None,
57+
force_from_dep_node_fn: Some(|_, _, _| bug!("cannot force an anon node")),
58+
promote_from_disk_fn: None,
5959
}
6060
}
6161

@@ -64,8 +64,8 @@ mod non_query {
6464
is_anon: true,
6565
is_eval_always: false,
6666
key_fingerprint_style: KeyFingerprintStyle::Unit,
67-
force_from_dep_node: None,
68-
try_load_from_on_disk_cache: None,
67+
force_from_dep_node_fn: None,
68+
promote_from_disk_fn: None,
6969
}
7070
}
7171

@@ -74,8 +74,8 @@ mod non_query {
7474
is_anon: false,
7575
is_eval_always: false,
7676
key_fingerprint_style: KeyFingerprintStyle::Opaque,
77-
force_from_dep_node: None,
78-
try_load_from_on_disk_cache: None,
77+
force_from_dep_node_fn: None,
78+
promote_from_disk_fn: None,
7979
}
8080
}
8181

@@ -84,8 +84,8 @@ mod non_query {
8484
is_anon: false,
8585
is_eval_always: false,
8686
key_fingerprint_style: KeyFingerprintStyle::Opaque,
87-
force_from_dep_node: None,
88-
try_load_from_on_disk_cache: None,
87+
force_from_dep_node_fn: None,
88+
promote_from_disk_fn: None,
8989
}
9090
}
9191

@@ -94,8 +94,8 @@ mod non_query {
9494
is_anon: false,
9595
is_eval_always: false,
9696
key_fingerprint_style: KeyFingerprintStyle::Unit,
97-
force_from_dep_node: None,
98-
try_load_from_on_disk_cache: None,
97+
force_from_dep_node_fn: None,
98+
promote_from_disk_fn: None,
9999
}
100100
}
101101
}
@@ -104,6 +104,7 @@ mod non_query {
104104
/// Called from macro-generated code for each query.
105105
pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>(
106106
is_anon: bool,
107+
is_cache_on_disk: bool,
107108
is_eval_always: bool,
108109
) -> DepKindVTable<'tcx>
109110
where
@@ -115,26 +116,20 @@ where
115116
<Q::Cache as QueryCache>::Key::key_fingerprint_style()
116117
};
117118

118-
if is_anon || !key_fingerprint_style.reconstructible() {
119-
return DepKindVTable {
120-
is_anon,
121-
is_eval_always,
122-
key_fingerprint_style,
123-
force_from_dep_node: None,
124-
try_load_from_on_disk_cache: None,
125-
};
119+
// A query dep-node can only be forced or promoted if it can recover a key
120+
// from its key fingerprint.
121+
let can_recover = key_fingerprint_style.is_maybe_recoverable();
122+
if is_anon {
123+
assert!(!can_recover);
126124
}
127125

128126
DepKindVTable {
129127
is_anon,
130128
is_eval_always,
131129
key_fingerprint_style,
132-
force_from_dep_node: Some(|tcx, dep_node, _| {
133-
force_from_dep_node_inner(Q::query_vtable(tcx), tcx, dep_node)
134-
}),
135-
try_load_from_on_disk_cache: Some(|tcx, dep_node| {
136-
try_load_from_on_disk_cache_inner(Q::query_vtable(tcx), tcx, dep_node)
137-
}),
130+
force_from_dep_node_fn: can_recover.then_some(force_from_dep_node_inner::<Q>),
131+
promote_from_disk_fn: (can_recover && is_cache_on_disk)
132+
.then_some(promote_from_disk_inner::<Q>),
138133
}
139134
}
140135

compiler/rustc_query_impl/src/execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>(
572572
// can be forced from `DepNode`.
573573
debug_assert!(
574574
!query.will_cache_on_disk_for_key(tcx, key)
575-
|| !tcx.key_fingerprint_style(dep_node.kind).reconstructible(),
575+
|| !tcx.key_fingerprint_style(dep_node.kind).is_maybe_recoverable(),
576576
"missing on-disk cache entry for {dep_node:?}"
577577
);
578578

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ use rustc_middle::ty::{self, TyCtxt};
2929
use rustc_serialize::{Decodable, Encodable};
3030
use rustc_span::def_id::LOCAL_CRATE;
3131

32-
use crate::collect_active_jobs_from_all_queries;
3332
use crate::error::{QueryOverflow, QueryOverflowNote};
3433
use crate::execution::{all_inactive, force_query};
3534
use crate::job::find_dep_kind_root;
35+
use crate::{GetQueryVTable, collect_active_jobs_from_all_queries};
3636

3737
fn depth_limit_error<'tcx>(tcx: TyCtxt<'tcx>, job: QueryJobId) {
3838
let job_map =
@@ -326,15 +326,15 @@ pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache>(
326326
});
327327
}
328328

329-
/// Implementation of [`DepKindVTable::try_load_from_on_disk_cache`] for queries.
330-
pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache>(
331-
query: &'tcx QueryVTable<'tcx, C>,
329+
/// Implementation of [`DepKindVTable::promote_from_disk_fn`] for queries.
330+
pub(crate) fn promote_from_disk_inner<'tcx, Q: GetQueryVTable<'tcx>>(
332331
tcx: TyCtxt<'tcx>,
333332
dep_node: DepNode,
334333
) {
334+
let query = Q::query_vtable(tcx);
335335
debug_assert!(tcx.dep_graph.is_green(&dep_node));
336336

337-
let key = C::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| {
337+
let key = <Q::Cache as QueryCache>::Key::try_recover_key(tcx, &dep_node).unwrap_or_else(|| {
338338
panic!(
339339
"Failed to recover key for {dep_node:?} with key fingerprint {}",
340340
dep_node.key_fingerprint
@@ -379,12 +379,15 @@ where
379379
value
380380
}
381381

382-
/// Implementation of [`DepKindVTable::force_from_dep_node`] for queries.
383-
pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache>(
384-
query: &'tcx QueryVTable<'tcx, C>,
382+
/// Implementation of [`DepKindVTable::force_from_dep_node_fn`] for queries.
383+
pub(crate) fn force_from_dep_node_inner<'tcx, Q: GetQueryVTable<'tcx>>(
385384
tcx: TyCtxt<'tcx>,
386385
dep_node: DepNode,
386+
// Needed by the vtable function signature, but not used when forcing queries.
387+
_prev_index: SerializedDepNodeIndex,
387388
) -> bool {
389+
let query = Q::query_vtable(tcx);
390+
388391
// We must avoid ever having to call `force_from_dep_node()` for a
389392
// `DepNode::codegen_unit`:
390393
// Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
@@ -403,7 +406,7 @@ pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache>(
403406
"calling force_from_dep_node() on dep_kinds::codegen_unit"
404407
);
405408

406-
if let Some(key) = C::Key::try_recover_key(tcx, &dep_node) {
409+
if let Some(key) = <Q::Cache as QueryCache>::Key::try_recover_key(tcx, &dep_node) {
407410
force_query(query, tcx, key, dep_node);
408411
true
409412
} else {
@@ -697,6 +700,7 @@ macro_rules! define_queries {
697700
use $crate::query_impl::$name::VTableGetter;
698701
make_dep_kind_vtable_for_query::<VTableGetter>(
699702
is_anon!([$($modifiers)*]),
703+
if_cache_on_disk!([$($modifiers)*] true false),
700704
is_eval_always!([$($modifiers)*]),
701705
)
702706
}

0 commit comments

Comments
 (0)