Skip to content

Commit 282a88e

Browse files
committed
Auto merge of #158059 - xmakro:perf/lexer-ascii-symbolgallery, r=<try>
Skip query machinery when promoting disk-cached values
2 parents 2574810 + ca30ec8 commit 282a88e

5 files changed

Lines changed: 77 additions & 31 deletions

File tree

compiler/rustc_middle/src/dep_graph/dep_node.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use rustc_hir::definitions::DefPathHash;
5757
use rustc_macros::{Decodable, Encodable, StableHash};
5858
use rustc_span::Symbol;
5959

60-
use super::{KeyFingerprintStyle, SerializedDepNodeIndex};
60+
use super::{DepNodeIndex, KeyFingerprintStyle, SerializedDepNodeIndex};
6161
use crate::dep_graph::DepNodeKey;
6262
use crate::mono::MonoItem;
6363
use crate::ty::{TyCtxt, tls};
@@ -208,8 +208,17 @@ pub struct DepKindVTable<'tcx> {
208208
fn(tcx: TyCtxt<'tcx>, dep_node: DepNode, prev_index: SerializedDepNodeIndex) -> bool,
209209
>,
210210

211-
/// Invoke a query to put the on-disk cached value in memory.
212-
pub promote_from_disk_fn: Option<fn(TyCtxt<'tcx>, DepNode)>,
211+
/// Load the on-disk cached value of a query into memory. The node is known
212+
/// to be green, with `prev_index` its index in the previous session's dep
213+
/// graph and `dep_node_index` its index in the current session's dep graph.
214+
pub promote_from_disk_fn: Option<
215+
fn(
216+
tcx: TyCtxt<'tcx>,
217+
dep_node: DepNode,
218+
prev_index: SerializedDepNodeIndex,
219+
dep_node_index: DepNodeIndex,
220+
),
221+
>,
213222
}
214223

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

compiler/rustc_middle/src/dep_graph/graph.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,12 +1063,12 @@ impl DepGraph {
10631063
let data = self.data.as_ref().unwrap();
10641064
for prev_index in data.colors.values.indices() {
10651065
match data.colors.get(prev_index) {
1066-
DepNodeColor::Green(_) => {
1066+
DepNodeColor::Green(dep_node_index) => {
10671067
let dep_node = data.previous.index_to_node(prev_index);
10681068
if let Some(promote_fn) =
10691069
tcx.dep_kind_vtable(dep_node.kind).promote_from_disk_fn
10701070
{
1071-
promote_fn(tcx, *dep_node)
1071+
promote_fn(tcx, *dep_node, prev_index, dep_node_index)
10721072
};
10731073
}
10741074
DepNodeColor::Unknown | DepNodeColor::Red => {

compiler/rustc_query_impl/src/dep_kind_vtables.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,12 @@ where
117117
crate::execution::force_query_dep_node(tcx, query, dep_node)
118118
},
119119
),
120-
promote_from_disk_fn: (can_recover && is_cache_on_disk).then_some(|tcx, dep_node| {
121-
let query = Q::query_vtable(tcx);
122-
promote_from_disk_inner(tcx, query, dep_node)
123-
}),
120+
promote_from_disk_fn: (can_recover && is_cache_on_disk).then_some(
121+
|tcx, dep_node, prev_index, dep_node_index| {
122+
let query = Q::query_vtable(tcx);
123+
promote_from_disk_inner(tcx, query, dep_node, prev_index, dep_node_index)
124+
},
125+
),
124126
}
125127
}
126128

compiler/rustc_query_impl/src/execution.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::hash::Hash;
22
use std::mem::ManuallyDrop;
33

4+
use rustc_data_structures::fingerprint::Fingerprint;
45
use rustc_data_structures::hash_table::{Entry, HashTable};
56
use rustc_data_structures::stack::ensure_sufficient_stack;
67
use rustc_data_structures::sync::{DynSend, DynSync};
@@ -484,6 +485,20 @@ fn execute_job_incr<'tcx, C: QueryCache>(
484485
(result, dep_node_index)
485486
}
486487

488+
/// Whether a value loaded from the on-disk cache should have its fingerprint
489+
/// verified with `incremental_verify_ich`. If `-Zincremental-verify-ich` is
490+
/// specified, re-hash results from the cache and make sure that they have the
491+
/// expected fingerprint.
492+
///
493+
/// If not, we still seek to verify a subset of fingerprints loaded from disk.
494+
/// Re-hashing results is fairly expensive, so we can't currently afford to
495+
/// verify every hash. This subset should still give us some coverage of
496+
/// potential bugs.
497+
pub(crate) fn should_verify_loaded_value(tcx: TyCtxt<'_>, prev_fingerprint: Fingerprint) -> bool {
498+
prev_fingerprint.split().1.as_u64().is_multiple_of(32)
499+
|| tcx.sess.opts.unstable_opts.incremental_verify_ich
500+
}
501+
487502
/// Given that the dep node for this query+key is green, obtain a value for it
488503
/// by loading one from disk if possible, or by invoking its query provider if
489504
/// necessary.
@@ -518,15 +533,7 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>(
518533
}
519534

520535
let prev_fingerprint = dep_graph_data.prev_value_fingerprint_of(prev_index);
521-
// If `-Zincremental-verify-ich` is specified, re-hash results from
522-
// the cache and make sure that they have the expected fingerprint.
523-
//
524-
// If not, we still seek to verify a subset of fingerprints loaded
525-
// from disk. Re-hashing results is fairly expensive, so we can't
526-
// currently afford to verify every hash. This subset should still
527-
// give us some coverage of potential bugs.
528-
let verify = prev_fingerprint.split().1.as_u64().is_multiple_of(32)
529-
|| tcx.sess.opts.unstable_opts.incremental_verify_ich;
536+
let verify = should_verify_loaded_value(tcx, prev_fingerprint);
530537

531538
(value, verify)
532539
}

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
use std::num::NonZero;
22

