Rename trait QueryConfig to QueryDispatcher
This commit is contained in:
parent
89d7695040
commit
2c9175d73d
5 changed files with 82 additions and 55 deletions
|
|
@ -21,7 +21,7 @@ use rustc_query_system::Value;
|
|||
use rustc_query_system::dep_graph::SerializedDepNodeIndex;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_query_system::query::{
|
||||
CycleError, CycleErrorHandling, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode,
|
||||
CycleError, CycleErrorHandling, HashResult, QueryCache, QueryDispatcher, QueryMap, QueryMode,
|
||||
QueryStackDeferred, QueryState, get_query_incr, get_query_non_incr,
|
||||
};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
|
@ -36,7 +36,13 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all};
|
|||
mod profiling_support;
|
||||
pub use self::profiling_support::alloc_self_profile_query_strings;
|
||||
|
||||
struct DynamicConfig<
|
||||
/// Combines a [`QueryVTable`] with some additional compile-time booleans
|
||||
/// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`].
|
||||
///
|
||||
/// Baking these boolean flags into the type gives a modest but measurable
|
||||
/// improvement to compiler perf and compiler code size; see
|
||||
/// <https://github.com/rust-lang/rust/pull/151633>.
|
||||
struct SemiDynamicQueryDispatcher<
|
||||
'tcx,
|
||||
C: QueryCache,
|
||||
const ANON: bool,
|
||||
|
|
@ -46,20 +52,23 @@ struct DynamicConfig<
|
|||
vtable: &'tcx QueryVTable<'tcx, C>,
|
||||
}
|
||||
|
||||
// Manually implement Copy/Clone, because deriving would put trait bounds on the cache type.
|
||||
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy
|
||||
for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
{
|
||||
}
|
||||
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone
|
||||
for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
// This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`.
|
||||
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool>
|
||||
QueryConfig<QueryCtxt<'tcx>> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
QueryDispatcher<QueryCtxt<'tcx>>
|
||||
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
|
||||
where
|
||||
for<'a> C::Key: HashStable<StableHashingContext<'a>>,
|
||||
{
|
||||
|
|
@ -193,17 +202,28 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// This is implemented per query. It allows restoring query values from their erased state
|
||||
/// and constructing a QueryConfig.
|
||||
trait QueryConfigRestored<'tcx> {
|
||||
type RestoredValue;
|
||||
type Config: QueryConfig<QueryCtxt<'tcx>>;
|
||||
/// Provides access to vtable-like operations for a query
|
||||
/// (by creating a [`QueryDispatcher`]),
|
||||
/// but also keeps track of the "unerased" value type of the query
|
||||
/// (i.e. the actual result type in the query declaration).
|
||||
///
|
||||
/// This trait allows some per-query code to be defined in generic functions
|
||||
/// with a trait bound, instead of having to be defined inline within a macro
|
||||
/// expansion.
|
||||
///
|
||||
/// There is one macro-generated implementation of this trait for each query,
|
||||
/// on the type `rustc_query_impl::query_impl::$name::QueryType`.
|
||||
trait QueryDispatcherUnerased<'tcx> {
|
||||
type UnerasedValue;
|
||||
type Dispatcher: QueryDispatcher<QueryCtxt<'tcx>>;
|
||||
|
||||
const NAME: &'static &'static str;
|
||||
|
||||
fn config(tcx: TyCtxt<'tcx>) -> Self::Config;
|
||||
fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value)
|
||||
-> Self::RestoredValue;
|
||||
fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher;
|
||||
|
||||
fn restore_val(
|
||||
value: <Self::Dispatcher as QueryDispatcher<QueryCtxt<'tcx>>>::Value,
|
||||
) -> Self::UnerasedValue;
|
||||
}
|
||||
|
||||
pub fn query_system<'a>(
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||
use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_query_system::query::{
|
||||
QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect,
|
||||
QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect,
|
||||
QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, force_query,
|
||||
};
|
||||
use rustc_query_system::{QueryOverflow, QueryOverflowNote};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
|
||||
use crate::QueryConfigRestored;
|
||||
use crate::QueryDispatcherUnerased;
|
||||
|
||||
/// Implements [`QueryContext`] for use by [`rustc_query_system`], since that
|
||||
/// crate does not have direct access to [`TyCtxt`].
|
||||
|
|
@ -387,13 +387,13 @@ pub(crate) fn create_query_frame<
|
|||
}
|
||||
|
||||
pub(crate) fn encode_query_results<'a, 'tcx, Q>(
|
||||
query: Q::Config,
|
||||
query: Q::Dispatcher,
|
||||
qcx: QueryCtxt<'tcx>,
|
||||
encoder: &mut CacheEncoder<'a, 'tcx>,
|
||||
query_result_index: &mut EncodedDepNodeIndex,
|
||||
) where
|
||||
Q: super::QueryConfigRestored<'tcx>,
|
||||
Q::RestoredValue: Encodable<CacheEncoder<'a, 'tcx>>,
|
||||
Q: QueryDispatcherUnerased<'tcx>,
|
||||
Q::UnerasedValue: Encodable<CacheEncoder<'a, 'tcx>>,
|
||||
{
|
||||
let _timer = qcx.tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name());
|
||||
|
||||
|
|
@ -408,13 +408,13 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>(
|
|||
|
||||
// Encode the type check tables with the `SerializedDepNodeIndex`
|
||||
// as tag.
|
||||
encoder.encode_tagged(dep_node, &Q::restore(*value));
|
||||
encoder.encode_tagged(dep_node, &Q::restore_val(*value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn query_key_hash_verify<'tcx>(
|
||||
query: impl QueryConfig<QueryCtxt<'tcx>>,
|
||||
query: impl QueryDispatcher<QueryCtxt<'tcx>>,
|
||||
qcx: QueryCtxt<'tcx>,
|
||||
) {
|
||||
let _timer = qcx.tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name());
|
||||
|
|
@ -442,7 +442,7 @@ pub(crate) fn query_key_hash_verify<'tcx>(
|
|||
|
||||
fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode)
|
||||
where
|
||||
Q: QueryConfig<QueryCtxt<'tcx>>,
|
||||
Q: QueryDispatcher<QueryCtxt<'tcx>>,
|
||||
{
|
||||
debug_assert!(tcx.dep_graph.is_green(&dep_node));
|
||||
|
||||
|
|
@ -488,7 +488,7 @@ where
|
|||
|
||||
fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
|
||||
where
|
||||
Q: QueryConfig<QueryCtxt<'tcx>>,
|
||||
Q: QueryDispatcher<QueryCtxt<'tcx>>,
|
||||
{
|
||||
// We must avoid ever having to call `force_from_dep_node()` for a
|
||||
// `DepNode::codegen_unit`:
|
||||
|
|
@ -521,9 +521,10 @@ pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>(
|
|||
is_eval_always: bool,
|
||||
) -> DepKindVTable<'tcx>
|
||||
where
|
||||
Q: QueryConfigRestored<'tcx>,
|
||||
Q: QueryDispatcherUnerased<'tcx>,
|
||||
{
|
||||
let fingerprint_style = <Q::Config as QueryConfig<QueryCtxt<'tcx>>>::Key::fingerprint_style();
|
||||
let fingerprint_style =
|
||||
<Q::Dispatcher as QueryDispatcher<QueryCtxt<'tcx>>>::Key::fingerprint_style();
|
||||
|
||||
if is_anon || !fingerprint_style.reconstructible() {
|
||||
return DepKindVTable {
|
||||
|
|
@ -541,10 +542,10 @@ where
|
|||
is_eval_always,
|
||||
fingerprint_style,
|
||||
force_from_dep_node: Some(|tcx, dep_node, _| {
|
||||
force_from_dep_node(Q::config(tcx), tcx, dep_node)
|
||||
force_from_dep_node(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
try_load_from_on_disk_cache: Some(|tcx, dep_node| {
|
||||
try_load_from_on_disk_cache(Q::config(tcx), tcx, dep_node)
|
||||
try_load_from_on_disk_cache(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
name: Q::NAME,
|
||||
}
|
||||
|
|
@ -613,7 +614,7 @@ macro_rules! define_queries {
|
|||
#[cfg(debug_assertions)]
|
||||
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
|
||||
get_query_incr(
|
||||
QueryType::config(tcx),
|
||||
QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
span,
|
||||
key,
|
||||
|
|
@ -633,7 +634,7 @@ macro_rules! define_queries {
|
|||
__mode: QueryMode,
|
||||
) -> Option<Erase<queries::$name::Value<'tcx>>> {
|
||||
Some(get_query_non_incr(
|
||||
QueryType::config(tcx),
|
||||
QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
span,
|
||||
key,
|
||||
|
|
@ -710,9 +711,9 @@ macro_rules! define_queries {
|
|||
data: PhantomData<&'tcx ()>
|
||||
}
|
||||
|
||||
impl<'tcx> QueryConfigRestored<'tcx> for QueryType<'tcx> {
|
||||
type RestoredValue = queries::$name::Value<'tcx>;
|
||||
type Config = DynamicConfig<
|
||||
impl<'tcx> QueryDispatcherUnerased<'tcx> for QueryType<'tcx> {
|
||||
type UnerasedValue = queries::$name::Value<'tcx>;
|
||||
type Dispatcher = SemiDynamicQueryDispatcher<
|
||||
'tcx,
|
||||
queries::$name::Storage<'tcx>,
|
||||
{ is_anon!([$($modifiers)*]) },
|
||||
|
|
@ -723,14 +724,14 @@ macro_rules! define_queries {
|
|||
const NAME: &'static &'static str = &stringify!($name);
|
||||
|
||||
#[inline(always)]
|
||||
fn config(tcx: TyCtxt<'tcx>) -> Self::Config {
|
||||
DynamicConfig {
|
||||
fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher {
|
||||
SemiDynamicQueryDispatcher {
|
||||
vtable: &tcx.query_system.query_vtables.$name,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue {
|
||||
fn restore_val(value: <Self::Dispatcher as QueryDispatcher<QueryCtxt<'tcx>>>::Value) -> Self::UnerasedValue {
|
||||
restore::<queries::$name::Value<'tcx>>(value)
|
||||
}
|
||||
}
|
||||
|
|
@ -782,7 +783,7 @@ macro_rules! define_queries {
|
|||
query_result_index: &mut EncodedDepNodeIndex
|
||||
) {
|
||||
$crate::plumbing::encode_query_results::<query_impl::$name::QueryType<'tcx>>(
|
||||
query_impl::$name::QueryType::config(tcx),
|
||||
query_impl::$name::QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
encoder,
|
||||
query_result_index,
|
||||
|
|
@ -792,7 +793,7 @@ macro_rules! define_queries {
|
|||
|
||||
pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||
$crate::plumbing::query_key_hash_verify(
|
||||
query_impl::$name::QueryType::config(tcx),
|
||||
query_impl::$name::QueryType::query_dispatcher(tcx),
|
||||
QueryCtxt::new(tcx),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
//! Query configuration and description traits.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
|
|
@ -14,7 +12,15 @@ use crate::query::{CycleError, CycleErrorHandling, DepNodeIndex, QueryContext, Q
|
|||
|
||||
pub type HashResult<V> = Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>;
|
||||
|
||||
pub trait QueryConfig<Qcx: QueryContext>: Copy {
|
||||
/// Trait that can be used as a vtable for a single query, providing operations
|
||||
/// and metadata for that query.
|
||||
///
|
||||
/// Implemented by `rustc_query_impl::SemiDynamicQueryDispatcher`, which
|
||||
/// mostly delegates to `rustc_middle::query::plumbing::QueryVTable`.
|
||||
/// Those types are not visible from this `rustc_query_system` crate.
|
||||
///
|
||||
/// "Dispatcher" should be understood as a near-synonym of "vtable".
|
||||
pub trait QueryDispatcher<Qcx: QueryContext>: Copy {
|
||||
fn name(self) -> &'static str;
|
||||
|
||||
// `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap,
|
||||
|
|
@ -13,7 +13,7 @@ use rustc_span::Span;
|
|||
use rustc_span::def_id::DefId;
|
||||
|
||||
pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache};
|
||||
pub use self::config::{HashResult, QueryConfig};
|
||||
pub use self::dispatcher::{HashResult, QueryDispatcher};
|
||||
pub use self::job::{
|
||||
QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack,
|
||||
report_cycle,
|
||||
|
|
@ -22,7 +22,7 @@ pub use self::plumbing::*;
|
|||
use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
|
||||
|
||||
mod caches;
|
||||
mod config;
|
||||
mod dispatcher;
|
||||
mod job;
|
||||
mod plumbing;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use rustc_errors::{Diag, FatalError, StashKey};
|
|||
use rustc_span::{DUMMY_SP, Span};
|
||||
use tracing::instrument;
|
||||
|
||||
use super::{QueryConfig, QueryStackFrameExtra};
|
||||
use super::{QueryDispatcher, QueryStackFrameExtra};
|
||||
use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::query::caches::QueryCache;
|
||||
|
|
@ -126,7 +126,7 @@ where
|
|||
#[inline(never)]
|
||||
fn mk_cycle<Q, Qcx>(query: Q, qcx: Qcx, cycle_error: CycleError) -> Q::Value
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
let error = report_cycle(qcx.dep_context().sess(), &cycle_error);
|
||||
|
|
@ -140,7 +140,7 @@ fn handle_cycle_error<Q, Qcx>(
|
|||
error: Diag<'_>,
|
||||
) -> Q::Value
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
match query.cycle_error_handling() {
|
||||
|
|
@ -279,7 +279,7 @@ fn cycle_error<Q, Qcx>(
|
|||
span: Span,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// Ensure there was no errors collecting all active jobs.
|
||||
|
|
@ -300,7 +300,7 @@ fn wait_for_query<Q, Qcx>(
|
|||
current: Option<QueryJobId>,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// For parallel queries, we'll block and wait until the query running
|
||||
|
|
@ -349,7 +349,7 @@ fn try_execute_query<Q, Qcx, const INCR: bool>(
|
|||
dep_node: Option<DepNode>,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
let state = query.query_state(qcx);
|
||||
|
|
@ -421,7 +421,7 @@ fn execute_job<Q, Qcx, const INCR: bool>(
|
|||
dep_node: Option<DepNode>,
|
||||
) -> (Q::Value, Option<DepNodeIndex>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// Use `JobOwner` so the query will be poisoned if executing it panics.
|
||||
|
|
@ -491,7 +491,7 @@ fn execute_job_non_incr<Q, Qcx>(
|
|||
job_id: QueryJobId,
|
||||
) -> (Q::Value, DepNodeIndex)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled());
|
||||
|
|
@ -530,7 +530,7 @@ fn execute_job_incr<Q, Qcx>(
|
|||
job_id: QueryJobId,
|
||||
) -> (Q::Value, DepNodeIndex)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
if !query.anon() && !query.eval_always() {
|
||||
|
|
@ -585,7 +585,7 @@ fn try_load_from_disk_and_cache_in_memory<Q, Qcx>(
|
|||
dep_node: &DepNode,
|
||||
) -> Option<(Q::Value, DepNodeIndex)>
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// Note this function can be called concurrently from the same query
|
||||
|
|
@ -771,7 +771,7 @@ fn ensure_must_run<Q, Qcx>(
|
|||
check_cache: bool,
|
||||
) -> (bool, Option<DepNode>)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
if query.eval_always() {
|
||||
|
|
@ -819,7 +819,7 @@ pub enum QueryMode {
|
|||
#[inline(always)]
|
||||
pub fn get_query_non_incr<Q, Qcx>(query: Q, qcx: Qcx, span: Span, key: Q::Key) -> Q::Value
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled());
|
||||
|
|
@ -836,7 +836,7 @@ pub fn get_query_incr<Q, Qcx>(
|
|||
mode: QueryMode,
|
||||
) -> Option<Q::Value>
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled());
|
||||
|
|
@ -862,7 +862,7 @@ where
|
|||
|
||||
pub fn force_query<Q, Qcx>(query: Q, qcx: Qcx, key: Q::Key, dep_node: DepNode)
|
||||
where
|
||||
Q: QueryConfig<Qcx>,
|
||||
Q: QueryDispatcher<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
// We may be concurrently trying both execute and force a query.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue