Skip to content

Commit 28d0e75

Browse files
committed
Auto merge of #90210 - cjgillot:qarray2, r=Mark-Simulacrum
Build the query vtable directly. Continuation of #89978. This shrinks the query interface and attempts to reduce the amount of function pointer calls.
2 parents 41d8c94 + 138e96b commit 28d0e75

File tree

7 files changed

+68
-122
lines changed

7 files changed

+68
-122
lines changed

compiler/rustc_macros/src/query.rs

+18-24
Original file line numberDiff line numberDiff line change
@@ -349,24 +349,14 @@ fn add_query_description_impl(
349349
let try_load_from_disk = if let Some((tcx, id, block)) = modifiers.load_cached.as_ref() {
350350
// Use custom code to load the query from disk
351351
quote! {
352-
#[inline]
353-
fn try_load_from_disk(
354-
#tcx: QueryCtxt<'tcx>,
355-
#id: SerializedDepNodeIndex
356-
) -> Option<Self::Value> {
357-
#block
358-
}
352+
const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>>
353+
= Some(|#tcx, #id| { #block });
359354
}
360355
} else {
361356
// Use the default code to load the query from disk
362357
quote! {
363-
#[inline]
364-
fn try_load_from_disk(
365-
tcx: QueryCtxt<'tcx>,
366-
id: SerializedDepNodeIndex
367-
) -> Option<Self::Value> {
368-
tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id)
369-
}
358+
const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>>
359+
= Some(|tcx, id| tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id));
370360
}
371361
};
372362

