]> git.lizzy.rs Git - rust.git/commitdiff
Move Sharded maps into each QueryCache impl
authorMark Rousskov <mark.simulacrum@gmail.com>
Sun, 20 Feb 2022 03:44:19 +0000 (22:44 -0500)
committerMark Rousskov <mark.simulacrum@gmail.com>
Sun, 20 Feb 2022 17:10:46 +0000 (12:10 -0500)
compiler/rustc_data_structures/src/sharded.rs
compiler/rustc_middle/src/ty/query.rs
compiler/rustc_query_impl/src/on_disk_cache.rs
compiler/rustc_query_impl/src/plumbing.rs
compiler/rustc_query_impl/src/profiling_support.rs
compiler/rustc_query_system/src/query/caches.rs
compiler/rustc_query_system/src/query/config.rs
compiler/rustc_query_system/src/query/plumbing.rs

index 417c61242a539d584e1aac62e7bad937b379b321..01d292dde8d13a262f89699ee50fc1c74d3cd6c9 100644 (file)
@@ -129,7 +129,7 @@ pub fn contains_pointer_to<T: Hash + IntoPointer>(&self, value: &T) -> bool {
 }
 
 #[inline]
-fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
+pub fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
     let mut state = FxHasher::default();
     val.hash(&mut state);
     state.finish()
