Skip to content

Commit e21d771

Browse files
committed
Auto merge of rust-lang#100943 - jyn514:query-system-2, r=cjgillot
Simplify the `define_query` macro This moves a bunch of control flow out of the macro into generic functions, leaving the macro just to call the function with a new generic parameter for each query. It may be possible to improve compile-times / icache by instantiating the generic functions only with the query key, not the query type itself, but I'm going to leave that for a follow-up PR. Helps with rust-lang#96524. r? `@cjgillot`
2 parents b10aed0 + 4e09a13 commit e21d771

File tree

5 files changed

+97
-82
lines changed

5 files changed

+97
-82
lines changed

Diff for: compiler/rustc_middle/src/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ macro_rules! arena_types {
100100
[decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::def_id::LocalDefId>,
101101
[decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,
102102

103-
[] dep_kind: rustc_middle::dep_graph::DepKindStruct,
103+
[] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>,
104104
]);
105105
)
106106
}

Diff for: compiler/rustc_middle/src/dep_graph/dep_node.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
7474
/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value
7575
/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual
7676
/// jump table instead of large matches.
77-
pub struct DepKindStruct {
77+
pub struct DepKindStruct<'tcx> {
7878
/// Anonymous queries cannot be replayed from one compiler invocation to the next.
7979
/// When their result is needed, it is recomputed. They are useful for fine-grained
8080
/// dependency tracking, and caching within one compiler invocation.
@@ -124,10 +124,10 @@ pub struct DepKindStruct {
124124
/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
125125
/// is actually a `DefPathHash`, and can therefore just look up the corresponding
126126
/// `DefId` in `tcx.def_path_hash_to_def_id`.
127-
pub force_from_dep_node: Option<fn(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool>,
127+
pub force_from_dep_node: Option<fn(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool>,
128128

129129
/// Invoke a query to put the on-disk cached value in memory.
130-
pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'_>, DepNode)>,
130+
pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'tcx>, DepNode)>,
131131
}
132132

133133
impl DepKind {

Diff for: compiler/rustc_middle/src/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ pub struct GlobalCtxt<'tcx> {
10891089

10901090
pub queries: &'tcx dyn query::QueryEngine<'tcx>,
10911091
pub query_caches: query::QueryCaches<'tcx>,
1092-
query_kinds: &'tcx [DepKindStruct],
1092+
query_kinds: &'tcx [DepKindStruct<'tcx>],
10931093

10941094
// Internal caches for metadata decoding. No need to track deps on this.
10951095
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
@@ -1246,7 +1246,7 @@ impl<'tcx> TyCtxt<'tcx> {
12461246
dep_graph: DepGraph,
12471247
on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
12481248
queries: &'tcx dyn query::QueryEngine<'tcx>,
1249-
query_kinds: &'tcx [DepKindStruct],
1249+
query_kinds: &'tcx [DepKindStruct<'tcx>],
12501250
crate_name: &str,
12511251
output_filenames: OutputFilenames,
12521252
) -> GlobalCtxt<'tcx> {
@@ -1296,7 +1296,7 @@ impl<'tcx> TyCtxt<'tcx> {
12961296
}
12971297
}
12981298

1299-
pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct {
1299+
pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct<'tcx> {
13001300
&self.query_kinds[k as usize]
13011301
}
13021302

Diff for: compiler/rustc_query_impl/src/plumbing.rs

+87-75
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ use crate::{on_disk_cache, Queries};
77
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
88
use rustc_data_structures::sync::Lock;
99
use rustc_errors::{Diagnostic, Handler};
10-
use rustc_middle::dep_graph::{self, DepKind, DepNodeIndex, SerializedDepNodeIndex};
10+
use rustc_middle::dep_graph::{
11+
self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
12+
};
1113
use rustc_middle::ty::tls::{self, ImplicitCtxt};
1214
use rustc_middle::ty::{self, TyCtxt};
13-
use rustc_query_system::dep_graph::HasDepContext;
15+
use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
1416
use rustc_query_system::ich::StableHashingContext;
1517
use rustc_query_system::query::{
16-
QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame,
18+
force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
19+
QuerySideEffects, QueryStackFrame,
1720
};
1821
use std::any::Any;
1922
use std::num::NonZeroU64;
@@ -298,6 +301,66 @@ pub(crate) fn create_query_frame<
298301
QueryStackFrame::new(name, description, span, def_kind, hash)
299302
}
300303

