Skip to content

Commit

Permalink
Auto merge of rust-lang#108638 - Zoxc:erase-query-values-map, r=cjgillot
Browse files Browse the repository at this point in the history
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 rust-lang#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 rust-lang#108167.

r? `@cjgillot`
  • Loading branch information
bors committed May 14, 2023
2 parents 3603a84 + 7aab1dd commit 8e8116c
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 247 deletions.
33 changes: 32 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"memoffset 0.7.1",
"scopeguard",
]

Expand Down Expand Up @@ -1241,6 +1241,16 @@ dependencies = [
"instant",
]

[[package]]
name = "field-offset"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535"
dependencies = [
"memoffset 0.8.0",
"rustc_version",
]

[[package]]
name = "filetime"
version = "0.2.20"
Expand Down Expand Up @@ -2188,6 +2198,15 @@ dependencies = [
"libc",
]

[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]

[[package]]
name = "memoffset"
version = "0.7.1"
Expand All @@ -2197,6 +2216,15 @@ dependencies = [
"autocfg",
]

[[package]]
name = "memoffset"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
"autocfg",
]

[[package]]
name = "mime"
version = "0.3.16"
Expand Down Expand Up @@ -3782,6 +3810,7 @@ dependencies = [
"chalk-ir",
"derive_more",
"either",
"field-offset",
"gsgdt",
"measureme",
"polonius-engine",
Expand Down Expand Up @@ -3996,7 +4025,9 @@ dependencies = [
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
"field-offset",
"measureme",
"memoffset 0.6.5",
"rustc-rayon-core",
"rustc_ast",
"rustc_data_structures",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
// state if it was responsible for triggering the panic.
let i = ty::tls::with_context_opt(|icx| {
if let Some(icx) = icx {
print_query_stack(QueryCtxt { tcx: icx.tcx }, icx.query, handler, num_frames)
print_query_stack(QueryCtxt::new(icx.tcx), icx.query, handler, num_frames)
} else {
0
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,12 @@ pub fn create_global_ctxt<'tcx>(
hir_arena,
untracked,
dep_graph,
query_result_on_disk_cache,
rustc_query_impl::query_callbacks(arena),
rustc_query_impl::query_system_fns(local_providers, extern_providers),
rustc_query_impl::query_system(
local_providers,
extern_providers,
query_result_on_disk_cache,
),
)
})
})
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ chalk-ir = "0.87.0"
derive_more = "0.99.17"
either = "1.5.0"
gsgdt = "0.1.2"
field-offset = "0.3.5"
measureme = "10.0.0"
polonius-engine = "0.13.0"
rustc_apfloat = { path = "../rustc_apfloat" }
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ use crate::middle::resolve_bound_vars;
use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstAllocation};
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::query::on_disk_cache::OnDiskCache;
use crate::query::LocalCrate;
use crate::thir::Thir;
use crate::traits;
use crate::traits::solve;
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
use crate::ty::query::QuerySystem;
use crate::ty::query::QuerySystemFns;
use crate::ty::query::{self, TyCtxtAt};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
Expand Down Expand Up @@ -653,9 +651,8 @@ impl<'tcx> TyCtxt<'tcx> {
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
untracked: Untracked,
dep_graph: DepGraph,
on_disk_cache: Option<OnDiskCache<'tcx>>,
query_kinds: &'tcx [DepKindStruct<'tcx>],
query_system_fns: QuerySystemFns<'tcx>,
query_system: QuerySystem<'tcx>,
) -> GlobalCtxt<'tcx> {
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
s.emit_fatal(err);
Expand All @@ -677,7 +674,7 @@ impl<'tcx> TyCtxt<'tcx> {
lifetimes: common_lifetimes,
consts: common_consts,
untracked,
query_system: QuerySystem::new(query_system_fns, on_disk_cache),
query_system,
query_kinds,
ty_rcache: Default::default(),
pred_rcache: Default::default(),
Expand Down
60 changes: 36 additions & 24 deletions compiler/rustc_middle/src/ty/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::GeneratorDiagnosticData;
use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams};
use field_offset::FieldOffset;
use measureme::StringId;
use rustc_arena::TypedArena;
use rustc_ast as ast;
Expand All @@ -66,9 +67,12 @@ use rustc_hir::hir_id::OwnerId;
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::IndexVec;
use rustc_query_system::dep_graph::DepNodeIndex;
use rustc_query_system::dep_graph::SerializedDepNodeIndex;
use rustc_query_system::ich::StableHashingContext;
pub(crate) use rustc_query_system::query::QueryJobId;
use rustc_query_system::query::*;
use rustc_query_system::HandleCycleError;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::cstore::{CrateDepKind, CrateSource};
use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
Expand All @@ -78,8 +82,6 @@ use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi;
use rustc_target::spec::PanicStrategy;