index 1688e59cdd12fe89fd7ba6858a9706691e2dc1f9..c72b823d8499aaa775a5e654c56fbdc4400430ce 100644 (file)
@@ -210,7 +210,7 @@ pub mod query_stored {
 
         #[derive(Default)]
         pub struct QueryCaches<$tcx> {
-            $($(#[$attr])* pub $name: QueryCacheStore<query_storage::$name<$tcx>>,)*
+            $($(#[$attr])* pub $name: query_storage::$name<$tcx>,)*
         }
 
         impl<$tcx> TyCtxtEnsure<$tcx> {
index 06e276ab42b3b46954e871eabafb0d761f200c6e..f2f895367ff826102c45f58e99d61b2beae19cb0 100644 (file)
@@ -13,7 +13,7 @@
 use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_query_system::dep_graph::DepContext;
-use rustc_query_system::query::{QueryContext, QuerySideEffects};
+use rustc_query_system::query::{QueryCache, QueryContext, QuerySideEffects};
 use rustc_serialize::{
     opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize},
     Decodable, Decoder, Encodable, Encoder,
@@ -1034,7 +1034,7 @@ pub fn encode_query_results<'a, 'tcx, CTX, Q>(
     assert!(Q::query_state(tcx).all_inactive());
     let cache = Q::query_cache(tcx);
     let mut res = Ok(());
-    cache.iter_results(&mut |key, value, dep_node| {
+    cache.iter(&mut |key, value, dep_node| {
         if res.is_err() {
             return;
         }
index ff9d32a6776520fb1aae2bd69b1900477fb61946..1eaf5ee0c05849baf8f5b2398bd4d595f15ad8a0 100644 (file)
@@ -337,7 +337,7 @@ fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<Self::Key>
             }
 
             #[inline(always)]
-            fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryCacheStore<Self::Cache>
+            fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a Self::Cache
                 where 'tcx:'a
             {
                 &tcx.query_caches.$name
index da318fc762290344b4fc65ebcfaf42ac62cdb5a5..acccf43f06285f59b8421227b0373d47bbbfac26 100644 (file)
@@ -4,7 +4,7 @@
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathData;
 use rustc_middle::ty::{TyCtxt, WithOptConstParam};
-use rustc_query_system::query::{QueryCache, QueryCacheStore};
+use rustc_query_system::query::QueryCache;
 use std::fmt::Debug;
 use std::io::Write;
 
@@ -229,7 +229,7 @@ fn spec_to_self_profile_string(
 fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
     tcx: TyCtxt<'tcx>,
     query_name: &'static str,
-    query_cache: &QueryCacheStore<C>,
+    query_cache: &C,
     string_cache: &mut QueryKeyStringCache,
 ) where
     C: QueryCache,
@@ -251,7 +251,7 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
             // locked while doing so. Instead we copy out the
             // `(query_key, dep_node_index)` pairs and release the lock again.
             let mut query_keys_and_indices = Vec::new();
-            query_cache.iter_results(&mut |k, _, i| query_keys_and_indices.push((k.clone(), i)));
+            query_cache.iter(&mut |k, _, i| query_keys_and_indices.push((k.clone(), i)));
 
             // Now actually allocate the strings. If allocating the strings
             // generates new entries in the query cache, we'll miss them but
@@ -276,7 +276,7 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
             let event_id = event_id_builder.from_label(query_name).to_string_id();
 
             let mut query_invocation_ids = Vec::new();
-            query_cache.iter_results(&mut |_, _, i| {
+            query_cache.iter(&mut |_, _, i| {
                 query_invocation_ids.push(i.into());
             });
 
index 011c2ceebb7148797d92260cc89576b8c5ccd0b5..05cc61c83aab98d5ac913136c20965ff836bf1d0 100644 (file)
@@ -1,9 +1,9 @@
 use crate::dep_graph::DepNodeIndex;
-use crate::query::plumbing::{QueryCacheStore, QueryLookup};
+use crate::query::plumbing::QueryLookup;
 
 use rustc_arena::TypedArena;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sharded::Sharded;
+use rustc_data_structures::sharded::{self, Sharded};
 use rustc_data_structures::sync::WorkerLocal;
 use std::default::Default;
 use std::fmt::Debug;
@@ -25,15 +25,13 @@ pub trait QueryStorage {
 
 pub trait QueryCache: QueryStorage + Sized {
     type Key: Hash + Eq + Clone + Debug;
-    type Sharded: Default;
 
     /// Checks if the query is already computed and in the cache.
     /// 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<'s, R, OnHit>(
+    fn lookup<R, OnHit>(
         &self,
-        state: &'s QueryCacheStore<Self>,
         key: &Self::Key,
         // `on_hit` can be called while holding a lock to the query state shard.
         on_hit: OnHit,
@@ -41,19 +39,9 @@ fn lookup<'s, R, OnHit>(
     where
         OnHit: FnOnce(&Self::Stored, DepNodeIndex) -> R;
 
-    fn complete(
-        &self,
-        lock_sharded_storage: &mut Self::Sharded,
-        key: Self::Key,
-        value: Self::Value,
-        index: DepNodeIndex,
-    ) -> Self::Stored;
+    fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex) -> Self::Stored;
 
-    fn iter(
-        &self,
-        shards: &Sharded<Self::Sharded>,
-        f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
-    );
+    fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
 }
 
 pub struct DefaultCacheSelector;
@@ -62,11 +50,13 @@ impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
     type Cache = DefaultCache<K, V>;
 }
 
-pub struct DefaultCache<K, V>(PhantomData<(K, V)>);
+pub struct DefaultCache<K, V> {
+    shards: Sharded<FxHashMap<K, (V, DepNodeIndex)>>,
+}
 
 impl<K, V> Default for DefaultCache<K, V> {
     fn default() -> Self {
-        DefaultCache(PhantomData)
+        DefaultCache { shards: Default::default() }
     }
 }
 
@@ -87,19 +77,16 @@ impl<K, V> QueryCache for DefaultCache<K, V>
     V: Clone + Debug,
 {
     type Key = K;
-    type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
 
     #[inline(always)]
-    fn lookup<'s, R, OnHit>(
-        &self,
-        state: &'s QueryCacheStore<Self>,
-        key: &K,
-        on_hit: OnHit,
-    ) -> Result<R, QueryLookup>
+    fn lookup<R, OnHit>(&self, key: &K, on_hit: OnHit) -> Result<R, QueryLookup>
     where
         OnHit: FnOnce(&V, DepNodeIndex) -> R,
     {
-        let (lookup, lock) = state.get_lookup(key);
+        let key_hash = sharded::make_hash(key);
+        let shard = sharded::get_shard_index_by_hash(key_hash);
+        let lock = self.shards.get_shard_by_index(shard).lock();
+        let lookup = QueryLookup { key_hash, shard };
         let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, key);
 
         if let Some((_, value)) = result {
@@ -111,23 +98,13 @@ fn lookup<'s, R, OnHit>(
     }
 
     #[inline]
-    fn complete(
-        &self,
-        lock_sharded_storage: &mut Self::Sharded,
-        key: K,
-        value: V,
-        index: DepNodeIndex,
-    ) -> Self::Stored {
-        lock_sharded_storage.insert(key, (value.clone(), index));
+    fn complete(&self, key: K, value: V, index: DepNodeIndex) -> Self::Stored {
+        self.shards.get_shard_by_value(&key).lock().insert(key, (value.clone(), index));
         value
     }
 
-    fn iter(
-        &self,
-        shards: &Sharded<Self::Sharded>,
-        f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
-    ) {
-        let shards = shards.lock_shards();
+    fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
+        let shards = self.shards.lock_shards();
         for shard in shards.iter() {
             for (k, v) in shard.iter() {
                 f(k, &v.0, v.1);
@@ -144,12 +121,15 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<K, V> for ArenaCacheSelector<'tc
 
 pub struct ArenaCache<'tcx, K, V> {
     arena: WorkerLocal<TypedArena<(V, DepNodeIndex)>>,
-    phantom: PhantomData<(K, &'tcx V)>,
+    shards: Sharded<FxHashMap<K, &'tcx (V, DepNodeIndex)>>,
 }
 
 impl<'tcx, K, V> Default for ArenaCache<'tcx, K, V> {
     fn default() -> Self {
-        ArenaCache { arena: WorkerLocal::new(|_| TypedArena::default()), phantom: PhantomData }
+        ArenaCache {
+            arena: WorkerLocal::new(|_| TypedArena::default()),
+            shards: Default::default(),
+        }
     }
 }
 
@@ -171,19 +151,16 @@ impl<'tcx, K, V: 'tcx> QueryCache for ArenaCache<'tcx, K, V>
     V: Debug,
 {
     type Key = K;
-    type Sharded = FxHashMap<K, &'tcx (V, DepNodeIndex)>;
 
     #[inline(always)]
-    fn lookup<'s, R, OnHit>(
-        &self,
-        state: &'s QueryCacheStore<Self>,
-        key: &K,
-        on_hit: OnHit,
-    ) -> Result<R, QueryLookup>
+    fn lookup<R, OnHit>(&self, key: &K, on_hit: OnHit) -> Result<R, QueryLookup>
     where
         OnHit: FnOnce(&&'tcx V, DepNodeIndex) -> R,
     {
-        let (lookup, lock) = state.get_lookup(key);
+        let key_hash = sharded::make_hash(key);
+        let shard = sharded::get_shard_index_by_hash(key_hash);
+        let lock = self.shards.get_shard_by_index(shard).lock();
+        let lookup = QueryLookup { key_hash, shard };
         let result = lock.raw_entry().from_key_hashed_nocheck(lookup.key_hash, key);
 
         if let Some((_, value)) = result {
@@ -195,25 +172,15 @@ fn lookup<'s, R, OnHit>(
     }
 
     #[inline]
-    fn complete(
-        &self,
-        lock_sharded_storage: &mut Self::Sharded,
-        key: K,
-        value: V,
-        index: DepNodeIndex,
-    ) -> Self::Stored {
+    fn complete(&self, key: K, value: V, index: DepNodeIndex) -> Self::Stored {
         let value = self.arena.alloc((value, index));
         let value = unsafe { &*(value as *const _) };
-        lock_sharded_storage.insert(key, value);
+        self.shards.get_shard_by_value(&key).lock().insert(key, value);
         &value.0
     }
 
-    fn iter(
-        &self,
-        shards: &Sharded<Self::Sharded>,
-        f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
-    ) {
-        let shards = shards.lock_shards();
+    fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
+        let shards = self.shards.lock_shards();
         for shard in shards.iter() {
             for (k, v) in shard.iter() {
                 f(k, &v.0, v.1);
index b1ff1e15a9db53e0367d0fc895f2056c78c809ac..1ffcdbce6fc8ef1c6835b02979170d1f3bd72172 100644 (file)
@@ -4,7 +4,7 @@
 use crate::dep_graph::SerializedDepNodeIndex;
 use crate::ich::StableHashingContext;
 use crate::query::caches::QueryCache;
-use crate::query::{QueryCacheStore, QueryContext, QueryState};
+use crate::query::{QueryContext, QueryState};
 
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_errors::DiagnosticBuilder;
@@ -64,7 +64,7 @@ fn query_state<'a>(tcx: CTX) -> &'a QueryState<Self::Key>
         CTX: 'a;
 
     // Don't use this method to access query results, instead use the methods on TyCtxt
-    fn query_cache<'a>(tcx: CTX) -> &'a QueryCacheStore<Self::Cache>
+    fn query_cache<'a>(tcx: CTX) -> &'a Self::Cache
     where
         CTX: 'a;
 
index 77e1fd3f2ccbbda9952dda4d3faa617db717214f..9278bb602e11d6f9742873bd118c8ce100cc35eb 100644 (file)
@@ -12,7 +12,7 @@
 #[cfg(parallel_compiler)]
 use rustc_data_structures::profiling::TimingGuard;
 use rustc_data_structures::sharded::{get_shard_index_by_hash, Sharded};
-use rustc_data_structures::sync::{Lock, LockGuard};
+use rustc_data_structures::sync::Lock;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_errors::{DiagnosticBuilder, FatalError};
 use rustc_session::Session;
 use std::mem;
 use std::ptr;
 
-pub struct QueryCacheStore<C: QueryCache> {
-    cache: C,
-    shards: Sharded<C::Sharded>,
-}
-
-impl<C: QueryCache + Default> Default for QueryCacheStore<C> {
-    fn default() -> Self {
-        Self { cache: C::default(), shards: Default::default() }
-    }
-}
-
 /// Values used when checking a query cache which can be reused on a cache-miss to execute the query.
 pub struct QueryLookup {
     pub(super) key_hash: u64,
-    shard: usize,
+    pub(super) shard: usize,
 }
 
 // We compute the key's hash once and then use it for both the
@@ -50,22 +39,6 @@ fn hash_for_shard<K: Hash>(key: &K) -> u64 {
     hasher.finish()
 }
 
-impl<C: QueryCache> QueryCacheStore<C> {
-    pub(super) fn get_lookup<'tcx>(
-        &'tcx self,
-        key: &C::Key,
-    ) -> (QueryLookup, LockGuard<'tcx, C::Sharded>) {
-        let key_hash = hash_for_shard(key);
-        let shard = get_shard_index_by_hash(key_hash);
-        let lock = self.shards.get_shard_by_index(shard).lock();
-        (QueryLookup { key_hash, shard }, lock)
-    }
-
-    pub fn iter_results(&self, f: &mut dyn FnMut(&C::Key, &C::Value, DepNodeIndex)) {
-        self.cache.iter(&self.shards, f)
-    }
-}
-
 struct QueryStateShard<K> {
     active: FxHashMap<K, QueryResult>,
 }
@@ -239,12 +212,7 @@ fn try_start<'b, CTX>(
 
     /// 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
-    fn complete<C>(
-        self,
-        cache: &QueryCacheStore<C>,
-        result: C::Value,
-        dep_node_index: DepNodeIndex,
-    ) -> C::Stored
+    fn complete<C>(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) -> C::Stored
     where
         C: QueryCache<Key = K>,
     {
@@ -265,10 +233,7 @@ fn complete<C>(
                     QueryResult::Poisoned => panic!(),
                 }
             };
-            let result = {
-                let mut lock = cache.shards.get_shard_by_index(shard).lock();
-                cache.cache.complete(&mut lock, key, result, dep_node_index)
-            };
+            let result = cache.complete(key, result, dep_node_index);
             (job, result)
         };
 
@@ -334,7 +299,7 @@ enum TryGetJob<'tcx, K>
 #[inline]
 pub fn try_get_cached<'a, CTX, C, R, OnHit>(
     tcx: CTX,
-    cache: &'a QueryCacheStore<C>,
+    cache: &'a C,
     key: &C::Key,
     // `on_hit` can be called while holding a lock to the query cache
     on_hit: OnHit,
@@ -344,7 +309,7 @@ pub fn try_get_cached<'a, CTX, C, R, OnHit>(
     CTX: DepContext,
     OnHit: FnOnce(&C::Stored) -> R,
 {
-    cache.cache.lookup(cache, &key, |value, index| {
+    cache.lookup(&key, |value, index| {
         if unlikely!(tcx.profiler().enabled()) {
             tcx.profiler().query_cache_hit(index.into());
         }
@@ -356,7 +321,7 @@ pub fn try_get_cached<'a, CTX, C, R, OnHit>(
 fn try_execute_query<CTX, C>(
     tcx: CTX,
     state: &QueryState<C::Key>,
-    cache: &QueryCacheStore<C>,
+    cache: &C,
     span: Span,
     key: C::Key,
     lookup: QueryLookup,
@@ -375,14 +340,13 @@ fn try_execute_query<CTX, C>(
             (result, Some(dep_node_index))
         }
         TryGetJob::Cycle(error) => {
-            let result = mk_cycle(tcx, error, query.handle_cycle_error, &cache.cache);
+            let result = mk_cycle(tcx, error, query.handle_cycle_error, cache);
             (result, None)
         }
         #[cfg(parallel_compiler)]
         TryGetJob::JobCompleted(query_blocked_prof_timer) => {
             let (v, index) = cache
-                .cache
-                .lookup(cache, &key, |value, index| (value.clone(), index))
+                .lookup(&key, |value, index| (value.clone(), index))
                 .unwrap_or_else(|_| panic!("value must be in cache after waiting"));
 
             if unlikely!(tcx.dep_context().profiler().enabled()) {
@@ -760,7 +724,7 @@ pub fn force_query<Q, CTX>(tcx: CTX, key: Q::Key, dep_node: DepNode<CTX::DepKind
     // We may be concurrently trying both execute and force a query.
     // Ensure that only one of them runs the query.
     let cache = Q::query_cache(tcx);
-    let cached = cache.cache.lookup(cache, &key, |_, index| {
+    let cached = cache.lookup(&key, |_, index| {
         if unlikely!(tcx.dep_context().profiler().enabled()) {
             tcx.dep_context().profiler().query_cache_hit(index.into());
         }