304+
fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode)
305+
where
306+
Q: QueryDescription<QueryCtxt<'tcx>>,
307+
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
308+
{
309+
debug_assert!(tcx.dep_graph.is_green(&dep_node));
310+
311+
let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
312+
panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
313+
});
314+
if Q::cache_on_disk(tcx, &key) {
315+
let _ = Q::execute_query(tcx, key);
316+
}
317+
}
318+
319+
fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
320+
where
321+
Q: QueryDescription<QueryCtxt<'tcx>>,
322+
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
323+
{
324+
if let Some(key) = Q::Key::recover(tcx, &dep_node) {
325+
#[cfg(debug_assertions)]
326+
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
327+
let tcx = QueryCtxt::from_tcx(tcx);
328+
force_query::<Q, _>(tcx, key, dep_node);
329+
true
330+
} else {
331+
false
332+
}
333+
}
334+
335+
pub(crate) fn query_callback<'tcx, Q: QueryConfig>(
336+
is_anon: bool,
337+
is_eval_always: bool,
338+
) -> DepKindStruct<'tcx>
339+
where
340+
Q: QueryDescription<QueryCtxt<'tcx>>,
341+
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
342+
{
343+
let fingerprint_style = Q::Key::fingerprint_style();
344+
345+
if is_anon || !fingerprint_style.reconstructible() {
346+
return DepKindStruct {
347+
is_anon,
348+
is_eval_always,
349+
fingerprint_style,
350+
force_from_dep_node: None,
351+
try_load_from_on_disk_cache: None,
352+
};
353+
}
354+
355+
DepKindStruct {
356+
is_anon,
357+
is_eval_always,
358+
fingerprint_style,
359+
force_from_dep_node: Some(force_from_dep_node::<Q>),
360+
try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::<Q>),
361+
}
362+
}
363+
301364
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
302365
// invoked by `rustc_query_append`.
303366
macro_rules! define_queries {
@@ -308,18 +371,6 @@ macro_rules! define_queries {
308371
input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
309372
}
310373

311-
mod make_query {
312-
use super::*;
313-
314-
// Create an eponymous constructor for each query.
315-
$(#[allow(nonstandard_style)] $(#[$attr])*
316-
pub fn $name<'tcx>(tcx: QueryCtxt<'tcx>, key: <queries::$name<'tcx> as QueryConfig>::Key) -> QueryStackFrame {
317-
let kind = dep_graph::DepKind::$name;
318-
let name = stringify!($name);
319-
$crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name)
320-
})*
321-
}
322-
323374
#[allow(nonstandard_style)]
324375
mod queries {
325376
use std::marker::PhantomData;
@@ -373,18 +424,19 @@ macro_rules! define_queries {
373424
try_load_from_disk: Self::TRY_LOAD_FROM_DISK,
374425
}
375426
}
427+
428+
fn execute_query(tcx: TyCtxt<'tcx>, k: Self::Key) -> Self::Stored {
429+
tcx.$name(k)
430+
}
376431
})*
377432

