From 0bf5cae489e828a6678cab5144e638ae909d7b93 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 21:36:09 +0100 Subject: [PATCH 01/17] Remove __query_compute module. --- src/librustc/ty/query/plumbing.rs | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index acf67f52dcea..bfae0075c8d0 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -951,16 +951,6 @@ macro_rules! define_queries_inner { })* } - // This module and the functions in it exist only to provide a - // predictable symbol name prefix for query providers. This is helpful - // for analyzing queries in profilers. - pub(super) mod __query_compute { - $(#[inline(never)] - pub fn $name R, R>(f: F) -> R { - f() - })* - } - $(impl<$tcx> QueryConfig<$tcx> for queries::$name<$tcx> { type Key = $K; type Value = $V; @@ -997,16 +987,14 @@ macro_rules! define_queries_inner { #[inline] fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { - __query_compute::$name(move || { - let provider = tcx.queries.providers.get(key.query_crate()) - // HACK(eddyb) it's possible crates may be loaded after - // the query engine is created, and because crate loading - // is not yet integrated with the query engine, such crates - // would be missing appropriate entries in `providers`. - .unwrap_or(&tcx.queries.fallback_extern_providers) - .$name; - provider(tcx, key) - }) + let provider = tcx.queries.providers.get(key.query_crate()) + // HACK(eddyb) it's possible crates may be loaded after + // the query engine is created, and because crate loading + // is not yet integrated with the query engine, such crates + // would be missing appropriate entries in `providers`. + .unwrap_or(&tcx.queries.fallback_extern_providers) + .$name; + provider(tcx, key) } fn hash_result( From fc82376bc437d4494832b171d924e2f116174578 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 00:43:17 +0100 Subject: [PATCH 02/17] Make QueryAccessor::dep_kind an associated const. --- src/librustc/ty/query/config.rs | 3 +-- src/librustc/ty/query/plumbing.rs | 14 +++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 178c2362def6..5a05acc90e43 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -28,6 +28,7 @@ pub trait QueryConfig<'tcx> { pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { const ANON: bool; const EVAL_ALWAYS: bool; + const DEP_KIND: DepKind; type Cache: QueryCache; @@ -38,8 +39,6 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode; - fn dep_kind() -> DepKind; - // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index bfae0075c8d0..603c4fd9b72c 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -154,7 +154,7 @@ impl<'tcx, Q: QueryDescription<'tcx>> JobOwner<'tcx, Q> { }; // Create the id of the job we're waiting for - let id = QueryJobId::new(job.id, lookup.shard, Q::dep_kind()); + let id = QueryJobId::new(job.id, lookup.shard, Q::DEP_KIND); (job.latch(id), _query_blocked_prof_timer) } @@ -169,7 +169,7 @@ impl<'tcx, Q: QueryDescription<'tcx>> JobOwner<'tcx, Q> { lock.jobs = id; let id = QueryShardJobId(NonZeroU32::new(id).unwrap()); - let global_id = QueryJobId::new(id, lookup.shard, Q::dep_kind()); + let global_id = QueryJobId::new(id, lookup.shard, Q::DEP_KIND); let job = tls::with_related_context(tcx, |icx| QueryJob::new(id, span, icx.query)); @@ -498,7 +498,7 @@ impl<'tcx> TyCtxt<'tcx> { let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.id, diagnostics, |tcx| { - tcx.dep_graph.with_anon_task(Q::dep_kind(), || Q::compute(tcx, key)) + tcx.dep_graph.with_anon_task(Q::DEP_KIND, || Q::compute(tcx, key)) }) }); @@ -873,7 +873,7 @@ macro_rules! define_queries_inner { job: job.id, shard: u16::try_from(shard_id).unwrap(), kind: - as QueryAccessors<'tcx>>::dep_kind(), + as QueryAccessors<'tcx>>::DEP_KIND, }; let info = QueryInfo { span: job.span, @@ -961,6 +961,7 @@ macro_rules! define_queries_inner { impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> { const ANON: bool = is_anon!([$($modifiers)*]); const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]); + const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$node; type Cache = query_storage!([$($modifiers)*][$K, $V]); @@ -980,11 +981,6 @@ macro_rules! define_queries_inner { DepConstructor::$node(tcx, *key) } - #[inline(always)] - fn dep_kind() -> dep_graph::DepKind { - dep_graph::DepKind::$node - } - #[inline] fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { let provider = tcx.queries.providers.get(key.query_crate()) From cf238fd057651371731fde47a2ebf251bf37cfb5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 01:01:01 +0100 Subject: [PATCH 03/17] Inline QueryAccessor::query. --- src/librustc/ty/query/config.rs | 4 +--- src/librustc/ty/query/plumbing.rs | 7 +------ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 5a05acc90e43..29b9e0c3b40e 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -2,7 +2,7 @@ use crate::dep_graph::SerializedDepNodeIndex; use crate::dep_graph::{DepKind, DepNode}; use crate::ty::query::caches::QueryCache; use crate::ty::query::plumbing::CycleError; -use crate::ty::query::{Query, QueryState}; +use crate::ty::query::QueryState; use crate::ty::TyCtxt; use rustc_data_structures::profiling::ProfileCategory; use rustc_hir::def_id::DefId; @@ -32,8 +32,6 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { type Cache: QueryCache; - fn query(key: Self::Key) -> Query<'tcx>; - // Don't use this method to access query results, instead use the methods on TyCtxt fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 603c4fd9b72c..32138b3e1d5f 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -877,7 +877,7 @@ macro_rules! define_queries_inner { }; let info = QueryInfo { span: job.span, - query: queries::$name::query(k.clone()) + query: Query::$name(k.clone()) }; Some((id, QueryJobInfo { info, job: job.clone() })) } else { @@ -965,11 +965,6 @@ macro_rules! define_queries_inner { type Cache = query_storage!([$($modifiers)*][$K, $V]); - #[inline(always)] - fn query(key: Self::Key) -> Query<'tcx> { - Query::$name(key) - } - #[inline(always)] fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<$tcx, Self> { &tcx.queries.$name From 1249032aabe3a0a80c0a852ef803702d7fb70d21 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 17:10:31 +0100 Subject: [PATCH 04/17] Move impl of Queries with its definition. --- src/librustc/ty/query/plumbing.rs | 98 +++++++++++++++---------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 32138b3e1d5f..5532d7e08cc9 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -842,55 +842,6 @@ macro_rules! define_queries_inner { input: ($(([$($modifiers)*] [$($attr)*] [$name]))*) } - impl<$tcx> Queries<$tcx> { - pub fn new( - providers: IndexVec>, - fallback_extern_providers: Providers<$tcx>, - on_disk_cache: OnDiskCache<'tcx>, - ) -> Self { - Queries { - providers, - fallback_extern_providers: Box::new(fallback_extern_providers), - on_disk_cache, - $($name: Default::default()),* - } - } - - pub fn try_collect_active_jobs( - &self - ) -> Option>> { - let mut jobs = FxHashMap::default(); - - $( - // We use try_lock_shards here since we are called from the - // deadlock handler, and this shouldn't be locked. - let shards = self.$name.shards.try_lock_shards()?; - let shards = shards.iter().enumerate(); - jobs.extend(shards.flat_map(|(shard_id, shard)| { - shard.active.iter().filter_map(move |(k, v)| { - if let QueryResult::Started(ref job) = *v { - let id = QueryJobId { - job: job.id, - shard: u16::try_from(shard_id).unwrap(), - kind: - as QueryAccessors<'tcx>>::DEP_KIND, - }; - let info = QueryInfo { - span: job.span, - query: Query::$name(k.clone()) - }; - Some((id, QueryJobInfo { info, job: job.clone() })) - } else { - None - } - }) - })); - )* - - Some(jobs) - } - } - #[allow(nonstandard_style)] #[derive(Clone, Debug)] pub enum Query<$tcx> { @@ -1120,6 +1071,55 @@ macro_rules! define_queries_struct { $($(#[$attr])* $name: QueryState<$tcx, queries::$name<$tcx>>,)* } + + impl<$tcx> Queries<$tcx> { + pub fn new( + providers: IndexVec>, + fallback_extern_providers: Providers<$tcx>, + on_disk_cache: OnDiskCache<'tcx>, + ) -> Self { + Queries { + providers, + fallback_extern_providers: Box::new(fallback_extern_providers), + on_disk_cache, + $($name: Default::default()),* + } + } + + pub fn try_collect_active_jobs( + &self + ) -> Option>> { + let mut jobs = FxHashMap::default(); + + $( + // We use try_lock_shards here since we are called from the + // deadlock handler, and this shouldn't be locked. + let shards = self.$name.shards.try_lock_shards()?; + let shards = shards.iter().enumerate(); + jobs.extend(shards.flat_map(|(shard_id, shard)| { + shard.active.iter().filter_map(move |(k, v)| { + if let QueryResult::Started(ref job) = *v { + let id = QueryJobId { + job: job.id, + shard: u16::try_from(shard_id).unwrap(), + kind: + as QueryAccessors<'tcx>>::DEP_KIND, + }; + let info = QueryInfo { + span: job.span, + query: Query::$name(k.clone()) + }; + Some((id, QueryJobInfo { info, job: job.clone() })) + } else { + None + } + }) + })); + )* + + Some(jobs) + } + } }; } From b08943358ec8adc2d8e542659c7dcd2514311918 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 18:36:11 +0100 Subject: [PATCH 05/17] Unpack type arguments for QueryStateShard. --- src/librustc/ty/query/plumbing.rs | 35 ++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 5532d7e08cc9..b688365b2bb9 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -4,7 +4,7 @@ use crate::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex}; use crate::ty::query::caches::QueryCache; -use crate::ty::query::config::{QueryAccessors, QueryDescription}; +use crate::ty::query::config::{QueryAccessors, QueryConfig, QueryDescription}; use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryShardJobId}; use crate::ty::query::Query; use crate::ty::tls; @@ -27,25 +27,32 @@ use std::ptr; #[cfg(debug_assertions)] use std::sync::atomic::{AtomicUsize, Ordering}; -pub(crate) struct QueryStateShard<'tcx, D: QueryAccessors<'tcx> + ?Sized> { - pub(super) cache: <>::Cache as QueryCache>::Sharded, - pub(super) active: FxHashMap>, +pub(crate) type QueryStateShard<'tcx, Q> = QueryStateShardImpl< + 'tcx, + >::Key, + <>::Cache as QueryCache< + >::Key, + >::Value, + >>::Sharded, +>; + +pub(crate) struct QueryStateShardImpl<'tcx, K, C> { + pub(super) cache: C, + pub(super) active: FxHashMap>, /// Used to generate unique ids for active jobs. pub(super) jobs: u32, } -impl<'tcx, Q: QueryAccessors<'tcx>> QueryStateShard<'tcx, Q> { - fn get_cache( - &mut self, - ) -> &mut <>::Cache as QueryCache>::Sharded { +impl<'tcx, K, C> QueryStateShardImpl<'tcx, K, C> { + fn get_cache(&mut self) -> &mut C { &mut self.cache } } -impl<'tcx, Q: QueryAccessors<'tcx>> Default for QueryStateShard<'tcx, Q> { - fn default() -> QueryStateShard<'tcx, Q> { - QueryStateShard { cache: Default::default(), active: Default::default(), jobs: 0 } +impl<'tcx, K, C: Default> Default for QueryStateShardImpl<'tcx, K, C> { + fn default() -> QueryStateShardImpl<'tcx, K, C> { + QueryStateShardImpl { cache: Default::default(), active: Default::default(), jobs: 0 } } } @@ -122,7 +129,7 @@ pub(super) struct JobOwner<'tcx, Q: QueryDescription<'tcx>> { id: QueryJobId, } -impl<'tcx, Q: QueryDescription<'tcx>> JobOwner<'tcx, Q> { +impl<'tcx, Q: QueryDescription<'tcx> + 'tcx> JobOwner<'tcx, Q> { /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or returns with the result of the query. /// This function assumes that `try_get_cached` is already called and returned `lookup`. @@ -470,7 +477,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline(always)] - pub(super) fn try_execute_query>( + pub(super) fn try_execute_query + 'tcx>( self, span: Span, key: Q::Key, @@ -634,7 +641,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline(always)] - fn force_query_with_job>( + fn force_query_with_job + 'tcx>( self, key: Q::Key, job: JobOwner<'tcx, Q>, From 486a082c58c60959328e0b394f9e58850b3c6341 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 19:54:19 +0100 Subject: [PATCH 06/17] Unpack type arguments for QueryLookup. --- src/librustc/ty/query/plumbing.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index b688365b2bb9..67f0fdfcd548 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -74,7 +74,7 @@ impl<'tcx, Q: QueryAccessors<'tcx>> QueryState<'tcx, Q> { let shard = self.shards.get_shard_index_by_hash(key_hash); let lock = self.shards.get_shard_by_index(shard).lock(); - QueryLookup { key_hash, shard, lock } + QueryLookupImpl { key_hash, shard, lock } } } @@ -115,10 +115,11 @@ impl<'tcx, M: QueryAccessors<'tcx>> Default for QueryState<'tcx, M> { } /// Values used when checking a query cache which can be reused on a cache-miss to execute the query. -pub(crate) struct QueryLookup<'tcx, Q: QueryAccessors<'tcx>> { +pub(crate) type QueryLookup<'tcx, Q> = QueryLookupImpl<'tcx, QueryStateShard<'tcx, Q>>; +pub(crate) struct QueryLookupImpl<'tcx, QSS> { pub(super) key_hash: u64, pub(super) shard: usize, - pub(super) lock: LockGuard<'tcx, QueryStateShard<'tcx, Q>>, + pub(super) lock: LockGuard<'tcx, QSS>, } /// A type representing the responsibility to execute the job in the `job` field. From a0f57e24e35a365d9d55f37611edfc6666b5d3c9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 20:05:05 +0100 Subject: [PATCH 07/17] Unpack type arguments for QueryState. --- src/librustc/ty/query/plumbing.rs | 38 +++++++++++++++++++------------ 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 67f0fdfcd548..37fc339ee639 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -56,15 +56,25 @@ impl<'tcx, K, C: Default> Default for QueryStateShardImpl<'tcx, K, C> { } } -pub(crate) struct QueryState<'tcx, D: QueryAccessors<'tcx> + ?Sized> { - pub(super) cache: D::Cache, - pub(super) shards: Sharded>, +pub(crate) type QueryState<'tcx, Q> = QueryStateImpl< + 'tcx, + >::Key, + >::Value, + >::Cache, +>; + +pub(crate) struct QueryStateImpl<'tcx, K, V, C: QueryCache> { + pub(super) cache: C, + pub(super) shards: Sharded>, #[cfg(debug_assertions)] pub(super) cache_hits: AtomicUsize, } -impl<'tcx, Q: QueryAccessors<'tcx>> QueryState<'tcx, Q> { - pub(super) fn get_lookup(&'tcx self, key: &K) -> QueryLookup<'tcx, Q> { +impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { + pub(super) fn get_lookup( + &'tcx self, + key: &K2, + ) -> QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, C::Sharded>> { // We compute the key's hash once and then use it for both the // shard lookup and the hashmap lookup. This relies on the fact // that both of them use `FxHasher`. @@ -88,12 +98,10 @@ pub(super) enum QueryResult<'tcx> { Poisoned, } -impl<'tcx, M: QueryAccessors<'tcx>> QueryState<'tcx, M> { +impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { pub fn iter_results( &self, - f: impl for<'a> FnOnce( - Box + 'a>, - ) -> R, + f: impl for<'a> FnOnce(Box + 'a>) -> R, ) -> R { self.cache.iter(&self.shards, |shard| &mut shard.cache, f) } @@ -103,10 +111,10 @@ impl<'tcx, M: QueryAccessors<'tcx>> QueryState<'tcx, M> { } } -impl<'tcx, M: QueryAccessors<'tcx>> Default for QueryState<'tcx, M> { - fn default() -> QueryState<'tcx, M> { - QueryState { - cache: M::Cache::default(), +impl<'tcx, K, V, C: QueryCache> Default for QueryStateImpl<'tcx, K, V, C> { + fn default() -> QueryStateImpl<'tcx, K, V, C> { + QueryStateImpl { + cache: C::default(), shards: Default::default(), #[cfg(debug_assertions)] cache_hits: AtomicUsize::new(0), @@ -441,7 +449,7 @@ impl<'tcx> TyCtxt<'tcx> { { let state = Q::query_state(self); - state.cache.lookup( + state.cache.lookup::<_, _, _, _, Q>( state, QueryStateShard::::get_cache, key, @@ -1035,7 +1043,7 @@ macro_rules! define_queries_inner { let mut string_cache = QueryKeyStringCache::new(); $({ - alloc_self_profile_query_strings_for_query_cache( + alloc_self_profile_query_strings_for_query_cache::>( self, stringify!($name), &self.queries.$name, From fa02dca428314676716c78b5aa1953eea1627bf0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 20:10:53 +0100 Subject: [PATCH 08/17] Remove Q parameter from QueryCache::lookup. --- src/librustc/ty/query/caches.rs | 25 +++++++++++++------------ src/librustc/ty/query/plumbing.rs | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/librustc/ty/query/caches.rs b/src/librustc/ty/query/caches.rs index efc2804bd4d5..ae01dcb364bf 100644 --- a/src/librustc/ty/query/caches.rs +++ b/src/librustc/ty/query/caches.rs @@ -1,6 +1,5 @@ use crate::dep_graph::DepNodeIndex; -use crate::ty::query::config::QueryAccessors; -use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard}; +use crate::ty::query::plumbing::{QueryLookupImpl, QueryStateImpl, QueryStateShardImpl}; use crate::ty::TyCtxt; use rustc_data_structures::fx::FxHashMap; @@ -19,9 +18,9 @@ pub(crate) trait QueryCache: Default { /// It returns the shard index and a lock guard to the shard, /// which will be used if the query is not in the cache and we need /// to compute it. - fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>( + fn lookup<'tcx, R, GetCache, OnHit, OnMiss>( &self, - state: &'tcx QueryState<'tcx, Q>, + state: &'tcx QueryStateImpl<'tcx, K, V, Self>, get_cache: GetCache, key: K, // `on_hit` can be called while holding a lock to the query state shard. @@ -29,10 +28,11 @@ pub(crate) trait QueryCache: Default { on_miss: OnMiss, ) -> R where - Q: QueryAccessors<'tcx>, - GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded, + GetCache: for<'a> Fn( + &'a mut QueryStateShardImpl<'tcx, K, Self::Sharded>, + ) -> &'a mut Self::Sharded, OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R; + OnMiss: FnOnce(K, QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, Self::Sharded>>) -> R; fn complete( &self, @@ -64,19 +64,20 @@ impl QueryCache for DefaultCache { type Sharded = FxHashMap; #[inline(always)] - fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>( + fn lookup<'tcx, R, GetCache, OnHit, OnMiss>( &self, - state: &'tcx QueryState<'tcx, Q>, + state: &'tcx QueryStateImpl<'tcx, K, V, Self>, get_cache: GetCache, key: K, on_hit: OnHit, on_miss: OnMiss, ) -> R where - Q: QueryAccessors<'tcx>, - GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded, + GetCache: for<'a> Fn( + &'a mut QueryStateShardImpl<'tcx, K, Self::Sharded>, + ) -> &'a mut Self::Sharded, OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R, + OnMiss: FnOnce(K, QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, Self::Sharded>>) -> R, { let mut lookup = state.get_lookup(&key); let lock = &mut *lookup.lock; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 37fc339ee639..e4d0e96d07c7 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -449,7 +449,7 @@ impl<'tcx> TyCtxt<'tcx> { { let state = Q::query_state(self); - state.cache.lookup::<_, _, _, _, Q>( + state.cache.lookup( state, QueryStateShard::::get_cache, key, From a18aa81bd8dd3012e43f195c52b8113a74479056 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 20:17:03 +0100 Subject: [PATCH 09/17] Remove Q parameter from alloc_self_profile_query_strings_for_query_cache. --- src/librustc/ty/query/plumbing.rs | 2 +- src/librustc/ty/query/profiling_support.rs | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e4d0e96d07c7..98d8de89d8e9 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1043,7 +1043,7 @@ macro_rules! define_queries_inner { let mut string_cache = QueryKeyStringCache::new(); $({ - alloc_self_profile_query_strings_for_query_cache::>( + alloc_self_profile_query_strings_for_query_cache( self, stringify!($name), &self.queries.$name, diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index 99ada34d59eb..290e37f2cf82 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -1,7 +1,7 @@ use crate::hir::map::definitions::DefPathData; use crate::ty::context::TyCtxt; -use crate::ty::query::config::QueryAccessors; -use crate::ty::query::plumbing::QueryState; +use crate::ty::query::caches::QueryCache; +use crate::ty::query::plumbing::QueryStateImpl; use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; @@ -157,13 +157,14 @@ where /// Allocate the self-profiling query strings for a single query cache. This /// method is called from `alloc_self_profile_query_strings` which knows all /// the queries via macro magic. -pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>( +pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, K, V, C>( tcx: TyCtxt<'tcx>, query_name: &'static str, - query_state: &QueryState<'tcx, Q>, + query_state: &QueryStateImpl<'tcx, K, V, C>, string_cache: &mut QueryKeyStringCache, ) where - Q: QueryAccessors<'tcx>, + K: Debug + Clone, + C: QueryCache, { tcx.prof.with_profiler(|profiler| { let event_id_builder = profiler.event_id_builder(); From d125bbb12b9b1839068706834d350acf5a91244c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 6 Mar 2020 20:33:13 +0100 Subject: [PATCH 10/17] Remove Q parameter from query stats. --- src/librustc/ty/query/stats.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/librustc/ty/query/stats.rs b/src/librustc/ty/query/stats.rs index d257320d4eaf..c4c81cd5a13c 100644 --- a/src/librustc/ty/query/stats.rs +++ b/src/librustc/ty/query/stats.rs @@ -1,5 +1,6 @@ -use crate::ty::query::config::QueryAccessors; -use crate::ty::query::plumbing::QueryState; +use crate::ty::query::caches::QueryCache; +use crate::ty::query::config::{QueryAccessors, QueryConfig}; +use crate::ty::query::plumbing::QueryStateImpl; use crate::ty::query::queries; use crate::ty::TyCtxt; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -37,9 +38,9 @@ struct QueryStats { local_def_id_keys: Option, } -fn stats<'tcx, Q: QueryAccessors<'tcx>>( +fn stats<'tcx, K, V, C: QueryCache>( name: &'static str, - map: &QueryState<'tcx, Q>, + map: &QueryStateImpl<'tcx, K, V, C>, ) -> QueryStats { let mut stats = QueryStats { name, @@ -47,10 +48,10 @@ fn stats<'tcx, Q: QueryAccessors<'tcx>>( cache_hits: map.cache_hits.load(Ordering::Relaxed), #[cfg(not(debug_assertions))] cache_hits: 0, - key_size: mem::size_of::(), - key_type: type_name::(), - value_size: mem::size_of::(), - value_type: type_name::(), + key_size: mem::size_of::(), + key_type: type_name::(), + value_size: mem::size_of::(), + value_type: type_name::(), entry_count: map.iter_results(|results| results.count()), local_def_id_keys: None, }; @@ -125,7 +126,11 @@ macro_rules! print_stats { let mut queries = Vec::new(); $($( - queries.push(stats::>( + queries.push(stats::< + as QueryConfig<'_>>::Key, + as QueryConfig<'_>>::Value, + as QueryAccessors<'_>>::Cache, + >( stringify!($name), &tcx.queries.$name, )); From fa0794db239d588b5822233d32fa7aa82bd17069 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 10:38:44 +0100 Subject: [PATCH 11/17] Remove Q parameter from JobOwner. --- src/librustc/ty/query/plumbing.rs | 61 ++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 98d8de89d8e9..9228e569f558 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -20,6 +20,7 @@ use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, H use rustc_span::source_map::DUMMY_SP; use rustc_span::Span; use std::collections::hash_map::Entry; +use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::mem; use std::num::NonZeroU32; @@ -132,13 +133,28 @@ pub(crate) struct QueryLookupImpl<'tcx, QSS> { /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. -pub(super) struct JobOwner<'tcx, Q: QueryDescription<'tcx>> { - tcx: TyCtxt<'tcx>, - key: Q::Key, +pub(super) type JobOwner<'tcx, Q> = JobOwnerImpl< + 'tcx, + >::Key, + >::Value, + >::Cache, +>; + +pub(super) struct JobOwnerImpl<'tcx, K, V, C: QueryCache> +where + K: Eq + Hash + Clone + Debug, + V: Clone, +{ + state: &'tcx QueryStateImpl<'tcx, K, V, C>, + key: K, id: QueryJobId, } -impl<'tcx, Q: QueryDescription<'tcx> + 'tcx> JobOwner<'tcx, Q> { +impl<'tcx, K, V, C: QueryCache> JobOwnerImpl<'tcx, K, V, C> +where + K: Eq + Hash + Clone + Debug, + V: Clone, +{ /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or returns with the result of the query. /// This function assumes that `try_get_cached` is already called and returned `lookup`. @@ -148,12 +164,17 @@ impl<'tcx, Q: QueryDescription<'tcx> + 'tcx> JobOwner<'tcx, Q> { /// This function is inlined because that results in a noticeable speed-up /// for some compile-time benchmarks. #[inline(always)] - pub(super) fn try_start( + pub(super) fn try_start( tcx: TyCtxt<'tcx>, span: Span, - key: &Q::Key, + key: &K, mut lookup: QueryLookup<'tcx, Q>, - ) -> TryGetJob<'tcx, Q> { + ) -> TryGetJob<'tcx, Q> + where + K: Eq + Hash + Clone + Debug, + V: Clone, + Q: QueryDescription<'tcx, Key = K, Value = V, Cache = C> + 'tcx, + { let lock = &mut *lookup.lock; let (latch, mut _query_blocked_prof_timer) = match lock.active.entry((*key).clone()) { @@ -191,7 +212,8 @@ impl<'tcx, Q: QueryDescription<'tcx> + 'tcx> JobOwner<'tcx, Q> { entry.insert(QueryResult::Started(job)); - let owner = JobOwner { tcx, id: global_id, key: (*key).clone() }; + let owner = + JobOwnerImpl { state: Q::query_state(tcx), id: global_id, key: (*key).clone() }; return TryGetJob::NotYetStarted(owner); } }; @@ -231,16 +253,15 @@ impl<'tcx, Q: QueryDescription<'tcx> + 'tcx> JobOwner<'tcx, Q> { /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query #[inline(always)] - pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) { + pub(super) fn complete(self, tcx: TyCtxt<'tcx>, result: &V, dep_node_index: DepNodeIndex) { // We can move out of `self` here because we `mem::forget` it below let key = unsafe { ptr::read(&self.key) }; - let tcx = self.tcx; + let state = self.state; // Forget ourself so our destructor won't poison the query mem::forget(self); let job = { - let state = Q::query_state(tcx); let result = result.clone(); let mut lock = state.shards.get_shard_by_value(&key).lock(); let job = match lock.active.remove(&key).unwrap() { @@ -265,12 +286,16 @@ where (result, diagnostics.into_inner()) } -impl<'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'tcx, Q> { +impl<'tcx, K, V, C: QueryCache> Drop for JobOwnerImpl<'tcx, K, V, C> +where + K: Eq + Hash + Clone + Debug, + V: Clone, +{ #[inline(never)] #[cold] fn drop(&mut self) { // Poison the query so jobs waiting on it panic. - let state = Q::query_state(self.tcx); + let state = self.state; let shard = state.shards.get_shard_by_value(&self.key); let job = { let mut shard = shard.lock(); @@ -492,7 +517,7 @@ impl<'tcx> TyCtxt<'tcx> { key: Q::Key, lookup: QueryLookup<'tcx, Q>, ) -> Q::Value { - let job = match JobOwner::try_start(self, span, &key, lookup) { + let job = match JobOwnerImpl::try_start::(self, span, &key, lookup) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(result) => return result, #[cfg(parallel_compiler)] @@ -528,7 +553,7 @@ impl<'tcx> TyCtxt<'tcx> { .store_diagnostics_for_anon_node(dep_node_index, diagnostics); } - job.complete(&result, dep_node_index); + job.complete(self, &result, dep_node_index); return result; } @@ -554,7 +579,7 @@ impl<'tcx> TyCtxt<'tcx> { }) }); if let Some((result, dep_node_index)) = loaded { - job.complete(&result, dep_node_index); + job.complete(self, &result, dep_node_index); return result; } } @@ -696,7 +721,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - job.complete(&result, dep_node_index); + job.complete(self, &result, dep_node_index); (result, dep_node_index) } @@ -751,7 +776,7 @@ impl<'tcx> TyCtxt<'tcx> { // Cache hit, do nothing }, |key, lookup| { - let job = match JobOwner::try_start(self, span, &key, lookup) { + let job = match JobOwnerImpl::try_start::(self, span, &key, lookup) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(_) => return, #[cfg(parallel_compiler)] From 5dc7c2ed1aab0c6b0bfb15b4fb5a4d079d3aaa36 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 17:19:47 +0100 Subject: [PATCH 12/17] Remove Q parameter from try_get_cached. --- src/librustc/ty/query/plumbing.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 9228e569f558..1ff7e44bfbb9 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -236,7 +236,8 @@ where return TryGetJob::Cycle(Q::handle_cycle_error(tcx, cycle)); } - let cached = tcx.try_get_cached::( + let cached = tcx.try_get_cached( + Q::query_state(tcx), (*key).clone(), |value, index| (value.clone(), index), |_, _| panic!("value must be in cache after waiting"), @@ -460,23 +461,22 @@ impl<'tcx> TyCtxt<'tcx> { /// which will be used if the query is not in the cache and we need /// to compute it. #[inline(always)] - fn try_get_cached( + fn try_get_cached( self, - key: Q::Key, + state: &'tcx QueryStateImpl<'tcx, K, V, C>, + key: K, // `on_hit` can be called while holding a lock to the query cache on_hit: OnHit, on_miss: OnMiss, ) -> R where - Q: QueryDescription<'tcx> + 'tcx, - OnHit: FnOnce(&Q::Value, DepNodeIndex) -> R, - OnMiss: FnOnce(Q::Key, QueryLookup<'tcx, Q>) -> R, + C: QueryCache, + OnHit: FnOnce(&V, DepNodeIndex) -> R, + OnMiss: FnOnce(K, QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, C::Sharded>>) -> R, { - let state = Q::query_state(self); - state.cache.lookup( state, - QueryStateShard::::get_cache, + QueryStateShardImpl::::get_cache, key, |value, index| { if unlikely!(self.prof.enabled()) { @@ -500,7 +500,8 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Q::Value { debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME, key, span); - self.try_get_cached::( + self.try_get_cached( + Q::query_state(self), key, |value, index| { self.dep_graph.read_index(index); @@ -770,7 +771,8 @@ impl<'tcx> TyCtxt<'tcx> { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. - self.try_get_cached::( + self.try_get_cached( + Q::query_state(self), key, |_, _| { // Cache hit, do nothing From 7d84f4fb169d55b0423e4e379828700ec0214400 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 11:03:49 +0100 Subject: [PATCH 13/17] Offload try_collect_active_jobs. --- src/librustc/ty/query/mod.rs | 1 - src/librustc/ty/query/plumbing.rs | 62 ++++++++++++++++++------------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 3d17883fec3b..54e80b4dc0b1 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -57,7 +57,6 @@ use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; use std::borrow::Cow; use std::collections::BTreeMap; -use std::convert::TryFrom; use std::ops::Deref; use std::sync::Arc; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 1ff7e44bfbb9..406ca18b5910 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -2,10 +2,10 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex}; +use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; use crate::ty::query::caches::QueryCache; use crate::ty::query::config::{QueryAccessors, QueryConfig, QueryDescription}; -use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryShardJobId}; +use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId}; use crate::ty::query::Query; use crate::ty::tls; use crate::ty::{self, TyCtxt}; @@ -20,6 +20,7 @@ use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, H use rustc_span::source_map::DUMMY_SP; use rustc_span::Span; use std::collections::hash_map::Entry; +use std::convert::TryFrom; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::mem; @@ -110,6 +111,35 @@ impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { let shards = self.shards.lock_shards(); shards.iter().all(|shard| shard.active.is_empty()) } + + pub(super) fn try_collect_active_jobs( + &self, + kind: DepKind, + make_query: fn(K) -> Query<'tcx>, + jobs: &mut FxHashMap>, + ) -> Option<()> + where + K: Clone, + { + // We use try_lock_shards here since we are called from the + // deadlock handler, and this shouldn't be locked. + let shards = self.shards.try_lock_shards()?; + let shards = shards.iter().enumerate(); + jobs.extend(shards.flat_map(|(shard_id, shard)| { + shard.active.iter().filter_map(move |(k, v)| { + if let QueryResult::Started(ref job) = *v { + let id = + QueryJobId { job: job.id, shard: u16::try_from(shard_id).unwrap(), kind }; + let info = QueryInfo { span: job.span, query: make_query(k.clone()) }; + Some((id, QueryJobInfo { info, job: job.clone() })) + } else { + None + } + }) + })); + + Some(()) + } } impl<'tcx, K, V, C: QueryCache> Default for QueryStateImpl<'tcx, K, V, C> { @@ -1135,29 +1165,11 @@ macro_rules! define_queries_struct { let mut jobs = FxHashMap::default(); $( - // We use try_lock_shards here since we are called from the - // deadlock handler, and this shouldn't be locked. - let shards = self.$name.shards.try_lock_shards()?; - let shards = shards.iter().enumerate(); - jobs.extend(shards.flat_map(|(shard_id, shard)| { - shard.active.iter().filter_map(move |(k, v)| { - if let QueryResult::Started(ref job) = *v { - let id = QueryJobId { - job: job.id, - shard: u16::try_from(shard_id).unwrap(), - kind: - as QueryAccessors<'tcx>>::DEP_KIND, - }; - let info = QueryInfo { - span: job.span, - query: Query::$name(k.clone()) - }; - Some((id, QueryJobInfo { info, job: job.clone() })) - } else { - None - } - }) - })); + self.$name.try_collect_active_jobs( + as QueryAccessors<'tcx>>::DEP_KIND, + Query::$name, + &mut jobs, + )?; )* Some(jobs) From 7309b3cd8be928a0ec9e3219d9562ddeb54ff994 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 17:56:59 +0100 Subject: [PATCH 14/17] Simplify type aliases. --- src/librustc/ty/query/caches.rs | 16 ++++++------ src/librustc/ty/query/plumbing.rs | 41 +++++++++++-------------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/librustc/ty/query/caches.rs b/src/librustc/ty/query/caches.rs index ae01dcb364bf..17639545d12a 100644 --- a/src/librustc/ty/query/caches.rs +++ b/src/librustc/ty/query/caches.rs @@ -1,5 +1,5 @@ use crate::dep_graph::DepNodeIndex; -use crate::ty::query::plumbing::{QueryLookupImpl, QueryStateImpl, QueryStateShardImpl}; +use crate::ty::query::plumbing::{QueryLookup, QueryStateImpl, QueryStateShard}; use crate::ty::TyCtxt; use rustc_data_structures::fx::FxHashMap; @@ -28,11 +28,10 @@ pub(crate) trait QueryCache: Default { on_miss: OnMiss, ) -> R where - GetCache: for<'a> Fn( - &'a mut QueryStateShardImpl<'tcx, K, Self::Sharded>, - ) -> &'a mut Self::Sharded, + GetCache: + for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded, OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, Self::Sharded>>) -> R; + OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R; fn complete( &self, @@ -73,11 +72,10 @@ impl QueryCache for DefaultCache { on_miss: OnMiss, ) -> R where - GetCache: for<'a> Fn( - &'a mut QueryStateShardImpl<'tcx, K, Self::Sharded>, - ) -> &'a mut Self::Sharded, + GetCache: + for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded, OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, Self::Sharded>>) -> R, + OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R, { let mut lookup = state.get_lookup(&key); let lock = &mut *lookup.lock; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 406ca18b5910..467b1a7e4a17 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -29,16 +29,7 @@ use std::ptr; #[cfg(debug_assertions)] use std::sync::atomic::{AtomicUsize, Ordering}; -pub(crate) type QueryStateShard<'tcx, Q> = QueryStateShardImpl< - 'tcx, - >::Key, - <>::Cache as QueryCache< - >::Key, - >::Value, - >>::Sharded, ->; - -pub(crate) struct QueryStateShardImpl<'tcx, K, C> { +pub(crate) struct QueryStateShard<'tcx, K, C> { pub(super) cache: C, pub(super) active: FxHashMap>, @@ -46,15 +37,15 @@ pub(crate) struct QueryStateShardImpl<'tcx, K, C> { pub(super) jobs: u32, } -impl<'tcx, K, C> QueryStateShardImpl<'tcx, K, C> { +impl<'tcx, K, C> QueryStateShard<'tcx, K, C> { fn get_cache(&mut self) -> &mut C { &mut self.cache } } -impl<'tcx, K, C: Default> Default for QueryStateShardImpl<'tcx, K, C> { - fn default() -> QueryStateShardImpl<'tcx, K, C> { - QueryStateShardImpl { cache: Default::default(), active: Default::default(), jobs: 0 } +impl<'tcx, K, C: Default> Default for QueryStateShard<'tcx, K, C> { + fn default() -> QueryStateShard<'tcx, K, C> { + QueryStateShard { cache: Default::default(), active: Default::default(), jobs: 0 } } } @@ -67,16 +58,13 @@ pub(crate) type QueryState<'tcx, Q> = QueryStateImpl< pub(crate) struct QueryStateImpl<'tcx, K, V, C: QueryCache> { pub(super) cache: C, - pub(super) shards: Sharded>, + pub(super) shards: Sharded>, #[cfg(debug_assertions)] pub(super) cache_hits: AtomicUsize, } impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { - pub(super) fn get_lookup( - &'tcx self, - key: &K2, - ) -> QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, C::Sharded>> { + pub(super) fn get_lookup(&'tcx self, key: &K2) -> QueryLookup<'tcx, K, C::Sharded> { // We compute the key's hash once and then use it for both the // shard lookup and the hashmap lookup. This relies on the fact // that both of them use `FxHasher`. @@ -86,7 +74,7 @@ impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { let shard = self.shards.get_shard_index_by_hash(key_hash); let lock = self.shards.get_shard_by_index(shard).lock(); - QueryLookupImpl { key_hash, shard, lock } + QueryLookup { key_hash, shard, lock } } } @@ -154,11 +142,10 @@ impl<'tcx, K, V, C: QueryCache> Default for QueryStateImpl<'tcx, K, V, C> } /// Values used when checking a query cache which can be reused on a cache-miss to execute the query. -pub(crate) type QueryLookup<'tcx, Q> = QueryLookupImpl<'tcx, QueryStateShard<'tcx, Q>>; -pub(crate) struct QueryLookupImpl<'tcx, QSS> { +pub(crate) struct QueryLookup<'tcx, K, C> { pub(super) key_hash: u64, pub(super) shard: usize, - pub(super) lock: LockGuard<'tcx, QSS>, + pub(super) lock: LockGuard<'tcx, QueryStateShard<'tcx, K, C>>, } /// A type representing the responsibility to execute the job in the `job` field. @@ -198,7 +185,7 @@ where tcx: TyCtxt<'tcx>, span: Span, key: &K, - mut lookup: QueryLookup<'tcx, Q>, + mut lookup: QueryLookup<'tcx, K, C::Sharded>, ) -> TryGetJob<'tcx, Q> where K: Eq + Hash + Clone + Debug, @@ -502,11 +489,11 @@ impl<'tcx> TyCtxt<'tcx> { where C: QueryCache, OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookupImpl<'tcx, QueryStateShardImpl<'tcx, K, C::Sharded>>) -> R, + OnMiss: FnOnce(K, QueryLookup<'tcx, K, C::Sharded>) -> R, { state.cache.lookup( state, - QueryStateShardImpl::::get_cache, + QueryStateShard::::get_cache, key, |value, index| { if unlikely!(self.prof.enabled()) { @@ -546,7 +533,7 @@ impl<'tcx> TyCtxt<'tcx> { self, span: Span, key: Q::Key, - lookup: QueryLookup<'tcx, Q>, + lookup: QueryLookup<'tcx, Q::Key, >::Sharded>, ) -> Q::Value { let job = match JobOwnerImpl::try_start::(self, span, &key, lookup) { TryGetJob::NotYetStarted(job) => job, From 3abd4753b7c9fa9a3855d4b41b557f81b3e06aab Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 18:36:24 +0100 Subject: [PATCH 15/17] Make QueryCache parameters associated types. --- src/librustc/ty/query/caches.rs | 45 +++++--- src/librustc/ty/query/config.rs | 7 +- src/librustc/ty/query/plumbing.rs | 118 +++++++++++---------- src/librustc/ty/query/profiling_support.rs | 8 +- src/librustc/ty/query/stats.rs | 17 ++- 5 files changed, 101 insertions(+), 94 deletions(-) diff --git a/src/librustc/ty/query/caches.rs b/src/librustc/ty/query/caches.rs index 17639545d12a..71523ea39ca3 100644 --- a/src/librustc/ty/query/caches.rs +++ b/src/librustc/ty/query/caches.rs @@ -6,12 +6,15 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::Sharded; use std::default::Default; use std::hash::Hash; +use std::marker::PhantomData; pub(crate) trait CacheSelector { - type Cache: QueryCache; + type Cache: QueryCache; } -pub(crate) trait QueryCache: Default { +pub(crate) trait QueryCache: Default { + type Key; + type Value; type Sharded: Default; /// Checks if the query is already computed and in the cache. @@ -20,25 +23,26 @@ pub(crate) trait QueryCache: Default { /// to compute it. fn lookup<'tcx, R, GetCache, OnHit, OnMiss>( &self, - state: &'tcx QueryStateImpl<'tcx, K, V, Self>, + state: &'tcx QueryStateImpl<'tcx, Self>, get_cache: GetCache, - key: K, + key: Self::Key, // `on_hit` can be called while holding a lock to the query state shard. on_hit: OnHit, on_miss: OnMiss, ) -> R where - GetCache: - for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded, - OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R; + GetCache: for<'a> Fn( + &'a mut QueryStateShard<'tcx, Self::Key, Self::Sharded>, + ) -> &'a mut Self::Sharded, + OnHit: FnOnce(&Self::Value, DepNodeIndex) -> R, + OnMiss: FnOnce(Self::Key, QueryLookup<'tcx, Self::Key, Self::Sharded>) -> R; fn complete( &self, tcx: TyCtxt<'tcx>, lock_sharded_storage: &mut Self::Sharded, - key: K, - value: V, + key: Self::Key, + value: Self::Value, index: DepNodeIndex, ); @@ -46,26 +50,35 @@ pub(crate) trait QueryCache: Default { &self, shards: &Sharded, get_shard: impl Fn(&mut L) -> &mut Self::Sharded, - f: impl for<'a> FnOnce(Box + 'a>) -> R, + f: impl for<'a> FnOnce( + Box + 'a>, + ) -> R, ) -> R; } pub struct DefaultCacheSelector; impl CacheSelector for DefaultCacheSelector { - type Cache = DefaultCache; + type Cache = DefaultCache; } -#[derive(Default)] -pub struct DefaultCache; +pub struct DefaultCache(PhantomData<(K, V)>); + +impl Default for DefaultCache { + fn default() -> Self { + DefaultCache(PhantomData) + } +} -impl QueryCache for DefaultCache { +impl QueryCache for DefaultCache { + type Key = K; + type Value = V; type Sharded = FxHashMap; #[inline(always)] fn lookup<'tcx, R, GetCache, OnHit, OnMiss>( &self, - state: &'tcx QueryStateImpl<'tcx, K, V, Self>, + state: &'tcx QueryStateImpl<'tcx, Self>, get_cache: GetCache, key: K, on_hit: OnHit, diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 29b9e0c3b40e..5b0653bd599e 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -30,7 +30,7 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { const EVAL_ALWAYS: bool; const DEP_KIND: DepKind; - type Cache: QueryCache; + type Cache: QueryCache; // Don't use this method to access query results, instead use the methods on TyCtxt fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>; @@ -59,10 +59,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { } } -impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M -where - >::Cache: QueryCache>::Value>, -{ +impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M { default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> { if !tcx.sess.verbose() { format!("processing `{}`", tcx.def_path_str(def_id)).into() diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 467b1a7e4a17..c2740733977e 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -4,7 +4,7 @@ use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; use crate::ty::query::caches::QueryCache; -use crate::ty::query::config::{QueryAccessors, QueryConfig, QueryDescription}; +use crate::ty::query::config::{QueryAccessors, QueryDescription}; use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId}; use crate::ty::query::Query; use crate::ty::tls; @@ -49,22 +49,20 @@ impl<'tcx, K, C: Default> Default for QueryStateShard<'tcx, K, C> { } } -pub(crate) type QueryState<'tcx, Q> = QueryStateImpl< - 'tcx, - >::Key, - >::Value, - >::Cache, ->; +pub(crate) type QueryState<'tcx, Q> = QueryStateImpl<'tcx, >::Cache>; -pub(crate) struct QueryStateImpl<'tcx, K, V, C: QueryCache> { +pub(crate) struct QueryStateImpl<'tcx, C: QueryCache> { pub(super) cache: C, - pub(super) shards: Sharded>, + pub(super) shards: Sharded>, #[cfg(debug_assertions)] pub(super) cache_hits: AtomicUsize, } -impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { - pub(super) fn get_lookup(&'tcx self, key: &K2) -> QueryLookup<'tcx, K, C::Sharded> { +impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> { + pub(super) fn get_lookup( + &'tcx self, + key: &K2, + ) -> QueryLookup<'tcx, C::Key, C::Sharded> { // We compute the key's hash once and then use it for both the // shard lookup and the hashmap lookup. This relies on the fact // that both of them use `FxHasher`. @@ -88,10 +86,12 @@ pub(super) enum QueryResult<'tcx> { Poisoned, } -impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { +impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> { pub fn iter_results( &self, - f: impl for<'a> FnOnce(Box + 'a>) -> R, + f: impl for<'a> FnOnce( + Box + 'a>, + ) -> R, ) -> R { self.cache.iter(&self.shards, |shard| &mut shard.cache, f) } @@ -103,11 +103,11 @@ impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { pub(super) fn try_collect_active_jobs( &self, kind: DepKind, - make_query: fn(K) -> Query<'tcx>, + make_query: fn(C::Key) -> Query<'tcx>, jobs: &mut FxHashMap>, ) -> Option<()> where - K: Clone, + C::Key: Clone, { // We use try_lock_shards here since we are called from the // deadlock handler, and this shouldn't be locked. @@ -130,8 +130,8 @@ impl<'tcx, K, V, C: QueryCache> QueryStateImpl<'tcx, K, V, C> { } } -impl<'tcx, K, V, C: QueryCache> Default for QueryStateImpl<'tcx, K, V, C> { - fn default() -> QueryStateImpl<'tcx, K, V, C> { +impl<'tcx, C: QueryCache> Default for QueryStateImpl<'tcx, C> { + fn default() -> QueryStateImpl<'tcx, C> { QueryStateImpl { cache: C::default(), shards: Default::default(), @@ -150,27 +150,22 @@ pub(crate) struct QueryLookup<'tcx, K, C> { /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. -pub(super) type JobOwner<'tcx, Q> = JobOwnerImpl< - 'tcx, - >::Key, - >::Value, - >::Cache, ->; - -pub(super) struct JobOwnerImpl<'tcx, K, V, C: QueryCache> +pub(super) struct JobOwner<'tcx, C> where - K: Eq + Hash + Clone + Debug, - V: Clone, + C: QueryCache, + C::Key: Eq + Hash + Clone + Debug, + C::Value: Clone, { - state: &'tcx QueryStateImpl<'tcx, K, V, C>, - key: K, + state: &'tcx QueryStateImpl<'tcx, C>, + key: C::Key, id: QueryJobId, } -impl<'tcx, K, V, C: QueryCache> JobOwnerImpl<'tcx, K, V, C> +impl<'tcx, C: QueryCache> JobOwner<'tcx, C> where - K: Eq + Hash + Clone + Debug, - V: Clone, + C: QueryCache, + C::Key: Eq + Hash + Clone + Debug, + C::Value: Clone, { /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or returns with the result of the query. @@ -184,13 +179,11 @@ where pub(super) fn try_start( tcx: TyCtxt<'tcx>, span: Span, - key: &K, - mut lookup: QueryLookup<'tcx, K, C::Sharded>, - ) -> TryGetJob<'tcx, Q> + key: &C::Key, + mut lookup: QueryLookup<'tcx, C::Key, C::Sharded>, + ) -> TryGetJob<'tcx, C> where - K: Eq + Hash + Clone + Debug, - V: Clone, - Q: QueryDescription<'tcx, Key = K, Value = V, Cache = C> + 'tcx, + Q: QueryDescription<'tcx, Key = C::Key, Value = C::Value, Cache = C>, { let lock = &mut *lookup.lock; @@ -230,7 +223,7 @@ where entry.insert(QueryResult::Started(job)); let owner = - JobOwnerImpl { state: Q::query_state(tcx), id: global_id, key: (*key).clone() }; + JobOwner { state: Q::query_state(tcx), id: global_id, key: (*key).clone() }; return TryGetJob::NotYetStarted(owner); } }; @@ -271,7 +264,12 @@ where /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query #[inline(always)] - pub(super) fn complete(self, tcx: TyCtxt<'tcx>, result: &V, dep_node_index: DepNodeIndex) { + pub(super) fn complete( + self, + tcx: TyCtxt<'tcx>, + result: &C::Value, + dep_node_index: DepNodeIndex, + ) { // We can move out of `self` here because we `mem::forget` it below let key = unsafe { ptr::read(&self.key) }; let state = self.state; @@ -304,10 +302,10 @@ where (result, diagnostics.into_inner()) } -impl<'tcx, K, V, C: QueryCache> Drop for JobOwnerImpl<'tcx, K, V, C> +impl<'tcx, C: QueryCache> Drop for JobOwner<'tcx, C> where - K: Eq + Hash + Clone + Debug, - V: Clone, + C::Key: Eq + Hash + Clone + Debug, + C::Value: Clone, { #[inline(never)] #[cold] @@ -338,18 +336,22 @@ pub struct CycleError<'tcx> { } /// The result of `try_start`. -pub(super) enum TryGetJob<'tcx, D: QueryDescription<'tcx>> { +pub(super) enum TryGetJob<'tcx, C: QueryCache> +where + C::Key: Eq + Hash + Clone + Debug, + C::Value: Clone, +{ /// The query is not yet started. Contains a guard to the cache eventually used to start it. - NotYetStarted(JobOwner<'tcx, D>), + NotYetStarted(JobOwner<'tcx, C>), /// The query was already completed. /// Returns the result of the query and its dep-node index /// if it succeeded or a cycle error if it failed. #[cfg(parallel_compiler)] - JobCompleted((D::Value, DepNodeIndex)), + JobCompleted((C::Value, DepNodeIndex)), /// Trying to execute the query resulted in a cycle. - Cycle(D::Value), + Cycle(C::Value), } impl<'tcx> TyCtxt<'tcx> { @@ -478,22 +480,22 @@ impl<'tcx> TyCtxt<'tcx> { /// which will be used if the query is not in the cache and we need /// to compute it. #[inline(always)] - fn try_get_cached( + fn try_get_cached( self, - state: &'tcx QueryStateImpl<'tcx, K, V, C>, - key: K, + state: &'tcx QueryStateImpl<'tcx, C>, + key: C::Key, // `on_hit` can be called while holding a lock to the query cache on_hit: OnHit, on_miss: OnMiss, ) -> R where - C: QueryCache, - OnHit: FnOnce(&V, DepNodeIndex) -> R, - OnMiss: FnOnce(K, QueryLookup<'tcx, K, C::Sharded>) -> R, + C: QueryCache, + OnHit: FnOnce(&C::Value, DepNodeIndex) -> R, + OnMiss: FnOnce(C::Key, QueryLookup<'tcx, C::Key, C::Sharded>) -> R, { state.cache.lookup( state, - QueryStateShard::::get_cache, + QueryStateShard::::get_cache, key, |value, index| { if unlikely!(self.prof.enabled()) { @@ -533,9 +535,9 @@ impl<'tcx> TyCtxt<'tcx> { self, span: Span, key: Q::Key, - lookup: QueryLookup<'tcx, Q::Key, >::Sharded>, + lookup: QueryLookup<'tcx, Q::Key, ::Sharded>, ) -> Q::Value { - let job = match JobOwnerImpl::try_start::(self, span, &key, lookup) { + let job = match JobOwner::try_start::(self, span, &key, lookup) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(result) => return result, #[cfg(parallel_compiler)] @@ -696,7 +698,7 @@ impl<'tcx> TyCtxt<'tcx> { fn force_query_with_job + 'tcx>( self, key: Q::Key, - job: JobOwner<'tcx, Q>, + job: JobOwner<'tcx, Q::Cache>, dep_node: DepNode, ) -> (Q::Value, DepNodeIndex) { // If the following assertion triggers, it can have two reasons: @@ -795,7 +797,7 @@ impl<'tcx> TyCtxt<'tcx> { // Cache hit, do nothing }, |key, lookup| { - let job = match JobOwnerImpl::try_start::(self, span, &key, lookup) { + let job = match JobOwner::try_start::(self, span, &key, lookup) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(_) => return, #[cfg(parallel_compiler)] diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index 290e37f2cf82..256bd86a3de3 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -157,14 +157,14 @@ where /// Allocate the self-profiling query strings for a single query cache. This /// method is called from `alloc_self_profile_query_strings` which knows all /// the queries via macro magic. -pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, K, V, C>( +pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( tcx: TyCtxt<'tcx>, query_name: &'static str, - query_state: &QueryStateImpl<'tcx, K, V, C>, + query_state: &QueryStateImpl<'tcx, C>, string_cache: &mut QueryKeyStringCache, ) where - K: Debug + Clone, - C: QueryCache, + C: QueryCache, + C::Key: Debug + Clone, { tcx.prof.with_profiler(|profiler| { let event_id_builder = profiler.event_id_builder(); diff --git a/src/librustc/ty/query/stats.rs b/src/librustc/ty/query/stats.rs index c4c81cd5a13c..20894a2a5d1e 100644 --- a/src/librustc/ty/query/stats.rs +++ b/src/librustc/ty/query/stats.rs @@ -1,5 +1,5 @@ use crate::ty::query::caches::QueryCache; -use crate::ty::query::config::{QueryAccessors, QueryConfig}; +use crate::ty::query::config::QueryAccessors; use crate::ty::query::plumbing::QueryStateImpl; use crate::ty::query::queries; use crate::ty::TyCtxt; @@ -38,20 +38,17 @@ struct QueryStats { local_def_id_keys: Option, } -fn stats<'tcx, K, V, C: QueryCache>( - name: &'static str, - map: &QueryStateImpl<'tcx, K, V, C>, -) -> QueryStats { +fn stats<'tcx, C: QueryCache>(name: &'static str, map: &QueryStateImpl<'tcx, C>) -> QueryStats { let mut stats = QueryStats { name, #[cfg(debug_assertions)] cache_hits: map.cache_hits.load(Ordering::Relaxed), #[cfg(not(debug_assertions))] cache_hits: 0, - key_size: mem::size_of::(), - key_type: type_name::(), - value_size: mem::size_of::(), - value_type: type_name::(), + key_size: mem::size_of::(), + key_type: type_name::(), + value_size: mem::size_of::(), + value_type: type_name::(), entry_count: map.iter_results(|results| results.count()), local_def_id_keys: None, }; @@ -127,8 +124,6 @@ macro_rules! print_stats { $($( queries.push(stats::< - as QueryConfig<'_>>::Key, - as QueryConfig<'_>>::Value, as QueryAccessors<'_>>::Cache, >( stringify!($name), From 5557407fbb322dc1265ba3c05cd5474a20c2e1d3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 7 Mar 2020 18:45:44 +0100 Subject: [PATCH 16/17] Remove QueryState type alias. --- src/librustc/ty/query/caches.rs | 6 ++--- src/librustc/ty/query/config.rs | 2 +- src/librustc/ty/query/plumbing.rs | 27 +++++++++++----------- src/librustc/ty/query/profiling_support.rs | 4 ++-- src/librustc/ty/query/stats.rs | 4 ++-- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/librustc/ty/query/caches.rs b/src/librustc/ty/query/caches.rs index 71523ea39ca3..a11b3bcba3ed 100644 --- a/src/librustc/ty/query/caches.rs +++ b/src/librustc/ty/query/caches.rs @@ -1,5 +1,5 @@ use crate::dep_graph::DepNodeIndex; -use crate::ty::query::plumbing::{QueryLookup, QueryStateImpl, QueryStateShard}; +use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard}; use crate::ty::TyCtxt; use rustc_data_structures::fx::FxHashMap; @@ -23,7 +23,7 @@ pub(crate) trait QueryCache: Default { /// to compute it. fn lookup<'tcx, R, GetCache, OnHit, OnMiss>( &self, - state: &'tcx QueryStateImpl<'tcx, Self>, + state: &'tcx QueryState<'tcx, Self>, get_cache: GetCache, key: Self::Key, // `on_hit` can be called while holding a lock to the query state shard. @@ -78,7 +78,7 @@ impl QueryCache for DefaultCache { #[inline(always)] fn lookup<'tcx, R, GetCache, OnHit, OnMiss>( &self, - state: &'tcx QueryStateImpl<'tcx, Self>, + state: &'tcx QueryState<'tcx, Self>, get_cache: GetCache, key: K, on_hit: OnHit, diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 5b0653bd599e..72a0fdf15672 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -33,7 +33,7 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { type Cache: QueryCache; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>; + fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self::Cache>; fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c2740733977e..442b3edcafe0 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -4,7 +4,7 @@ use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; use crate::ty::query::caches::QueryCache; -use crate::ty::query::config::{QueryAccessors, QueryDescription}; +use crate::ty::query::config::QueryDescription; use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId}; use crate::ty::query::Query; use crate::ty::tls; @@ -49,16 +49,14 @@ impl<'tcx, K, C: Default> Default for QueryStateShard<'tcx, K, C> { } } -pub(crate) type QueryState<'tcx, Q> = QueryStateImpl<'tcx, >::Cache>; - -pub(crate) struct QueryStateImpl<'tcx, C: QueryCache> { +pub(crate) struct QueryState<'tcx, C: QueryCache> { pub(super) cache: C, pub(super) shards: Sharded>, #[cfg(debug_assertions)] pub(super) cache_hits: AtomicUsize, } -impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> { +impl<'tcx, C: QueryCache> QueryState<'tcx, C> { pub(super) fn get_lookup( &'tcx self, key: &K2, @@ -86,7 +84,7 @@ pub(super) enum QueryResult<'tcx> { Poisoned, } -impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> { +impl<'tcx, C: QueryCache> QueryState<'tcx, C> { pub fn iter_results( &self, f: impl for<'a> FnOnce( @@ -130,9 +128,9 @@ impl<'tcx, C: QueryCache> QueryStateImpl<'tcx, C> { } } -impl<'tcx, C: QueryCache> Default for QueryStateImpl<'tcx, C> { - fn default() -> QueryStateImpl<'tcx, C> { - QueryStateImpl { +impl<'tcx, C: QueryCache> Default for QueryState<'tcx, C> { + fn default() -> QueryState<'tcx, C> { + QueryState { cache: C::default(), shards: Default::default(), #[cfg(debug_assertions)] @@ -156,7 +154,7 @@ where C::Key: Eq + Hash + Clone + Debug, C::Value: Clone, { - state: &'tcx QueryStateImpl<'tcx, C>, + state: &'tcx QueryState<'tcx, C>, key: C::Key, id: QueryJobId, } @@ -482,7 +480,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline(always)] fn try_get_cached( self, - state: &'tcx QueryStateImpl<'tcx, C>, + state: &'tcx QueryState<'tcx, C>, key: C::Key, // `on_hit` can be called while holding a lock to the query cache on_hit: OnHit, @@ -979,7 +977,7 @@ macro_rules! define_queries_inner { type Cache = query_storage!([$($modifiers)*][$K, $V]); #[inline(always)] - fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<$tcx, Self> { + fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<$tcx, Self::Cache> { &tcx.queries.$name } @@ -1131,7 +1129,10 @@ macro_rules! define_queries_struct { providers: IndexVec>, fallback_extern_providers: Box>, - $($(#[$attr])* $name: QueryState<$tcx, queries::$name<$tcx>>,)* + $($(#[$attr])* $name: QueryState< + $tcx, + as QueryAccessors<'tcx>>::Cache, + >,)* } impl<$tcx> Queries<$tcx> { diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index 256bd86a3de3..58ace917786c 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -1,7 +1,7 @@ use crate::hir::map::definitions::DefPathData; use crate::ty::context::TyCtxt; use crate::ty::query::caches::QueryCache; -use crate::ty::query::plumbing::QueryStateImpl; +use crate::ty::query::plumbing::QueryState; use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; @@ -160,7 +160,7 @@ where pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( tcx: TyCtxt<'tcx>, query_name: &'static str, - query_state: &QueryStateImpl<'tcx, C>, + query_state: &QueryState<'tcx, C>, string_cache: &mut QueryKeyStringCache, ) where C: QueryCache, diff --git a/src/librustc/ty/query/stats.rs b/src/librustc/ty/query/stats.rs index 20894a2a5d1e..527bb46c9088 100644 --- a/src/librustc/ty/query/stats.rs +++ b/src/librustc/ty/query/stats.rs @@ -1,6 +1,6 @@ use crate::ty::query::caches::QueryCache; use crate::ty::query::config::QueryAccessors; -use crate::ty::query::plumbing::QueryStateImpl; +use crate::ty::query::plumbing::QueryState; use crate::ty::query::queries; use crate::ty::TyCtxt; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -38,7 +38,7 @@ struct QueryStats { local_def_id_keys: Option, } -fn stats<'tcx, C: QueryCache>(name: &'static str, map: &QueryStateImpl<'tcx, C>) -> QueryStats { +fn stats<'tcx, C: QueryCache>(name: &'static str, map: &QueryState<'tcx, C>) -> QueryStats { let mut stats = QueryStats { name, #[cfg(debug_assertions)] From 8aa13289b5fbfcbdf5afb19d15a41a15d8f8aa22 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 15 Mar 2020 09:44:23 +0100 Subject: [PATCH 17/17] Make stuff private. --- src/librustc/ty/query/mod.rs | 2 +- src/librustc/ty/query/plumbing.rs | 41 ++++++++++++++----------------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 54e80b4dc0b1..1279ae2059ba 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -62,7 +62,7 @@ use std::sync::Arc; #[macro_use] mod plumbing; -pub use self::plumbing::CycleError; +pub(crate) use self::plumbing::CycleError; use self::plumbing::*; mod stats; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 442b3edcafe0..0bfcae5fa2e6 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -30,11 +30,11 @@ use std::ptr; use std::sync::atomic::{AtomicUsize, Ordering}; pub(crate) struct QueryStateShard<'tcx, K, C> { - pub(super) cache: C, - pub(super) active: FxHashMap>, + cache: C, + active: FxHashMap>, /// Used to generate unique ids for active jobs. - pub(super) jobs: u32, + jobs: u32, } impl<'tcx, K, C> QueryStateShard<'tcx, K, C> { @@ -50,8 +50,8 @@ impl<'tcx, K, C: Default> Default for QueryStateShard<'tcx, K, C> { } pub(crate) struct QueryState<'tcx, C: QueryCache> { - pub(super) cache: C, - pub(super) shards: Sharded>, + cache: C, + shards: Sharded>, #[cfg(debug_assertions)] pub(super) cache_hits: AtomicUsize, } @@ -75,7 +75,7 @@ impl<'tcx, C: QueryCache> QueryState<'tcx, C> { } /// Indicates the state of a query for a given key in a query map. -pub(super) enum QueryResult<'tcx> { +enum QueryResult<'tcx> { /// An already executing query. The query job can be used to await for its completion. Started(QueryJob<'tcx>), @@ -85,7 +85,7 @@ pub(super) enum QueryResult<'tcx> { } impl<'tcx, C: QueryCache> QueryState<'tcx, C> { - pub fn iter_results( + pub(super) fn iter_results( &self, f: impl for<'a> FnOnce( Box + 'a>, @@ -93,7 +93,7 @@ impl<'tcx, C: QueryCache> QueryState<'tcx, C> { ) -> R { self.cache.iter(&self.shards, |shard| &mut shard.cache, f) } - pub fn all_inactive(&self) -> bool { + pub(super) fn all_inactive(&self) -> bool { let shards = self.shards.lock_shards(); shards.iter().all(|shard| shard.active.is_empty()) } @@ -142,13 +142,13 @@ impl<'tcx, C: QueryCache> Default for QueryState<'tcx, C> { /// Values used when checking a query cache which can be reused on a cache-miss to execute the query. pub(crate) struct QueryLookup<'tcx, K, C> { pub(super) key_hash: u64, - pub(super) shard: usize, + shard: usize, pub(super) lock: LockGuard<'tcx, QueryStateShard<'tcx, K, C>>, } /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. -pub(super) struct JobOwner<'tcx, C> +struct JobOwner<'tcx, C> where C: QueryCache, C::Key: Eq + Hash + Clone + Debug, @@ -174,7 +174,7 @@ where /// This function is inlined because that results in a noticeable speed-up /// for some compile-time benchmarks. #[inline(always)] - pub(super) fn try_start( + fn try_start( tcx: TyCtxt<'tcx>, span: Span, key: &C::Key, @@ -262,12 +262,7 @@ where /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query #[inline(always)] - pub(super) fn complete( - self, - tcx: TyCtxt<'tcx>, - result: &C::Value, - dep_node_index: DepNodeIndex, - ) { + fn complete(self, tcx: TyCtxt<'tcx>, result: &C::Value, dep_node_index: DepNodeIndex) { // We can move out of `self` here because we `mem::forget` it below let key = unsafe { ptr::read(&self.key) }; let state = self.state; @@ -327,14 +322,14 @@ where } #[derive(Clone)] -pub struct CycleError<'tcx> { +pub(crate) struct CycleError<'tcx> { /// The query and related span that uses the cycle. pub(super) usage: Option<(Span, Query<'tcx>)>, pub(super) cycle: Vec>, } /// The result of `try_start`. -pub(super) enum TryGetJob<'tcx, C: QueryCache> +enum TryGetJob<'tcx, C: QueryCache> where C::Key: Eq + Hash + Clone + Debug, C::Value: Clone, @@ -357,7 +352,7 @@ impl<'tcx> TyCtxt<'tcx> { /// new query job while it executes. It returns the diagnostics /// captured during execution and the actual result. #[inline(always)] - pub(super) fn start_query( + fn start_query( self, token: QueryJobId, diagnostics: Option<&Lock>>, @@ -529,7 +524,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline(always)] - pub(super) fn try_execute_query + 'tcx>( + fn try_execute_query + 'tcx>( self, span: Span, key: Q::Key, @@ -1136,7 +1131,7 @@ macro_rules! define_queries_struct { } impl<$tcx> Queries<$tcx> { - pub fn new( + pub(crate) fn new( providers: IndexVec>, fallback_extern_providers: Providers<$tcx>, on_disk_cache: OnDiskCache<'tcx>, @@ -1149,7 +1144,7 @@ macro_rules! define_queries_struct { } } - pub fn try_collect_active_jobs( + pub(crate) fn try_collect_active_jobs( &self ) -> Option>> { let mut jobs = FxHashMap::default();