diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 18a669175b9ef..922cbd51b88e0 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -731,6 +731,7 @@ pub fn create_global_ctxt<'tcx>( extern_providers, query_result_on_disk_cache, incremental, + !rustc_data_structures::sync::is_dyn_thread_safe(), ), ) }) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index a1aac2846210d..bbc48a882e641 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -3,6 +3,8 @@ use crate::dep_graph::DepKind; use crate::query::on_disk_cache::CacheEncoder; use crate::query::on_disk_cache::EncodedDepNodeIndex; use crate::query::on_disk_cache::OnDiskCache; +#[cfg(parallel_compiler)] +use crate::query::MtQueryCaches; use crate::query::{ DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates, }; @@ -11,6 +13,8 @@ use field_offset::FieldOffset; use measureme::StringId; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::AtomicU64; +#[cfg(parallel_compiler)] +use rustc_data_structures::sync::DynSync; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::OwnerId; @@ -20,6 +24,8 @@ pub(crate) use rustc_query_system::query::QueryJobId; use rustc_query_system::query::*; use rustc_query_system::HandleCycleError; use rustc_span::{Span, DUMMY_SP}; +#[cfg(not(parallel_compiler))] +use std::marker::PhantomData; use std::ops::Deref; pub struct QueryKeyStringCache { @@ -32,13 +38,17 @@ impl QueryKeyStringCache { } } -pub struct DynamicQuery<'tcx, C: QueryCache> { +pub struct DynamicQuery<'tcx, C: QueryCache, C2: QueryCache> { pub name: &'static str, pub eval_always: bool, pub dep_kind: DepKind, pub handle_cycle_error: HandleCycleError, pub query_state: FieldOffset, QueryState>, pub query_cache: FieldOffset, C>, + #[cfg(not(parallel_compiler))] + pub mt_query_cache: PhantomData, + #[cfg(parallel_compiler)] + pub mt_query_cache: FieldOffset, C2>, 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, @@ -72,6 +82,10 @@ pub struct QuerySystem<'tcx> { pub states: QueryStates<'tcx>, pub arenas: QueryArenas<'tcx>, pub caches: QueryCaches<'tcx>, + #[cfg(parallel_compiler)] + pub single_thread: bool, + #[cfg(parallel_compiler)] + pub mt_caches: MtQueryCaches<'tcx>, pub dynamic_queries: DynamicQueries<'tcx>, /// This provides access to the incremental compilation on-disk cache for query results. @@ -85,6 +99,10 @@ pub struct QuerySystem<'tcx> { pub jobs: AtomicU64, } +// It's thread safe since `QueryCaches` only used under single thread +#[cfg(parallel_compiler)] +unsafe impl<'tcx> DynSync for QuerySystem<'tcx> {} + #[derive(Copy, Clone)] pub struct TyCtxtAt<'tcx> { pub tcx: TyCtxt<'tcx>, @@ -138,6 +156,36 @@ impl<'tcx> TyCtxt<'tcx> { } } +#[macro_export] +#[cfg(not(parallel_compiler))] +macro_rules! with_query_caches { + ($func: ident($($params: expr,)* :$tcx: expr, $name:ident, $($rest: expr,)*)) => { + $func($($params,)* &$tcx.query_system.caches.$name, $($rest,)*) + }; + ($tcx: expr, $name:ident, $func: ident($($params: expr,)*)) => { + $tcx.query_system.caches.$name.$func($($params,)*) + } +} + +#[macro_export] +#[cfg(parallel_compiler)] +macro_rules! with_query_caches { + ($func: ident($($params: expr,)* :$tcx: expr, $name:ident, $($rest: expr,)*)) => { + if $tcx.query_system.single_thread { + $func($($params,)* &$tcx.query_system.caches.$name, $($rest,)*) + } else { + $func($($params,)* &$tcx.query_system.mt_caches.$name, $($rest,)*) + } + }; + ($tcx: expr, $name:ident, $func: ident($($params: expr,)*)) => { + if $tcx.query_system.single_thread { + $tcx.query_system.caches.$name.$func($($params,)*) + } else { + $tcx.query_system.mt_caches.$name.$func($($params,)*) + } + } +} + #[inline] pub fn query_get_at<'tcx, Cache>( tcx: TyCtxt<'tcx>, @@ -286,6 +334,10 @@ macro_rules! define_callbacks { <$($K)* as keys::Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>> >::Cache; + pub type MtStorage<'tcx> = < + <$($K)* as keys::Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>> + >::MtCache; + // Ensure that keys grow no larger than 64 bytes #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] const _: () = { @@ -339,17 +391,22 @@ macro_rules! define_callbacks { $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)* } + #[derive(Default)] + pub struct MtQueryCaches<'tcx> { + $($(#[$attr])* pub $name: queries::$name::MtStorage<'tcx>,)* + } + impl<'tcx> TyCtxtEnsure<'tcx> { $($(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - query_ensure( + with_query_caches!(query_ensure( self.tcx, self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, + :self.tcx, $name, key.into_query_param(), false, - ); + )); })* } @@ -357,13 +414,13 @@ macro_rules! define_callbacks { $($(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - query_ensure( + with_query_caches!(query_ensure( self.tcx, self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, + :self.tcx, $name, key.into_query_param(), true, - ); + )); })* } @@ -377,8 +434,10 @@ macro_rules! define_callbacks { })* } + #[cfg(not(parallel_compiler))] impl<'tcx> TyCtxtAt<'tcx> { $($(#[$attr])* + #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { @@ -392,9 +451,35 @@ macro_rules! define_callbacks { })* } + #[cfg(parallel_compiler)] + impl<'tcx> TyCtxtAt<'tcx> { + $($(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V + { + if std::intrinsics::likely(self.tcx.query_system.single_thread) { + restore::<$V>(query_get_at( + self.tcx, + self.tcx.query_system.fns.engine.$name, + &self.tcx.query_system.caches.$name, + self.span, + key.into_query_param(), + )) + } else { + restore::<$V>(query_get_at( + self.tcx, + self.tcx.query_system.fns.engine.$name, + &self.tcx.query_system.mt_caches.$name, + self.span, + key.into_query_param(), + )) + } + })* + } + pub struct DynamicQueries<'tcx> { $( - pub $name: DynamicQuery<'tcx, queries::$name::Storage<'tcx>>, + pub $name: DynamicQuery<'tcx, queries::$name::Storage<'tcx>, queries::$name::MtStorage<'tcx>>, )* } @@ -484,10 +569,9 @@ macro_rules! define_feedable { let tcx = self.tcx; let erased = queries::$name::provided_to_erased(tcx, value); let value = restore::<$V>(erased); - let cache = &tcx.query_system.caches.$name; let hasher: Option, &_) -> _> = hash_result!([$($modifiers)*]); - match try_get_cached(tcx, cache, &key) { + match with_query_caches!(try_get_cached(tcx, :tcx, $name, &key,)) { Some(old) => { let old = restore::<$V>(old); if let Some(hasher) = hasher { @@ -523,7 +607,7 @@ macro_rules! define_feedable { &value, hash_result!([$($modifiers)*]), ); - cache.complete(key, erased, dep_node_index); + with_query_caches!(tcx, $name, complete(key, erased, dep_node_index,)); } } } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 53005ede84378..5e7c21c641d52 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -29,6 +29,8 @@ use rustc_middle::query::plumbing::{ DynamicQuery, QueryKeyStringCache, QuerySystem, QuerySystemFns, }; use rustc_middle::query::AsLocalKey; +#[cfg(parallel_compiler)] +use rustc_middle::query::MtQueryCaches; use rustc_middle::query::{ queries, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; @@ -53,33 +55,40 @@ pub use self::profiling_support::alloc_self_profile_query_strings; struct DynamicConfig< 'tcx, C: QueryCache, + C2: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool, > { - dynamic: &'tcx DynamicQuery<'tcx, C>, + dynamic: &'tcx DynamicQuery<'tcx, C, C2>, } -impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy - for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +impl<'tcx, C: QueryCache, C2, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy + for DynamicConfig<'tcx, C, C2, ANON, DEPTH_LIMIT, FEEDABLE> +where + C2: QueryCache, { } -impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone - for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +impl<'tcx, C: QueryCache, C2, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone + for DynamicConfig<'tcx, C, C2, ANON, DEPTH_LIMIT, FEEDABLE> +where + C2: QueryCache, { fn clone(&self) -> Self { DynamicConfig { dynamic: self.dynamic } } } -impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> - QueryConfig> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +impl<'tcx, C: QueryCache, C2, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> + QueryConfig> for DynamicConfig<'tcx, C, C2, ANON, DEPTH_LIMIT, FEEDABLE> where + C2: QueryCache, for<'a> C::Key: HashStable>, { type Key = C::Key; type Value = C::Value; type Cache = C; + type MtCache = C2; #[inline(always)] fn name(self) -> &'static str { @@ -107,6 +116,15 @@ where self.dynamic.query_cache.apply(&qcx.tcx.query_system.caches) } + #[inline(always)] + #[cfg(parallel_compiler)] + fn mt_query_cache<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a Self::MtCache + where + 'tcx: 'a, + { + self.dynamic.mt_query_cache.apply(&qcx.tcx.query_system.mt_caches) + } + #[inline(always)] fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { (self.dynamic.execute_query)(tcx, key) @@ -207,11 +225,16 @@ pub fn query_system<'tcx>( extern_providers: ExternProviders, on_disk_cache: Option>, incremental: bool, + _single_thread: bool, ) -> QuerySystem<'tcx> { QuerySystem { states: Default::default(), arenas: Default::default(), caches: Default::default(), + #[cfg(parallel_compiler)] + single_thread: _single_thread, + #[cfg(parallel_compiler)] + mt_caches: Default::default(), dynamic_queries: dynamic_queries(), on_disk_cache, fns: QuerySystemFns { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index def6ac280b804..4ea7029c03ea7 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -23,7 +23,7 @@ use rustc_query_system::query::{ force_query, QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame, }; -use rustc_query_system::{LayoutOfDepth, QueryOverflow}; +use rustc_query_system::{with_qcx_query_caches, LayoutOfDepth, QueryOverflow}; use rustc_serialize::Decodable; use rustc_serialize::Encodable; use rustc_session::Limit; @@ -73,6 +73,12 @@ impl QueryContext for QueryCtxt<'_> { ) } + #[inline] + #[cfg(parallel_compiler)] + fn single_thread(self) -> bool { + self.query_system.single_thread + } + #[inline] fn current_query_job(self) -> Option { tls::with_related_context(self.tcx, |icx| icx.query) @@ -352,19 +358,22 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( qcx.profiler().verbose_generic_activity_with_arg("encode_query_results_for", query.name()); assert!(query.query_state(qcx).all_inactive()); - let cache = query.query_cache(qcx); - cache.iter(&mut |key, value, dep_node| { - if query.cache_on_disk(qcx.tcx, &key) { - let dep_node = SerializedDepNodeIndex::new(dep_node.index()); - - // Record position of the cache entry. - query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position()))); - - // Encode the type check tables with the `SerializedDepNodeIndex` - // as tag. - encoder.encode_tagged(dep_node, &Q::restore(*value)); - } - }); + with_qcx_query_caches!( + query, + qcx, + iter(&mut |key, value, dep_node| { + if query.cache_on_disk(qcx.tcx, &key) { + let dep_node = SerializedDepNodeIndex::new(dep_node.index()); + + // Record position of the cache entry. + query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position()))); + + // Encode the type check tables with the `SerializedDepNodeIndex` + // as tag. + encoder.encode_tagged(dep_node, &Q::restore(*value)); + } + }) + ); } fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) @@ -562,7 +571,7 @@ macro_rules! define_queries { } } - pub fn dynamic_query<'tcx>() -> DynamicQuery<'tcx, queries::$name::Storage<'tcx>> { + pub fn dynamic_query<'tcx>() -> DynamicQuery<'tcx, queries::$name::Storage<'tcx>, queries::$name::MtStorage<'tcx>> { DynamicQuery { name: stringify!($name), eval_always: is_eval_always!([$($modifiers)*]), @@ -570,6 +579,10 @@ macro_rules! define_queries { handle_cycle_error: handle_cycle_error!([$($modifiers)*]), query_state: offset_of!(QueryStates<'tcx> => $name), query_cache: offset_of!(QueryCaches<'tcx> => $name), + #[cfg(not(parallel_compiler))] + mt_query_cache: PhantomData, + #[cfg(parallel_compiler)] + mt_query_cache: offset_of!(MtQueryCaches<'tcx> => $name), cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key), execute_query: |tcx, key| erase(tcx.$name(key)), compute: |tcx, key| { @@ -632,6 +645,7 @@ macro_rules! define_queries { type Config = DynamicConfig< 'tcx, queries::$name::Storage<'tcx>, + queries::$name::MtStorage<'tcx>, { is_anon!([$($modifiers)*]) }, { depth_limit!([$($modifiers)*]) }, { feedable!([$($modifiers)*]) }, @@ -664,12 +678,13 @@ macro_rules! define_queries { } pub fn alloc_self_profile_query_strings<'tcx>(tcx: TyCtxt<'tcx>, string_cache: &mut QueryKeyStringCache) { - $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache( + use $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache; + with_query_caches!(alloc_self_profile_query_strings_for_query_cache( tcx, stringify!($name), - &tcx.query_system.caches.$name, + :tcx, $name, string_cache, - ) + )) } item_if_cached! { [$($modifiers)*] { diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 4ba9d53a92f75..ab0f055f99122 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -1,4 +1,5 @@ use crate::dep_graph::DepNodeIndex; +use std::cell::RefCell; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::{self, Sharded}; @@ -12,6 +13,9 @@ pub trait CacheSelector<'tcx, V> { type Cache where V: Copy; + type MtCache + where + V: Copy; } pub trait QueryCache: Sized { @@ -32,10 +36,13 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<'tcx, V> for DefaultCacheSelecto type Cache = DefaultCache where V: Copy; + type MtCache = MtDefaultCache + where + V: Copy; } pub struct DefaultCache { - cache: Sharded>, + cache: RefCell>, } impl Default for DefaultCache { @@ -52,6 +59,50 @@ where type Key = K; type Value = V; + #[inline(always)] + fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> { + let key_hash = sharded::make_hash(key); + let lock = self.cache.borrow_mut(); + let result = lock.raw_entry().from_key_hashed_nocheck(key_hash, key); + + if let Some((_, value)) = result { Some(*value) } else { None } + } + + #[inline] + fn complete(&self, key: K, value: V, index: DepNodeIndex) { + let mut lock = self.cache.borrow_mut(); + // We may be overwriting another value. This is all right, since the dep-graph + // will check that the fingerprint matches. + lock.insert(key, (value, index)); + } + + fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + let map = self.cache.borrow_mut(); + for (k, v) in map.iter() { + f(k, &v.0, v.1); + } + } +} + +// Default caches for multiple threads +pub struct MtDefaultCache { + cache: Sharded>, +} + +impl Default for MtDefaultCache { + fn default() -> Self { + MtDefaultCache { cache: Default::default() } + } +} + +impl QueryCache for MtDefaultCache +where + K: Eq + Hash + Copy + Debug, + V: Copy, +{ + type Key = K; + type Value = V; + #[inline(always)] fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> { let key_hash = sharded::make_hash(key); @@ -85,6 +136,9 @@ impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector { type Cache = SingleCache where V: Copy; + type MtCache = SingleCache + where + V: Copy; } pub struct SingleCache { @@ -127,10 +181,13 @@ impl<'tcx, K: Idx, V: 'tcx> CacheSelector<'tcx, V> for VecCacheSelector { type Cache = VecCache where V: Copy; + type MtCache = MtVecCache + where + V: Copy; } pub struct VecCache { - cache: Sharded>>, + cache: RefCell>>, } impl Default for VecCache { @@ -147,6 +204,47 @@ where type Key = K; type Value = V; + #[inline(always)] + fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> { + let lock = self.cache.borrow_mut(); + if let Some(Some(value)) = lock.get(*key) { Some(*value) } else { None } + } + + #[inline] + fn complete(&self, key: K, value: V, index: DepNodeIndex) { + let mut lock = self.cache.borrow_mut(); + lock.insert(key, (value, index)); + } + + fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + let map = self.cache.borrow_mut(); + for (k, v) in map.iter_enumerated() { + if let Some(v) = v { + f(&k, &v.0, v.1); + } + } + } +} + +// Vec caches for multiple threads +pub struct MtVecCache { + cache: Sharded>>, +} + +impl Default for MtVecCache { + fn default() -> Self { + MtVecCache { cache: Default::default() } + } +} + +impl QueryCache for MtVecCache +where + K: Eq + Idx + Copy + Debug, + V: Copy, +{ + type Key = K; + type Value = V; + #[inline(always)] fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> { let lock = self.cache.get_shard_by_hash(key.index() as u64).lock(); diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index 7e47d70120544..70d12c4027d29 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -22,6 +22,7 @@ pub trait QueryConfig: Copy { type Value: Copy; type Cache: QueryCache; + type MtCache: QueryCache; fn format_value(self) -> fn(&Self::Value) -> String; @@ -35,6 +36,12 @@ pub trait QueryConfig: Copy { where Qcx: 'a; + // Don't use this method to access query results, instead use the methods on TyCtxt + #[cfg(parallel_compiler)] + fn mt_query_cache<'a>(self, tcx: Qcx) -> &'a Self::MtCache + where + Qcx: 'a; + fn cache_on_disk(self, tcx: Qcx::DepContext, key: &Self::Key) -> bool; // Don't use this method to compute query results, instead use the methods on TyCtxt @@ -73,3 +80,33 @@ pub trait QueryConfig: Copy { DepNode::construct(tcx, self.dep_kind(), key) } } + +#[macro_export] +#[cfg(not(parallel_compiler))] +macro_rules! with_qcx_query_caches { + ($query: ident, $qcx: ident, $func:ident($($params: expr)*)) => { + $query.query_cache($qcx).$func($($params)*) + }; + ($func: ident$(.$call: ident)?($query: ident, $qcx: ident, $($rest: expr,)*)) => { + $func$(.$call)?($query.query_cache($qcx), $($rest,)*) + }; +} + +#[macro_export] +#[cfg(parallel_compiler)] +macro_rules! with_qcx_query_caches { + ($query: ident, $qcx: ident, $func:ident($($params: expr)*)) => { + if $qcx.single_thread() { + $query.query_cache($qcx).$func($($params)*) + } else { + $query.mt_query_cache($qcx).$func($($params)*) + } + }; + ($func: ident$(.$call: ident)?($query: ident, $qcx: ident, $($rest: expr,)*)) => { + if $qcx.single_thread() { + $func$(.$call)?($query.query_cache($qcx), $($rest,)*) + } else { + $func$(.$call)?($query.mt_query_cache($qcx), $($rest,)*) + } + }; +} diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index f7619d75be768..358ef6a072855 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -103,6 +103,9 @@ impl QuerySideEffects { pub trait QueryContext: HasDepContext { fn next_job_id(self) -> QueryJobId; + #[cfg(parallel_compiler)] + fn single_thread(self) -> bool; + /// Get the query information from the TLS context. fn current_query_job(self) -> Option; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 4adb4eb7475be..790135d41690d 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -11,7 +11,7 @@ use crate::query::job::QueryLatch; use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo}; use crate::query::SerializedDepNodeIndex; use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame}; -use crate::HandleCycleError; +use crate::{with_qcx_query_caches, HandleCycleError}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -299,7 +299,7 @@ where match result { Ok(()) => { - let Some((v, index)) = query.query_cache(qcx).lookup(&key) else { + let Some((v, index)) = query.mt_query_cache(qcx).lookup(&key) else { cold_path(|| panic!("value must be in cache after waiting")) }; @@ -336,8 +336,9 @@ where // re-executing the query since `try_start` only checks that the query is not currently // executing, but another thread may have already completed the query and stores it result // in the query cache. - if cfg!(parallel_compiler) && qcx.dep_context().sess().threads() > 1 { - if let Some((value, index)) = query.query_cache(qcx).lookup(&key) { + #[cfg(parallel_compiler)] + if rustc_data_structures::sync::is_dyn_thread_safe() { + if let Some((value, index)) = query.mt_query_cache(qcx).lookup(&key) { qcx.dep_context().profiler().query_cache_hit(index.into()); return (value, Some(index)); } @@ -414,13 +415,12 @@ where execute_job_non_incr(query, qcx, key, id) }; - let cache = query.query_cache(qcx); if query.feedable() { // We should not compute queries that also got a value via feeding. // This can't happen, as query feeding adds the very dependencies to the fed query // as its feeding query had. So if the fed query is red, so is its feeder, which will // get evaluated first, and re-feed the query. - if let Some((cached_result, _)) = cache.lookup(&key) { + if let Some((cached_result, _)) = with_qcx_query_caches!(query, qcx, lookup(&key)) { let Some(hasher) = query.hash_result() else { panic!( "no_hash fed query later has its value computed.\n\ @@ -452,7 +452,7 @@ where } } } - job_owner.complete(cache, result, dep_node_index); + with_qcx_query_caches!(job_owner.complete(query, qcx, result, dep_node_index,)); (result, Some(dep_node_index)) } @@ -855,7 +855,7 @@ pub fn force_query( { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. - if let Some((_, index)) = query.query_cache(qcx).lookup(&key) { + if let Some((_, index)) = with_qcx_query_caches!(query, qcx, lookup(&key)) { qcx.dep_context().profiler().query_cache_hit(index.into()); return; }