@@ -380,12 +370,9 @@ fn add_query_description_impl(
380370
// expr is a `Block`, meaning that `{ #expr }` gets expanded
381371
// to `{ { stmts... } }`, which triggers the `unused_braces` lint.
382372
quote! {
383-
#[inline]
384373
#[allow(unused_variables, unused_braces)]
385-
fn cache_on_disk(
386-
#tcx: QueryCtxt<'tcx>,
387-
#key: &Self::Key,
388-
) -> bool {
374+
#[inline]
375+
fn cache_on_disk(#tcx: TyCtxt<'tcx>, #key: &Self::Key) -> bool {
389376
#expr
390377
}
391378

@@ -395,25 +382,32 @@ fn add_query_description_impl(
395382
if modifiers.load_cached.is_some() {
396383
panic!("load_cached modifier on query `{}` without a cache modifier", name);
397384
}
398-
quote! {}
385+
quote! {
386+
#[inline]
387+
fn cache_on_disk(_: TyCtxt<'tcx>, _: &Self::Key) -> bool {
388+
false
389+
}
390+
391+
const TRY_LOAD_FROM_DISK: Option<fn(QueryCtxt<$tcx>, SerializedDepNodeIndex) -> Option<Self::Value>> = None;
392+
}
399393
};
400394

401395
let (tcx, desc) = modifiers.desc;
402396
let tcx = tcx.as_ref().map_or_else(|| quote! { _ }, |t| quote! { #t });
403397

404398
let desc = quote! {
405399
#[allow(unused_variables)]
406-
fn describe(tcx: QueryCtxt<'tcx>, key: Self::Key) -> String {
400+
fn describe(tcx: QueryCtxt<$tcx>, key: Self::Key) -> String {
407401
let (#tcx, #key) = (*tcx, key);
408402
::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into())
409403
}
410404
};
411405

412406
impls.extend(quote! {
413-
impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::#name<'tcx> {
407+
(#name<$tcx:tt>) => {
414408
#desc
415409
#cache
416-
}
410+
};
417411
});
418412
}
419413

@@ -521,7 +515,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
521515
}
522516
#[macro_export]
523517
macro_rules! rustc_query_description {
524-
() => { #query_description_stream }
518+
#query_description_stream
525519
}
526520
})
527521
}

compiler/rustc_query_impl/src/lib.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ extern crate rustc_macros;
1515
#[macro_use]
1616
extern crate rustc_middle;
1717

18-
use rustc_data_structures::fingerprint::Fingerprint;
1918
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
20-
use rustc_errors::DiagnosticBuilder;
2119
use rustc_middle::arena::Arena;
22-
use rustc_middle::dep_graph::{self, DepKindStruct};
20+
use rustc_middle::dep_graph::{self, DepKindStruct, SerializedDepNodeIndex};
2321
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
2422
use rustc_middle::ty::query::{Providers, QueryEngine};
2523
use rustc_middle::ty::{self, TyCtxt};
26-
use rustc_query_system::ich::StableHashingContext;
24+
use rustc_span::def_id::LocalDefId;
2725
use rustc_span::Span;
2826

2927
#[macro_use]
@@ -40,9 +38,8 @@ use keys::Key;
4038
mod values;
4139
use self::values::Value;
4240

43-
use rustc_query_system::query::QueryAccessors;
4441
pub use rustc_query_system::query::QueryConfig;
45-
pub(crate) use rustc_query_system::query::QueryDescription;
42+
pub(crate) use rustc_query_system::query::{QueryDescription, QueryVtable};
4643

4744
mod on_disk_cache;
4845
pub use on_disk_cache::OnDiskCache;
@@ -52,6 +49,14 @@ pub use self::profiling_support::alloc_self_profile_query_strings;
5249

5350
mod util;
5451

52+
fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
53+
if def_id.is_top_level_module() {
54+
"top-level module".to_string()
55+
} else {
56+
format!("module `{}`", tcx.def_path_str(def_id.to_def_id()))
57+
}
58+
}
59+
5560
rustc_query_append! { [define_queries!][<'tcx>] }
5661

5762
impl<'tcx> Queries<'tcx> {

compiler/rustc_query_impl/src/on_disk_cache.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ pub fn encode_query_results<'a, 'tcx, CTX, Q>(
10181018
) -> FileEncodeResult
10191019
where
10201020
CTX: QueryContext + 'tcx,
1021-
Q: super::QueryDescription<CTX> + super::QueryAccessors<CTX>,
1021+
Q: super::QueryDescription<CTX>,
10221022
Q::Value: Encodable<CacheEncoder<'a, 'tcx, FileEncoder>>,
10231023
{
10241024
let _timer = tcx
@@ -1033,7 +1033,7 @@ where
10331033
if res.is_err() {
10341034
return;
10351035
}
1036-
if Q::cache_on_disk(tcx, &key) {
1036+
if Q::cache_on_disk(*tcx.dep_context(), &key) {
10371037
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
10381038

10391039
// Record position of the cache entry.

compiler/rustc_query_impl/src/plumbing.rs

+19-32
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,17 @@
22
//! generate the actual methods on tcx which find and execute the provider,
33
//! manage the caches, and so forth.
44
5-
use crate::{on_disk_cache, queries, Queries};
5+
use crate::{on_disk_cache, Queries};
66
use rustc_middle::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex};
77
use rustc_middle::ty::tls::{self, ImplicitCtxt};
8-
use rustc_middle::ty::{self, TyCtxt};
8+
use rustc_middle::ty::TyCtxt;
99
use rustc_query_system::dep_graph::HasDepContext;
10-
use rustc_query_system::query::{
11-
QueryContext, QueryDescription, QueryJobId, QueryMap, QuerySideEffects,
12-
};
10+
use rustc_query_system::query::{QueryContext, QueryJobId, QueryMap, QuerySideEffects};
1311

1412
use rustc_data_structures::sync::Lock;
1513
use rustc_data_structures::thin_vec::ThinVec;
1614
use rustc_errors::{Diagnostic, Handler};
1715
use rustc_serialize::opaque;
18-
use rustc_span::def_id::LocalDefId;
1916

2017
use std::any::Any;
2118

@@ -290,11 +287,8 @@ macro_rules! define_queries {
290287
const NAME: &'static str = stringify!($name);
291288
}
292289

293-
impl<$tcx> QueryAccessors<QueryCtxt<$tcx>> for queries::$name<$tcx> {
294-
const ANON: bool = is_anon!([$($modifiers)*]);
295-
const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
296-
const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$name;
297-
const HASH_RESULT: Option<fn(&mut StableHashingContext<'_>, &Self::Value) -> Fingerprint> = hash_result!([$($modifiers)*]);
290+
impl<$tcx> QueryDescription<QueryCtxt<$tcx>> for queries::$name<$tcx> {
291+
rustc_query_description! { $name<$tcx> }
298292

299293
type Cache = query_storage::$name<$tcx>;
300294

@@ -313,22 +307,26 @@ macro_rules! define_queries {
313307
}
314308

315309
#[inline]
316-
fn compute_fn(tcx: QueryCtxt<'tcx>, key: &Self::Key) ->
317-
fn(TyCtxt<'tcx>, Self::Key) -> Self::Value
310+
fn make_vtable(tcx: QueryCtxt<'tcx>, key: &Self::Key) ->
311+
QueryVtable<QueryCtxt<$tcx>, Self::Key, Self::Value>
318312
{
319-
if key.query_crate_is_local() {
313+
let compute = if key.query_crate_is_local() {
320314
tcx.queries.local_providers.$name
321315
} else {
322316
tcx.queries.extern_providers.$name
317+
};
318+
let cache_on_disk = Self::cache_on_disk(tcx.tcx, key);
319+
QueryVtable {
320+
anon: is_anon!([$($modifiers)*]),
321+
eval_always: is_eval_always!([$($modifiers)*]),
322+
dep_kind: dep_graph::DepKind::$name,
323+
hash_result: hash_result!([$($modifiers)*]),
324+
handle_cycle_error: |tcx, mut error| handle_cycle_error!([$($modifiers)*][tcx, error]),
325+
compute,
326+
cache_on_disk,
327+
try_load_from_disk: Self::TRY_LOAD_FROM_DISK,
323328
}
324329
}
325-
326-
fn handle_cycle_error(
327-
tcx: QueryCtxt<'tcx>,
328-
mut error: DiagnosticBuilder<'_>,
329-
) -> Self::Value {
330-
handle_cycle_error!([$($modifiers)*][tcx, error])
331-
}
332330
})*
333331

334332
#[allow(nonstandard_style)]
@@ -417,7 +415,6 @@ macro_rules! define_queries {
417415
debug_assert!(tcx.dep_graph.is_green(&dep_node));
418416

419417
let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash));
420-
let tcx = QueryCtxt::from_tcx(tcx);
421418
if queries::$name::cache_on_disk(tcx, &key) {
422419
let _ = tcx.$name(key);
423420
}
@@ -518,13 +515,3 @@ macro_rules! define_queries_struct {
518515
}
519516
};
520517
}
521-
522-
fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
523-
if def_id.is_top_level_module() {
524-
"top-level module".to_string()
525-
} else {
526-
format!("module `{}`", tcx.def_path_str(def_id.to_def_id()))
527-
}
528-
}
529-
530-
rustc_query_description! {}

compiler/rustc_query_system/src/query/config.rs

+13-53
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ pub trait QueryConfig {
1919
type Stored: Clone;
2020
}
2121

22-
pub(crate) struct QueryVtable<CTX: QueryContext, K, V> {
22+
pub struct QueryVtable<CTX: QueryContext, K, V> {
2323
pub anon: bool,
2424
pub dep_kind: CTX::DepKind,
2525
pub eval_always: bool,
26+
pub cache_on_disk: bool,
2627

2728
pub compute: fn(CTX::DepContext, K) -> V,
2829
pub hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
2930
pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V,
30-
pub cache_on_disk: fn(CTX, &K) -> bool,
31-
pub try_load_from_disk: fn(CTX, SerializedDepNodeIndex) -> Option<V>,
31+
pub try_load_from_disk: Option<fn(CTX, SerializedDepNodeIndex) -> Option<V>>,
3232
}
3333

3434
impl<CTX: QueryContext, K, V> QueryVtable<CTX, K, V> {
@@ -43,25 +43,21 @@ impl<CTX: QueryContext, K, V> QueryVtable<CTX, K, V> {
4343
(self.compute)(tcx, key)
4444
}
4545

46-
pub(crate) fn cache_on_disk(&self, tcx: CTX, key: &K) -> bool {
47-
(self.cache_on_disk)(tcx, key)
48-
}
49-
5046
pub(crate) fn try_load_from_disk(&self, tcx: CTX, index: SerializedDepNodeIndex) -> Option<V> {
51-
(self.try_load_from_disk)(tcx, index)
47+
self.try_load_from_disk
48+
.expect("QueryDescription::load_from_disk() called for an unsupported query.")(
49+
tcx, index,
50+
)
5251
}
5352
}
5453

55-
pub trait QueryAccessors<CTX: QueryContext>: QueryConfig {
56-
const ANON: bool;
57-
const EVAL_ALWAYS: bool;
58-
const DEP_KIND: CTX::DepKind;
59-
const HASH_RESULT: Option<
60-
fn(hcx: &mut StableHashingContext<'_>, result: &Self::Value) -> Fingerprint,
61-
>;
54+
pub trait QueryDescription<CTX: QueryContext>: QueryConfig {
55+
const TRY_LOAD_FROM_DISK: Option<fn(CTX, SerializedDepNodeIndex) -> Option<Self::Value>>;
6256

6357
type Cache: QueryCache<Key = Self::Key, Stored = Self::Stored, Value = Self::Value>;
6458

59+
fn describe(tcx: CTX, key: Self::Key) -> String;
60+
6561
// Don't use this method to access query results, instead use the methods on TyCtxt
6662
fn query_state<'a>(tcx: CTX) -> &'a QueryState<CTX::DepKind, Self::Key>
6763
where
@@ -73,43 +69,7 @@ pub trait QueryAccessors<CTX: QueryContext>: QueryConfig {
7369
CTX: 'a;
7470

7571
// Don't use this method to compute query results, instead use the methods on TyCtxt
76-
fn compute_fn(tcx: CTX, key: &Self::Key) -> fn(CTX::DepContext, Self::Key) -> Self::Value;
77-
78-
fn handle_cycle_error(tcx: CTX, diag: DiagnosticBuilder<'_>) -> Self::Value;
79-
}
80-
81-
pub trait QueryDescription<CTX: QueryContext>: QueryAccessors<CTX> {
82-
fn describe(tcx: CTX, key: Self::Key) -> String;
72+
fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVtable<CTX, Self::Key, Self::Value>;
8373

84-
#[inline]
85-
fn cache_on_disk(_: CTX, _: &Self::Key) -> bool {
86-
false
87-
}
88-
89-
fn try_load_from_disk(_: CTX, _: SerializedDepNodeIndex) -> Option<Self::Value> {
90-
panic!("QueryDescription::load_from_disk() called for an unsupported query.")
91-
}
92-
}
93-
94-
pub(crate) trait QueryVtableExt<CTX: QueryContext, K, V> {
95-
fn make_vtable(tcx: CTX, key: &K) -> QueryVtable<CTX, K, V>;
96-
}
97-
98-
impl<CTX, Q> QueryVtableExt<CTX, Q::Key, Q::Value> for Q
99-
where
100-
CTX: QueryContext,
101-
Q: QueryDescription<CTX>,
102-
{
103-
fn make_vtable(tcx: CTX, key: &Q::Key) -> QueryVtable<CTX, Q::Key, Q::Value> {
104-
QueryVtable {
105-
anon: Q::ANON,
106-
dep_kind: Q::DEP_KIND,
107-
eval_always: Q::EVAL_ALWAYS,
108-
hash_result: Q::HASH_RESULT,
109-
compute: Q::compute_fn(tcx, key),
110-
handle_cycle_error: Q::handle_cycle_error,
111-
cache_on_disk: Q::cache_on_disk,
112-
try_load_from_disk: Q::try_load_from_disk,
113-
}
114-
}
74+
fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool;
11575
}

compiler/rustc_query_system/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub use self::caches::{
1212
};
1313

1414
mod config;
15-
pub use self::config::{QueryAccessors, QueryConfig, QueryDescription};
15+
pub use self::config::{QueryConfig, QueryDescription, QueryVtable};
1616

1717
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
1818

compiler/rustc_query_system/src/query/plumbing.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use crate::dep_graph::{DepContext, DepNode, DepNodeIndex, DepNodeParams};
66
use crate::query::caches::QueryCache;
7-
use crate::query::config::{QueryDescription, QueryVtable, QueryVtableExt};
7+
use crate::query::config::{QueryDescription, QueryVtable};
88
use crate::query::job::{
99
report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId,
1010
};
@@ -512,7 +512,7 @@ where
512512

513513
// First we try to load the result from the on-disk cache.
514514
// Some things are never cached on disk.
515-
if query.cache_on_disk(tcx, key) {
515+
if query.cache_on_disk {
516516
let prof_timer = tcx.dep_context().profiler().incr_cache_loading();
517517
let result = query.try_load_from_disk(tcx, prev_dep_node_index);
518518
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
@@ -713,8 +713,6 @@ where
713713
Q::Key: DepNodeParams<CTX::DepContext>,
714714
CTX: QueryContext,
715715
{
716-
assert!(!Q::ANON);
717-
718716
// We may be concurrently trying both execute and force a query.
719717
// Ensure that only one of them runs the query.
720718
let cache = Q::query_cache(tcx);
@@ -731,5 +729,7 @@ where
731729

732730
let query = Q::make_vtable(tcx, &key);
733731
let state = Q::query_state(tcx);
732+
debug_assert!(!query.anon);
733+
734734
try_execute_query(tcx, state, cache, DUMMY_SP, key, lookup, Some(dep_node), &query);
735735
}

0 commit comments

Comments
 (0)