Skip to content

Commit e2a8589

Browse files
committed
Add an abstraction for custom query caches
1 parent 6bf014e commit e2a8589

File tree

7 files changed

+305
-123
lines changed

7 files changed

+305
-123
lines changed

src/librustc/ty/query/caches.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
use crate::dep_graph::DepNodeIndex;
2+
use crate::ty::query::config::QueryAccessors;
3+
use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard};
4+
use crate::ty::TyCtxt;
5+
6+
use rustc_data_structures::fx::FxHashMap;
7+
use rustc_data_structures::sharded::Sharded;
8+
use std::default::Default;
9+
use std::hash::Hash;
10+
11+
pub(crate) trait CacheSelector<K, V> {
12+
type Cache: QueryCache<K, V>;
13+
}
14+
15+
pub(crate) trait QueryCache<K, V>: Default {
16+
type Sharded: Default;
17+
18+
/// Checks if the query is already computed and in the cache.
19+
/// It returns the shard index and a lock guard to the shard,
20+
/// which will be used if the query is not in the cache and we need
21+
/// to compute it.
22+
fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
23+
&self,
24+
state: &'tcx QueryState<'tcx, Q>,
25+
get_cache: GetCache,
26+
key: K,
27+
// `on_hit` can be called while holding a lock to the query state shard.
28+
on_hit: OnHit,
29+
on_miss: OnMiss,
30+
) -> R
31+
where
32+
Q: QueryAccessors<'tcx>,
33+
GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
34+
OnHit: FnOnce(&V, DepNodeIndex) -> R,
35+
OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R;
36+
37+
fn complete(
38+
&self,
39+
tcx: TyCtxt<'tcx>,
40+
lock_sharded_storage: &mut Self::Sharded,
41+
key: K,
42+
value: V,
43+
index: DepNodeIndex,
44+
);
45+
46+
fn iter<R, L>(
47+
&self,
48+
shards: &Sharded<L>,
49+
get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
50+
f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
51+
) -> R;
52+
}
53+
54+
pub struct DefaultCacheSelector;
55+
56+
impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
57+
type Cache = DefaultCache;
58+
}
59+
60+
#[derive(Default)]
61+
pub struct DefaultCache;
62+
63+
impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
64+
type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
65+
66+
#[inline(always)]
67+
fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
68+
&self,
69+
state: &'tcx QueryState<'tcx, Q>,
70+
get_cache: GetCache,
71+
key: K,
72+
on_hit: OnHit,
73+
on_miss: OnMiss,
74+
) -> R
75+
where
76+
Q: QueryAccessors<'tcx>,
77+
GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
78+
OnHit: FnOnce(&V, DepNodeIndex) -> R,
79+
OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R,
80+
{
81+
let mut lookup = state.get_lookup(&key);
82+
let lock = &mut *lookup.lock;
83+
84+
let result = get_cache(lock).raw_entry().from_key_hashed_nocheck(lookup.key_hash, &key);
85+
86+
if let Some((_, value)) = result { on_hit(&value.0, value.1) } else { on_miss(key, lookup) }
87+
}
88+
89+
#[inline]
90+
fn complete(
91+
&self,
92+
_: TyCtxt<'tcx>,
93+
lock_sharded_storage: &mut Self::Sharded,
94+
key: K,
95+
value: V,
96+
index: DepNodeIndex,
97+
) {
98+
lock_sharded_storage.insert(key, (value, index));
99+
}
100+
101+
fn iter<R, L>(
102+
&self,
103+
shards: &Sharded<L>,
104+
get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
105+
f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
106+
) -> R {
107+
let mut shards = shards.lock_shards();
108+
let mut shards: Vec<_> = shards.iter_mut().map(|shard| get_shard(shard)).collect();
109+
let results = shards.iter_mut().flat_map(|shard| shard.iter()).map(|(k, v)| (k, &v.0, v.1));
110+
f(Box::new(results))
111+
}
112+
}

src/librustc/ty/query/config.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use crate::dep_graph::SerializedDepNodeIndex;
22
use crate::dep_graph::{DepKind, DepNode};
3+
use crate::ty::query::caches::QueryCache;
34
use crate::ty::query::plumbing::CycleError;
45
use crate::ty::query::queries;
5-
use crate::ty::query::{Query, QueryCache};
6+
use crate::ty::query::{Query, QueryState};
67
use crate::ty::TyCtxt;
78
use rustc_data_structures::profiling::ProfileCategory;
89
use rustc_hir::def_id::{CrateNum, DefId};
910