378433
#[allow(nonstandard_style)]
379434
mod query_callbacks {
380435
use super::*;
381-
use rustc_middle::dep_graph::DepNode;
382-
use rustc_query_system::dep_graph::DepNodeParams;
383-
use rustc_query_system::query::{force_query, QueryDescription};
384436
use rustc_query_system::dep_graph::FingerprintStyle;
385437

386438
// We use this for most things when incr. comp. is turned off.
387-
pub fn Null() -> DepKindStruct {
439+
pub fn Null<'tcx>() -> DepKindStruct<'tcx> {
388440
DepKindStruct {
389441
is_anon: false,
390442
is_eval_always: false,
@@ -395,7 +447,7 @@ macro_rules! define_queries {
395447
}
396448

397449
// We use this for the forever-red node.
398-
pub fn Red() -> DepKindStruct {
450+
pub fn Red<'tcx>() -> DepKindStruct<'tcx> {
399451
DepKindStruct {
400452
is_anon: false,
401453
is_eval_always: false,
@@ -405,7 +457,7 @@ macro_rules! define_queries {
405457
}
406458
}
407459

408-
pub fn TraitSelect() -> DepKindStruct {
460+
pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
409461
DepKindStruct {
410462
is_anon: true,
411463
is_eval_always: false,
@@ -415,7 +467,7 @@ macro_rules! define_queries {
415467
}
416468
}
417469

418-
pub fn CompileCodegenUnit() -> DepKindStruct {
470+
pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
419471
DepKindStruct {
420472
is_anon: false,
421473
is_eval_always: false,
@@ -425,7 +477,7 @@ macro_rules! define_queries {
425477
}
426478
}
427479

428-
pub fn CompileMonoItem() -> DepKindStruct {
480+
pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
429481
DepKindStruct {
430482
is_anon: false,
431483
is_eval_always: false,
@@ -435,60 +487,15 @@ macro_rules! define_queries {
435487
}
436488
}
437489

438-
$(pub(crate) fn $name()-> DepKindStruct {
439-
let is_anon = is_anon!([$($modifiers)*]);
440-
let is_eval_always = is_eval_always!([$($modifiers)*]);
441-
442-
let fingerprint_style =
443-
<<queries::$name<'_> as QueryConfig>::Key as DepNodeParams<TyCtxt<'_>>>::fingerprint_style();
444-
445-
if is_anon || !fingerprint_style.reconstructible() {
446-
return DepKindStruct {
447-
is_anon,
448-
is_eval_always,
449-
fingerprint_style,
450-
force_from_dep_node: None,
451-
try_load_from_on_disk_cache: None,
452-
}
453-
}
454-
455-
#[inline(always)]
456-
fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> Option<<queries::$name<'tcx> as QueryConfig>::Key> {
457-
<<queries::$name<'_> as QueryConfig>::Key as DepNodeParams<TyCtxt<'_>>>::recover(tcx, &dep_node)
458-
}
459-
460-
fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool {
461-
if let Some(key) = recover(tcx, dep_node) {
462-
#[cfg(debug_assertions)]
463-
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
464-
let tcx = QueryCtxt::from_tcx(tcx);
465-
force_query::<queries::$name<'_>, _>(tcx, key, dep_node);
466-
true
467-
} else {
468-
false
469-
}
470-
}
471-
472-
fn try_load_from_on_disk_cache(tcx: TyCtxt<'_>, dep_node: DepNode) {
473-
debug_assert!(tcx.dep_graph.is_green(&dep_node));
474-
475-
let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash));
476-
if queries::$name::cache_on_disk(tcx, &key) {
477-
let _ = tcx.$name(key);
478-
}
479-
}
480-
481-
DepKindStruct {
482-
is_anon,
483-
is_eval_always,
484-
fingerprint_style,
485-
force_from_dep_node: Some(force_from_dep_node),
486-
try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache),
487-
}
490+
$(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
491+
$crate::plumbing::query_callback::<queries::$name<'tcx>>(
492+
is_anon!([$($modifiers)*]),
493+
is_eval_always!([$($modifiers)*]),
494+
)
488495
})*
489496
}
490497

491-
pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] {
498+
pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
492499
arena.alloc_from_iter(make_dep_kind_array!(query_callbacks))
493500
}
494501
}
@@ -531,9 +538,14 @@ macro_rules! define_queries_struct {
531538
let mut jobs = QueryMap::default();
532539

533540
$(
541+
let make_query = |tcx, key| {
542+
let kind = dep_graph::DepKind::$name;
543+
let name = stringify!($name);
544+
$crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name)
545+
};
534546
self.$name.try_collect_active_jobs(
535547
tcx,
536-
make_query::$name,
548+
make_query,
537549
&mut jobs,
538550
)?;
539551
)*

Diff for: compiler/rustc_query_system/src/query/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ pub trait QueryDescription<CTX: QueryContext>: QueryConfig {
7373
fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable<CTX, Self::Key, Self::Value>;
7474

7575
fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool;
76+
77+
// Don't use this method to compute query results, instead use the methods on TyCtxt
78+
fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored;
7679
}

0 commit comments

Comments
 (0)