use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::path::PathBuf;
Expand All @@ -103,6 +105,31 @@ pub struct QueryStruct<'tcx> {
Option<fn(TyCtxt<'tcx>, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>,
}

pub struct DynamicQuery<'tcx, C: QueryCache> {
pub name: &'static str,
pub eval_always: bool,
pub dep_kind: rustc_middle::dep_graph::DepKind,
pub handle_cycle_error: HandleCycleError,
pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key, crate::dep_graph::DepKind>>,
pub query_cache: FieldOffset<QueryCaches<'tcx>, C>,
pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool,
pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value,
pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value,
pub can_load_from_disk: bool,
pub try_load_from_disk: fn(
tcx: TyCtxt<'tcx>,
key: &C::Key,
prev_index: SerializedDepNodeIndex,
index: DepNodeIndex,
) -> Option<C::Value>,
pub loadable_from_disk:
fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
pub hash_result: HashResult<C::Value>,
pub value_from_cycle_error:
fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<crate::dep_graph::DepKind>]) -> C::Value,
pub format_value: fn(&C::Value) -> String,
}

pub struct QuerySystemFns<'tcx> {
pub engine: QueryEngine,
pub local_providers: Providers,
Expand All @@ -120,6 +147,7 @@ pub struct QuerySystem<'tcx> {
pub states: QueryStates<'tcx>,
pub arenas: QueryArenas<'tcx>,
pub caches: QueryCaches<'tcx>,
pub dynamic_queries: DynamicQueries<'tcx>,

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

pub jobs: AtomicU64,

// Since we erase query value types we tell the typesystem about them with `PhantomData`.
_phantom_values: QueryPhantomValues<'tcx>,
}

impl<'tcx> QuerySystem<'tcx> {
pub fn new(fns: QuerySystemFns<'tcx>, on_disk_cache: Option<OnDiskCache<'tcx>>) -> Self {
QuerySystem {
states: Default::default(),
arenas: Default::default(),
caches: Default::default(),
on_disk_cache,
fns,
jobs: AtomicU64::new(1),
_phantom_values: Default::default(),
}
}
}

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -427,11 +438,6 @@ macro_rules! define_callbacks {
}
}

#[derive(Default)]
pub struct QueryPhantomValues<'tcx> {
$($(#[$attr])* pub $name: PhantomData<query_values::$name<'tcx>>,)*
}

#[derive(Default)]
pub struct QueryCaches<'tcx> {
$($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
Expand Down Expand Up @@ -490,6 +496,12 @@ macro_rules! define_callbacks {
})*
}

pub struct DynamicQueries<'tcx> {
$(
pub $name: DynamicQuery<'tcx, query_storage::$name<'tcx>>,
)*
}

#[derive(Default)]
pub struct QueryStates<'tcx> {
$(
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_query_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"


[dependencies]
memoffset = { version = "0.6.0", features = ["unstable_const"] }
field-offset = "0.3.5"
measureme = "10.0.0"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
Expand Down
Loading

0 comments on commit 8e8116c

Please sign in to comment.