1011
use crate::ich::StableHashingContext;
1112
use rustc_data_structures::fingerprint::Fingerprint;
12-
use rustc_data_structures::sharded::Sharded;
1313
use std::borrow::Cow;
1414
use std::fmt::Debug;
1515
use std::hash::Hash;
@@ -30,10 +30,12 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
3030
const ANON: bool;
3131
const EVAL_ALWAYS: bool;
3232

33+
type Cache: QueryCache<Self::Key, Self::Value>;
34+
3335
fn query(key: Self::Key) -> Query<'tcx>;
3436

3537
// Don't use this method to access query results, instead use the methods on TyCtxt
36-
fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Sharded<QueryCache<'tcx, Self>>;
38+
fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>;
3739

3840
fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
3941

@@ -61,7 +63,10 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
6163
}
6264
}
6365

64-
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
66+
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M
67+
where
68+
<M as QueryAccessors<'tcx>>::Cache: QueryCache<DefId, <M as QueryConfig<'tcx>>::Value>,
69+
{
6570
default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> {
6671
if !tcx.sess.verbose() {
6772
format!("processing `{}`", tcx.def_path_str(def_id)).into()

src/librustc/ty/query/keys.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::infer::canonical::Canonical;
44
use crate::mir;
55
use crate::traits;
66
use crate::ty::fast_reject::SimplifiedType;
7+
use crate::ty::query::caches::DefaultCacheSelector;
78
use crate::ty::subst::SubstsRef;
89
use crate::ty::{self, Ty, TyCtxt};
910
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
@@ -12,7 +13,9 @@ use rustc_span::{Span, DUMMY_SP};
1213

1314
/// The `Key` trait controls what types can legally be used as the key
1415
/// for a query.
15-
pub(super) trait Key {
16+
pub trait Key {
17+
type CacheSelector;
18+
1619
/// Given an instance of this key, what crate is it referring to?
1720
/// This is used to find the provider.
1821
fn query_crate(&self) -> CrateNum;
@@ -23,6 +26,8 @@ pub(super) trait Key {
2326
}
2427

2528
impl<'tcx> Key for ty::InstanceDef<'tcx> {
29+
type CacheSelector = DefaultCacheSelector;
30+
2631
fn query_crate(&self) -> CrateNum {
2732
LOCAL_CRATE
2833
}
@@ -33,6 +38,8 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> {
3338
}
3439

3540
impl<'tcx> Key for ty::Instance<'tcx> {
41+
type CacheSelector = DefaultCacheSelector;
42+
3643
fn query_crate(&self) -> CrateNum {
3744
LOCAL_CRATE
3845
}
@@ -43,6 +50,8 @@ impl<'tcx> Key for ty::Instance<'tcx> {
4350
}
4451

4552
impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
53+
type CacheSelector = DefaultCacheSelector;
54+
4655
fn query_crate(&self) -> CrateNum {
4756
self.instance.query_crate()
4857
}
@@ -53,6 +62,8 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
5362
}
5463

5564
impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> {
65+
type CacheSelector = DefaultCacheSelector;
66+
5667
fn query_crate(&self) -> CrateNum {
5768
LOCAL_CRATE
5869
}
@@ -63,6 +74,8 @@ impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> {
6374
}
6475

6576
impl Key for CrateNum {
77+
type CacheSelector = DefaultCacheSelector;
78+
6679
fn query_crate(&self) -> CrateNum {
6780
*self
6881
}
@@ -72,6 +85,8 @@ impl Key for CrateNum {
7285
}
7386

7487
impl Key for DefIndex {
88+
type CacheSelector = DefaultCacheSelector;
89+
7590
fn query_crate(&self) -> CrateNum {
7691
LOCAL_CRATE
7792
}
@@ -81,6 +96,8 @@ impl Key for DefIndex {
8196
}
8297

8398
impl Key for DefId {
99+
type CacheSelector = DefaultCacheSelector;
100+
84101
fn query_crate(&self) -> CrateNum {
85102
self.krate
86103
}
@@ -90,6 +107,8 @@ impl Key for DefId {
90107
}
91108

92109
impl Key for (DefId, DefId) {
110+
type CacheSelector = DefaultCacheSelector;
111+
93112
fn query_crate(&self) -> CrateNum {
94113
self.0.krate
95114
}
@@ -99,6 +118,8 @@ impl Key for (DefId, DefId) {
99118
}
100119

101120
impl Key for (CrateNum, DefId) {
121+
type CacheSelector = DefaultCacheSelector;
122+
102123
fn query_crate(&self) -> CrateNum {
103124
self.0
104125
}
@@ -108,6 +129,8 @@ impl Key for (CrateNum, DefId) {
108129
}
109130

110131
impl Key for (DefId, SimplifiedType) {
132+
type CacheSelector = DefaultCacheSelector;
133+
111134
fn query_crate(&self) -> CrateNum {
112135
self.0.krate
113136
}
@@ -117,6 +140,8 @@ impl Key for (DefId, SimplifiedType) {
117140
}
118141

119142
impl<'tcx> Key for SubstsRef<'tcx> {
143+
type CacheSelector = DefaultCacheSelector;
144+
120145
fn query_crate(&self) -> CrateNum {
121146
LOCAL_CRATE
122147
}
@@ -126,6 +151,8 @@ impl<'tcx> Key for SubstsRef<'tcx> {
126151
}
127152

128153
impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
154+
type CacheSelector = DefaultCacheSelector;
155+
129156
fn query_crate(&self) -> CrateNum {
130157
self.0.krate
131158
}
@@ -135,6 +162,8 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
135162
}
136163

137164
impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
165+
type CacheSelector = DefaultCacheSelector;
166+
138167
fn query_crate(&self) -> CrateNum {
139168
self.1.def_id().krate
140169
}
@@ -144,6 +173,8 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
144173
}
145174

146175
impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) {
176+
type CacheSelector = DefaultCacheSelector;
177+
147178
fn query_crate(&self) -> CrateNum {
148179
LOCAL_CRATE
149180
}
@@ -153,6 +184,8 @@ impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) {
153184
}
154185

155186
impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
187+
type CacheSelector = DefaultCacheSelector;
188+
156189
fn query_crate(&self) -> CrateNum {
157190
self.def_id().krate
158191
}
@@ -162,6 +195,8 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
162195
}
163196

164197
impl<'tcx> Key for &'tcx ty::Const<'tcx> {
198+
type CacheSelector = DefaultCacheSelector;
199+
165200
fn query_crate(&self) -> CrateNum {
166201
LOCAL_CRATE
167202
}
@@ -171,6 +206,8 @@ impl<'tcx> Key for &'tcx ty::Const<'tcx> {
171206
}
172207

173208
impl<'tcx> Key for Ty<'tcx> {
209+
type CacheSelector = DefaultCacheSelector;
210+
174211
fn query_crate(&self) -> CrateNum {
175212
LOCAL_CRATE
176213
}
@@ -180,6 +217,8 @@ impl<'tcx> Key for Ty<'tcx> {
180217
}
181218

182219
impl<'tcx> Key for ty::ParamEnv<'tcx> {
220+
type CacheSelector = DefaultCacheSelector;
221+
183222
fn query_crate(&self) -> CrateNum {
184223
LOCAL_CRATE
185224
}
@@ -189,6 +228,8 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> {
189228
}
190229

191230
impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
231+
type CacheSelector = DefaultCacheSelector;
232+
192233
fn query_crate(&self) -> CrateNum {
193234
self.value.query_crate()
194235
}
@@ -198,6 +239,8 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
198239
}
199240

200241
impl<'tcx> Key for traits::Environment<'tcx> {
242+
type CacheSelector = DefaultCacheSelector;
243+
201244
fn query_crate(&self) -> CrateNum {
202245
LOCAL_CRATE
203246
}
@@ -207,6 +250,8 @@ impl<'tcx> Key for traits::Environment<'tcx> {
207250
}
208251

209252
impl Key for Symbol {
253+
type CacheSelector = DefaultCacheSelector;
254+
210255
fn query_crate(&self) -> CrateNum {
211256
LOCAL_CRATE
212257
}
@@ -218,6 +263,8 @@ impl Key for Symbol {
218263
/// Canonical query goals correspond to abstract trait operations that
219264
/// are not tied to any crate in particular.
220265
impl<'tcx, T> Key for Canonical<'tcx, T> {
266+
type CacheSelector = DefaultCacheSelector;
267+
221268
fn query_crate(&self) -> CrateNum {
222269
LOCAL_CRATE
223270
}
@@ -228,6 +275,8 @@ impl<'tcx, T> Key for Canonical<'tcx, T> {
228275
}
229276

230277
impl Key for (Symbol, u32, u32) {
278+
type CacheSelector = DefaultCacheSelector;
279+
231280
fn query_crate(&self) -> CrateNum {
232281
LOCAL_CRATE
233282
}

src/librustc/ty/query/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ use self::keys::Key;
7676
mod values;
7777
use self::values::Value;
7878

79+
mod caches;
80+
use self::caches::CacheSelector;
81+
7982
mod config;
8083
use self::config::QueryAccessors;
8184
pub use self::config::QueryConfig;

0 commit comments

Comments
 (0)