Skip to content

Commit 8e8116c

Browse files
committed
Auto merge of #108638 - Zoxc:erase-query-values-map, r=cjgillot
Use dynamic dispatch for queries This replaces most concrete query values `V` with `MaybeUninit<[u8; { size_of::<V>() }]>` reducing the code instantiated by queries. The compile time of `rustc_query_impl` is reduced by 27%. It is an alternative to #107937 which uses unstable const generics while this uses a `EraseType` trait which maps query values to their erased variant. This is achieved by introducing an `Erased` type which does sanity check with `cfg(debug_assertions)`. The query caches gets instantiated with these erased types leaving the code in `rustc_query_system` unaware of them. `rustc_query_system` is changed to use instances of `QueryConfig` so that `rustc_query_impl` can pass in `DynamicConfig` which holds a pointer to a virtual table. <table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check</td><td align="right">1.7055s</td><td align="right">1.6949s</td><td align="right"> -0.62%</td></tr><tr><td>🟣 <b>hyper</b>:check</td><td align="right">0.2547s</td><td align="right">0.2528s</td><td align="right"> -0.73%</td></tr><tr><td>🟣 <b>regex</b>:check</td><td align="right">0.9590s</td><td align="right">0.9553s</td><td align="right"> -0.39%</td></tr><tr><td>🟣 <b>syn</b>:check</td><td align="right">1.5457s</td><td align="right">1.5440s</td><td align="right"> -0.11%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check</td><td align="right">5.9092s</td><td align="right">5.9009s</td><td align="right"> -0.14%</td></tr><tr><td>Total</td><td align="right">10.3741s</td><td align="right">10.3479s</td><td align="right"> -0.25%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9960s</td><td align="right"> -0.40%</td></tr></table> <table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check:initial</td><td align="right">2.0605s</td><td align="right">2.0575s</td><td align="right"> -0.15%</td></tr><tr><td>🟣 <b>hyper</b>:check:initial</td><td align="right">0.3218s</td><td align="right">0.3216s</td><td align="right"> -0.07%</td></tr><tr><td>🟣 <b>regex</b>:check:initial</td><td align="right">1.1848s</td><td align="right">1.1839s</td><td align="right"> -0.07%</td></tr><tr><td>🟣 <b>syn</b>:check:initial</td><td align="right">1.9409s</td><td align="right">1.9376s</td><td align="right"> -0.17%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check:initial</td><td align="right">7.3105s</td><td align="right">7.2928s</td><td align="right"> -0.24%</td></tr><tr><td>Total</td><td align="right">12.8185s</td><td align="right">12.7935s</td><td align="right"> -0.20%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9986s</td><td align="right"> -0.14%</td></tr></table> <table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check:unchanged</td><td align="right">0.4606s</td><td align="right">0.4617s</td><td align="right"> 0.24%</td></tr><tr><td>🟣 <b>hyper</b>:check:unchanged</td><td align="right">0.1335s</td><td align="right">0.1336s</td><td align="right"> 0.08%</td></tr><tr><td>🟣 <b>regex</b>:check:unchanged</td><td align="right">0.3324s</td><td align="right">0.3346s</td><td align="right"> 0.65%</td></tr><tr><td>🟣 <b>syn</b>:check:unchanged</td><td align="right">0.6268s</td><td align="right">0.6307s</td><td align="right"> 0.64%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check:unchanged</td><td align="right">1.8248s</td><td align="right">1.8508s</td><td align="right">💔 1.43%</td></tr><tr><td>Total</td><td align="right">3.3779s</td><td align="right">3.4113s</td><td align="right"> 0.99%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">1.0061s</td><td align="right"> 0.61%</td></tr></table> It's based on #108167. r? `@cjgillot`
2 parents 3603a84 + 7aab1dd commit 8e8116c

File tree

13 files changed

+409
-247
lines changed

13 files changed

+409
-247
lines changed

Cargo.lock

+32-1
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ dependencies = [
854854
"autocfg",
855855
"cfg-if",
856856
"crossbeam-utils",
857-
"memoffset",
857+
"memoffset 0.7.1",
858858
"scopeguard",
859859
]
860860

@@ -1241,6 +1241,16 @@ dependencies = [
12411241
"instant",
12421242
]
12431243

1244+
[[package]]
1245+
name = "field-offset"
1246+
version = "0.3.5"
1247+
source = "registry+https://github.com/rust-lang/crates.io-index"
1248+
checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535"
1249+
dependencies = [
1250+
"memoffset 0.8.0",
1251+
"rustc_version",
1252+
]
1253+
12441254
[[package]]
12451255
name = "filetime"
12461256
version = "0.2.20"
@@ -2188,6 +2198,15 @@ dependencies = [
21882198
"libc",
21892199
]
21902200

