Skip to content

Commit 7948340

Browse files
committed
Work on cache
1 parent e4a6032 commit 7948340

File tree

5 files changed

+113
-4
lines changed

5 files changed

+113
-4
lines changed

compiler/rustc_middle/src/query/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rustc_queries! {
2323
query hir_crate(key: ()) -> &'tcx Crate<'tcx> {
2424
eval_always
2525
no_hash
26+
storage(CellCacheSelector<'tcx>)
2627
desc { "get the crate HIR" }
2728
}
2829

@@ -31,6 +32,7 @@ rustc_queries! {
3132
query index_hir(_: ()) -> &'tcx crate::hir::IndexedHir<'tcx> {
3233
eval_always
3334
no_hash
35+
storage(CellCacheSelector<'tcx>)
3436
desc { "index HIR" }
3537
}
3638

@@ -116,6 +118,7 @@ rustc_queries! {
116118

117119
query analysis(key: ()) -> Result<(), ErrorReported> {
118120
eval_always
121+
storage(CellCacheSelector<'tcx>)
119122
desc { "running analysis passes on this crate" }
120123
}
121124

@@ -701,6 +704,7 @@ rustc_queries! {
701704
}
702705

703706
query typeck_item_bodies(_: ()) -> () {
707+
storage(CellCacheSelector<'tcx>)
704708
desc { "type-checking all item bodies" }
705709
}
706710

@@ -770,6 +774,7 @@ rustc_queries! {
770774
query crate_inherent_impls_overlap_check(_: ())
771775
-> () {
772776
eval_always
777+
storage(CellCacheSelector<'tcx>)
773778
desc { "check for overlap between inherent impls defined in this crate" }
774779
}
775780

@@ -863,10 +868,12 @@ rustc_queries! {
863868
/// Performs part of the privacy check and computes "access levels".
864869
query privacy_access_levels(_: ()) -> &'tcx AccessLevels {
865870
eval_always
871+
storage(CellCacheSelector<'tcx>)
866872
desc { "privacy access levels" }
867873
}
868874
query check_private_in_public(_: ()) -> () {
869875
eval_always
876+
storage(CellCacheSelector<'tcx>)
870877
desc { "checking for private elements in public interfaces" }
871878
}
872879

@@ -981,6 +988,7 @@ rustc_queries! {
981988
///
982989
/// [`LOCAL_CRATE`]: rustc_hir::def_id::LOCAL_CRATE
983990
query all_local_trait_impls(_: ()) -> &'tcx BTreeMap<DefId, Vec<LocalDefId>> {
991+
storage(CellCacheSelector<'tcx>)
984992
desc { "local trait impls" }
985993
}
986994

@@ -1229,12 +1237,15 @@ rustc_queries! {
12291237
/// Identifies the entry-point (e.g., the `main` function) for a given
12301238
/// crate, returning `None` if there is no entry point (such as for library crates).
12311239
query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> {
1240+
storage(CellCacheSelector<'tcx>)
12321241
desc { "looking up the entry function of a crate" }
12331242
}
12341243
query plugin_registrar_fn(_: ()) -> Option<LocalDefId> {
1244+
storage(CellCacheSelector<'tcx>)
12351245
desc { "looking up the plugin registrar for a crate" }
12361246
}
12371247
query proc_macro_decls_static(_: ()) -> Option<LocalDefId> {
1248+
storage(CellCacheSelector<'tcx>)
12381249
desc { "looking up the derive registrar for a crate" }
12391250
}
12401251
query crate_disambiguator(_: CrateNum) -> CrateDisambiguator {
@@ -1412,6 +1423,7 @@ rustc_queries! {
14121423
}
14131424
query postorder_cnums(_: ()) -> &'tcx [CrateNum] {
14141425
eval_always
1426+
storage(CellCacheSelector<'tcx>)
14151427
desc { "generating a postorder list of CrateNums" }
14161428
}
14171429
/// Returns whether or not the crate with CrateNum 'cnum'
@@ -1431,6 +1443,7 @@ rustc_queries! {
14311443
}
14321444
query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
14331445
eval_always
1446+
storage(CellCacheSelector<'tcx>)
14341447
desc { "looking up all possibly unused extern crates" }
14351448
}
14361449
query names_imported_by_glob_use(def_id: LocalDefId)
@@ -1446,13 +1459,15 @@ rustc_queries! {
14461459
}
14471460
query all_crate_nums(_: ()) -> &'tcx [CrateNum] {
14481461
eval_always
1462+
storage(CellCacheSelector<'tcx>)
14491463
desc { "fetching all foreign CrateNum instances" }
14501464
}
14511465

14521466
/// A vector of every trait accessible in the whole crate
14531467
/// (i.e., including those from subcrates). This is used only for
14541468
/// error reporting.
14551469
query all_traits(_: ()) -> &'tcx [DefId] {
1470+
storage(CellCacheSelector<'tcx>)
14561471
desc { "fetching all foreign and local traits" }
14571472
}
14581473

@@ -1468,6 +1483,7 @@ rustc_queries! {
14681483

14691484
query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) {
14701485
eval_always
1486+
storage(CellCacheSelector<'tcx>)
14711487
desc { "collect_and_partition_mono_items" }
14721488
}
14731489
query is_codegened_item(def_id: DefId) -> bool {
@@ -1477,7 +1493,8 @@ rustc_queries! {
14771493
/// All items participating in code generation together with items inlined into them.
14781494
query codegened_and_inlined_items(_: ()) -> &'tcx DefIdSet {
14791495
eval_always
1480-
desc { "codegened_and_inlined_items" }
1496+
storage(CellCacheSelector<'tcx>)
1497+
desc { "codegened_and_inlined_items" }
14811498
}
14821499

14831500
query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
@@ -1491,6 +1508,7 @@ rustc_queries! {
14911508
}
14921509
}
14931510
query backend_optimization_level(_: ()) -> OptLevel {
1511+
storage(CellCacheSelector<'tcx>)
14941512
desc { "optimization level used by backend" }
14951513
}
14961514

@@ -1672,6 +1690,7 @@ rustc_queries! {
16721690

16731691
query features_query(_: ()) -> &'tcx rustc_feature::Features {
16741692
eval_always
1693+
storage(CellCacheSelector<'tcx>)
16751694
desc { "looking up enabled feature gates" }
16761695
}
16771696

compiler/rustc_query_system/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(bool_to_option)]
2+
#![feature(const_panic)]
23
#![feature(core_intrinsics)]
34
#![feature(hash_raw_entry)]
45
#![feature(iter_zip)]

compiler/rustc_query_system/src/query/caches.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_data_structures::sync::WorkerLocal;
88
use std::default::Default;
99
use std::fmt::Debug;
1010
use std::hash::Hash;
11+
use std::cell::Cell;
1112
use std::marker::PhantomData;
1213

1314
pub trait CacheSelector<K, V> {
@@ -221,3 +222,91 @@ where
221222
}
222223
}
223224
}
225+
226+
pub struct CellCacheSelector<'tcx>(PhantomData<&'tcx ()>);
227+
228+
impl<'tcx, K: Eq + Hash, V: Clone> CacheSelector<K, V> for CellCacheSelector<'tcx> {
229+
type Cache = CellCache<K, V>;
230+
}
231+
232+
pub struct CellCache<K, V>(PhantomData<(K, V)>);
233+
234+
impl<K, V> Default for CellCache<K, V> {
235+
fn default() -> Self {
236+
CellCache(PhantomData)
237+
}
238+
}
239+
240+
impl<K, V> CellCache<K, V> {
241+
const KEY_IS_ZST: () = {
242+
if std::mem::size_of::<K>() != 0 {
243+
panic!("Key must be a ZST");
244+
}
245+
};
246+
}
247+
248+
impl<K: Eq + Hash, V: Clone + Debug> QueryStorage for CellCache<K, V> {
249+
type Value = V;
250+
type Stored = V;
251+
252+
#[inline]
253+
fn store_nocache(&self, value: Self::Value) -> Self::Stored {
254+
// We have no dedicated storage
255+
value
256+
}
257+
}
258+
259+
impl<K, V> QueryCache for CellCache<K, V>
260+
where
261+
K: Eq + Hash + Copy + Clone + Debug,
262+
V: Copy + Clone + Debug,
263+
{
264+
type Key = K;
265+
type Sharded = Cell<Option<(K, V, DepNodeIndex)>>;
266+
267+
#[inline(always)]
268+
fn lookup<'s, R, OnHit>(
269+
&self,
270+
state: &'s QueryCacheStore<Self>,
271+
_key: &K,
272+
on_hit: OnHit,
273+
) -> Result<R, QueryLookup>
274+
where
275+
OnHit: FnOnce(&V, DepNodeIndex) -> R,
276+
{
277+
let _ = Self::KEY_IS_ZST;
278+
279+
let lock = state.shards.get_shard_by_index(0).lock();
280+
if let Some((_key, val, dep_node)) = lock.get() {
281+
Ok(on_hit(&val, dep_node))
282+
} else {
283+
Err(QueryLookup {
284+
key_hash: 0,
285+
shard: 0
286+
})
287+
}
288+
}
289+
290+
#[inline]
291+
fn complete(
292+
&self,
293+
lock_sharded_storage: &mut Self::Sharded,
294+
key: K,
295+
value: V,
296+
index: DepNodeIndex,
297+
) -> Self::Stored {
298+
lock_sharded_storage.set(Some((key, value, index)));
299+
value
300+
}
301+
302+
fn iter(
303+
&self,
304+
shards: &Sharded<Self::Sharded>,
305+
f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
306+
) {
307+
let lock = shards.get_shard_by_index(0).lock();
308+
if let Some((key, val, dep_node)) = lock.get() {
309+
f(&key, &val, dep_node);
310+
}
311+
}
312+
}

compiler/rustc_query_system/src/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub use self::job::{print_query_stack, QueryInfo, QueryJob, QueryJobId, QueryJob
88

99
mod caches;
1010
pub use self::caches::{
11-
ArenaCacheSelector, CacheSelector, DefaultCacheSelector, QueryCache, QueryStorage,
11+
ArenaCacheSelector, CacheSelector, CellCacheSelector, DefaultCacheSelector, QueryCache, QueryStorage,
1212
};
1313

1414
mod config;

compiler/rustc_query_system/src/query/plumbing.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
3131

3232
pub struct QueryCacheStore<C: QueryCache> {
3333
cache: C,
34-
shards: Sharded<C::Sharded>,
34+
pub(super) shards: Sharded<C::Sharded>,
3535
#[cfg(debug_assertions)]
3636
pub cache_hits: AtomicUsize,
3737
}
@@ -50,7 +50,7 @@ impl<C: QueryCache + Default> Default for QueryCacheStore<C> {
5050
/// Values used when checking a query cache which can be reused on a cache-miss to execute the query.
5151
pub struct QueryLookup {
5252
pub(super) key_hash: u64,
53-
shard: usize,
53+
pub(super) shard: usize,
5454
}
5555

5656
// We compute the key's hash once and then use it for both the

0 commit comments

Comments
 (0)