3+
use rustc_data_structures::stack::ensure_sufficient_stack;
34
use rustc_data_structures::unord::UnordMap;
45
use rustc_hir::limit::Limit;
56
use rustc_middle::bug;
67
#[expect(unused_imports, reason = "used by doc comments")]
78
use rustc_middle::dep_graph::DepKindVTable;
8-
use rustc_middle::dep_graph::{DepNode, DepNodeKey, SerializedDepNodeIndex};
9+
use rustc_middle::dep_graph::{DepNode, DepNodeIndex, DepNodeKey, SerializedDepNodeIndex};
910
use rustc_middle::query::erase::{Erasable, Erased};
1011
use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder};
1112
use rustc_middle::query::{QueryCache, QueryJobId, QueryMode, QueryVTable, erase};
1213
use rustc_middle::ty::TyCtxt;
1314
use rustc_middle::ty::tls::{self, ImplicitCtxt};
15+
use rustc_middle::verify_ich::incremental_verify_ich;
1416
use rustc_serialize::{Decodable, Encodable};
1517
use rustc_span::DUMMY_SP;
1618
use rustc_span::def_id::LOCAL_CRATE;
1719

1820
use crate::error::{QueryOverflow, QueryOverflowNote};
19-
use crate::execution::all_inactive;
21+
use crate::execution::{all_inactive, should_verify_loaded_value};
2022
use crate::job::find_dep_kind_root;
2123
use crate::query_impl::for_each_query_vtable;
2224
use crate::{CollectActiveJobsKind, collect_active_query_jobs};
@@ -140,6 +142,8 @@ pub(crate) fn promote_from_disk_inner<'tcx, C: QueryCache>(
140142
tcx: TyCtxt<'tcx>,
141143
query: &'tcx QueryVTable<'tcx, C>,
142144
dep_node: DepNode,
145+
prev_index: SerializedDepNodeIndex,
146+
dep_node_index: DepNodeIndex,
143147
) {
144148
debug_assert!(tcx.dep_graph.is_green(&dep_node));
145149

@@ -156,17 +160,41 @@ pub(crate) fn promote_from_disk_inner<'tcx, C: QueryCache>(
156160
return;
157161
}
158162

159-
match query.cache.lookup(&key) {
160-
// If the value is already in memory, then promotion isn't needed.
161-
Some(_) => {}
162-
163-
// "Execute" the query to load its disk-cached value into memory.
164-
//
165-
// We know that the key is cache-on-disk and its node is green,
166-
// so there _must_ be a value on disk to load.
167-
//
168-
// FIXME(Zalathar): Is there a reasonable way to skip more of the
169-
// query bookkeeping when doing this?
163+
// If the value is already in memory, then promotion isn't needed.
164+
if query.cache.lookup(&key).is_some() {
165+
return;
166+
}
167+
168+
// Load the disk-cached value into memory.
169+
let dep_graph_data =
170+
tcx.dep_graph.data().expect("should always be present in incremental mode");
171+
172+
let prof_timer = tcx.prof.incr_cache_loading();
173+
let value = ensure_sufficient_stack(|| (query.try_load_from_disk_fn)(tcx, prev_index));
174+
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
175+
176+
match value {
177+
Some(value) => {
178+
// Verify the fingerprints of the same subset of loaded values as
179+
// `load_from_disk_or_invoke_provider_green` does.
180+
let prev_fingerprint = dep_graph_data.prev_value_fingerprint_of(prev_index);
181+
if should_verify_loaded_value(tcx, prev_fingerprint) {
182+
incremental_verify_ich(
183+
tcx,
184+
dep_graph_data,
185+
&value,
186+
prev_index,
187+
query.hash_value_fn,
188+
query.format_value,
189+
);
190+
}
191+
192+
query.cache.complete(key, value, dep_node_index);
193+
}
194+
195+
// There was no value on disk, despite the key being cache-on-disk and
196+
// its node being green. "Execute" the query through the normal
197+
// machinery, which will recompute the value and put it in memory.
170198
None => {
171199
(query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Get);
172200
}

0 commit comments

Comments
 (0)