2201+
[[package]]
2202+
name = "memoffset"
2203+
version = "0.6.5"
2204+
source = "registry+https://github.com/rust-lang/crates.io-index"
2205+
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
2206+
dependencies = [
2207+
"autocfg",
2208+
]
2209+
21912210
[[package]]
21922211
name = "memoffset"
21932212
version = "0.7.1"
@@ -2197,6 +2216,15 @@ dependencies = [
21972216
"autocfg",
21982217
]
21992218

2219+
[[package]]
2220+
name = "memoffset"
2221+
version = "0.8.0"
2222+
source = "registry+https://github.com/rust-lang/crates.io-index"
2223+
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
2224+
dependencies = [
2225+
"autocfg",
2226+
]
2227+
22002228
[[package]]
22012229
name = "mime"
22022230
version = "0.3.16"
@@ -3782,6 +3810,7 @@ dependencies = [
37823810
"chalk-ir",
37833811
"derive_more",
37843812
"either",
3813+
"field-offset",
37853814
"gsgdt",
37863815
"measureme",
37873816
"polonius-engine",
@@ -3996,7 +4025,9 @@ dependencies = [
39964025
name = "rustc_query_impl"
39974026
version = "0.0.0"
39984027
dependencies = [
4028+
"field-offset",
39994029
"measureme",
4030+
"memoffset 0.6.5",
40004031
"rustc-rayon-core",
40014032
"rustc_ast",
40024033
"rustc_data_structures",

compiler/rustc_interface/src/interface.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
352352
// state if it was responsible for triggering the panic.
353353
let i = ty::tls::with_context_opt(|icx| {
354354
if let Some(icx) = icx {
355-
print_query_stack(QueryCtxt { tcx: icx.tcx }, icx.query, handler, num_frames)
355+
print_query_stack(QueryCtxt::new(icx.tcx), icx.query, handler, num_frames)
356356
} else {
357357
0
358358
}

compiler/rustc_interface/src/passes.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,12 @@ pub fn create_global_ctxt<'tcx>(
700700
hir_arena,
701701
untracked,
702702
dep_graph,
703-
query_result_on_disk_cache,
704703
rustc_query_impl::query_callbacks(arena),
705-
rustc_query_impl::query_system_fns(local_providers, extern_providers),
704+
rustc_query_impl::query_system(
705+
local_providers,
706+
extern_providers,
707+
query_result_on_disk_cache,
708+
),
706709
)
707710
})
708711
})

compiler/rustc_middle/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ chalk-ir = "0.87.0"
1111
derive_more = "0.99.17"
1212
either = "1.5.0"
1313
gsgdt = "0.1.2"
14+
field-offset = "0.3.5"
1415
measureme = "10.0.0"
1516
polonius-engine = "0.13.0"
1617
rustc_apfloat = { path = "../rustc_apfloat" }

compiler/rustc_middle/src/ty/context.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ use crate::middle::resolve_bound_vars;
1414
use crate::middle::stability;
1515
use crate::mir::interpret::{self, Allocation, ConstAllocation};
1616
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
17-
use crate::query::on_disk_cache::OnDiskCache;
1817
use crate::query::LocalCrate;
1918
use crate::thir::Thir;
2019
use crate::traits;
2120
use crate::traits::solve;
2221
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
2322
use crate::ty::query::QuerySystem;
24-
use crate::ty::query::QuerySystemFns;
2523
use crate::ty::query::{self, TyCtxtAt};
2624
use crate::ty::{
2725
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
@@ -653,9 +651,8 @@ impl<'tcx> TyCtxt<'tcx> {
653651
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
654652
untracked: Untracked,
655653
dep_graph: DepGraph,
656-
on_disk_cache: Option<OnDiskCache<'tcx>>,
657654
query_kinds: &'tcx [DepKindStruct<'tcx>],
658-
query_system_fns: QuerySystemFns<'tcx>,
655+
query_system: QuerySystem<'tcx>,
659656
) -> GlobalCtxt<'tcx> {
660657
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
661658
s.emit_fatal(err);
@@ -677,7 +674,7 @@ impl<'tcx> TyCtxt<'tcx> {
677674
lifetimes: common_lifetimes,
678675
consts: common_consts,
679676
untracked,
680-
query_system: QuerySystem::new(query_system_fns, on_disk_cache),
677+
query_system,
681678
query_kinds,
682679
ty_rcache: Default::default(),
683680
pred_rcache: Default::default(),

compiler/rustc_middle/src/ty/query.rs

+36-24
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use crate::ty::subst::{GenericArg, SubstsRef};
4343
use crate::ty::util::AlwaysRequiresDrop;
4444
use crate::ty::GeneratorDiagnosticData;
4545
use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams};
46+
use field_offset::FieldOffset;
4647
use measureme::StringId;
4748
use rustc_arena::TypedArena;
4849
use rustc_ast as ast;
@@ -66,9 +67,12 @@ use rustc_hir::hir_id::OwnerId;
6667
use rustc_hir::lang_items::{LangItem, LanguageItems};
6768
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
6869
use rustc_index::IndexVec;
70+
use rustc_query_system::dep_graph::DepNodeIndex;
71+
use rustc_query_system::dep_graph::SerializedDepNodeIndex;
6972
use rustc_query_system::ich::StableHashingContext;
7073
pub(crate) use rustc_query_system::query::QueryJobId;
7174
use rustc_query_system::query::*;
75+
use rustc_query_system::HandleCycleError;
7276
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
7377
use rustc_session::cstore::{CrateDepKind, CrateSource};
7478
use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
@@ -78,8 +82,6 @@ use rustc_span::symbol::Symbol;
7882
use rustc_span::{Span, DUMMY_SP};
7983
use rustc_target::abi;
8084
use rustc_target::spec::PanicStrategy;
81-
82-
use std::marker::PhantomData;
8385
use std::mem;
8486
use std::ops::Deref;
8587
use std::path::PathBuf;
@@ -103,6 +105,31 @@ pub struct QueryStruct<'tcx> {
103105
Option<fn(TyCtxt<'tcx>, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>,
104106
}
105107

108+
pub struct DynamicQuery<'tcx, C: QueryCache> {
109+
pub name: &'static str,
110+
pub eval_always: bool,
111+
pub dep_kind: rustc_middle::dep_graph::DepKind,
112+
pub handle_cycle_error: HandleCycleError,
113+
pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key, crate::dep_graph::DepKind>>,
114+
pub query_cache: FieldOffset<QueryCaches<'tcx>, C>,
115+
pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
116+
pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
117+
pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
118+
pub can_load_from_disk: bool,
119+
pub try_load_from_disk: fn(
120+
tcx: TyCtxt<'tcx>,
121+
key: &C::Key,
122+
prev_index: SerializedDepNodeIndex,
123+
index: DepNodeIndex,
124+
) -> Option<C::Value>,
125+
pub loadable_from_disk:
126+
fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
127+
pub hash_result: HashResult<C::Value>,
128+
pub value_from_cycle_error:
129+
fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<crate::dep_graph::DepKind>]) -> C::Value,
130+
pub format_value: fn(&C::Value) -> String,
131+
}
132+
106133
pub struct QuerySystemFns<'tcx> {
107134
pub engine: QueryEngine,
108135
pub local_providers: Providers,
@@ -120,6 +147,7 @@ pub struct QuerySystem<'tcx> {
120147
pub states: QueryStates<'tcx>,
121148
pub arenas: QueryArenas<'tcx>,
122149
pub caches: QueryCaches<'tcx>,
150+
pub dynamic_queries: DynamicQueries<'tcx>,
123151

124152
/// This provides access to the incremental compilation on-disk cache for query results.
125153
/// Do not access this directly. It is only meant to be used by
@@ -130,23 +158,6 @@ pub struct QuerySystem<'tcx> {
130158
pub fns: QuerySystemFns<'tcx>,
131159

132160
pub jobs: AtomicU64,
133-
134-
// Since we erase query value types we tell the typesystem about them with `PhantomData`.
135-
_phantom_values: QueryPhantomValues<'tcx>,
136-
}
137-
138-
impl<'tcx> QuerySystem<'tcx> {
139-
pub fn new(fns: QuerySystemFns<'tcx>, on_disk_cache: Option<OnDiskCache<'tcx>>) -> Self {
140-
QuerySystem {
141-
states: Default::default(),
142-
arenas: Default::default(),
143-
caches: Default::default(),
144-
on_disk_cache,
145-
fns,
146-
jobs: AtomicU64::new(1),
147-
_phantom_values: Default::default(),
148-
}
149-
}
150161
}
151162

152163
#[derive(Copy, Clone)]
@@ -427,11 +438,6 @@ macro_rules! define_callbacks {
427438
}
428439
}
429440

430-
#[derive(Default)]
431-
pub struct QueryPhantomValues<'tcx> {
432-
$($(#[$attr])* pub $name: PhantomData<query_values::$name<'tcx>>,)*
433-
}
434-
435441
#[derive(Default)]
436442
pub struct QueryCaches<'tcx> {
437443
$($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
@@ -490,6 +496,12 @@ macro_rules! define_callbacks {
490496
})*
491497
}
492498

499+
pub struct DynamicQueries<'tcx> {
500+
$(
501+
pub $name: DynamicQuery<'tcx, query_storage::$name<'tcx>>,
502+
)*
503+
}
504+
493505
#[derive(Default)]
494506
pub struct QueryStates<'tcx> {
495507
$(

compiler/rustc_query_impl/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ edition = "2021"
77

88

99
[dependencies]
10+
memoffset = { version = "0.6.0", features = ["unstable_const"] }
11+
field-offset = "0.3.5"
1012
measureme = "10.0.0"
1113
rustc_ast = { path = "../rustc_ast" }
1214
rustc_data_structures = { path = "../rustc_data_structures" }

0 commit comments

Comments
 (0)