rustc_middle/query/
caches.rs1use std::fmt::Debug;
2use std::hash::Hash;
3use std::sync::OnceLock;
4
5use rustc_data_structures::sharded::ShardedHashMap;
6use rustc_data_structures::stable_hasher::HashStable;
7pub use rustc_data_structures::vec_cache::VecCache;
8use rustc_hir::def_id::LOCAL_CRATE;
9use rustc_index::Idx;
10use rustc_query_system::ich::StableHashingContext;
11use rustc_span::def_id::{DefId, DefIndex};
12
13use crate::dep_graph::DepNodeIndex;
14
15pub trait QueryCacheKey = Hash + Eq + Copy + Debug + for<'a> HashStable<StableHashingContext<'a>>;
17
18pub trait QueryCache: Sized {
24 type Key: QueryCacheKey;
25 type Value: Copy;
26
27 fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
30
31 fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex);
36
37 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
38
39 fn len(&self) -> usize;
40}
41
42pub struct DefaultCache<K, V> {
45 cache: ShardedHashMap<K, (V, DepNodeIndex)>,
46}
47
48impl<K, V> Default for DefaultCache<K, V> {
49 fn default() -> Self {
50 DefaultCache { cache: Default::default() }
51 }
52}
53
54impl<K, V> QueryCache for DefaultCache<K, V>
55where
56 K: QueryCacheKey,
57 V: Copy,
58{
59 type Key = K;
60 type Value = V;
61
62 #[inline(always)]
63 fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
64 self.cache.get(key)
65 }
66
67 #[inline]
68 fn complete(&self, key: K, value: V, index: DepNodeIndex) {
69 self.cache.insert(key, (value, index));
72 }
73
74 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
75 for shard in self.cache.lock_shards() {
76 for (k, v) in shard.iter() {
77 f(k, &v.0, v.1);
78 }
79 }
80 }
81
82 fn len(&self) -> usize {
83 self.cache.len()
84 }
85}
86
87pub struct SingleCache<V> {
90 cache: OnceLock<(V, DepNodeIndex)>,
91}
92
93impl<V> Default for SingleCache<V> {
94 fn default() -> Self {
95 SingleCache { cache: OnceLock::new() }
96 }
97}
98
99impl<V> QueryCache for SingleCache<V>
100where
101 V: Copy,
102{
103 type Key = ();
104 type Value = V;
105
106 #[inline(always)]
107 fn lookup(&self, _key: &()) -> Option<(V, DepNodeIndex)> {
108 self.cache.get().copied()
109 }
110
111 #[inline]
112 fn complete(&self, _key: (), value: V, index: DepNodeIndex) {
113 self.cache.set((value, index)).ok();
114 }
115
116 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
117 if let Some(value) = self.cache.get() {
118 f(&(), &value.0, value.1)
119 }
120 }
121
122 fn len(&self) -> usize {
123 self.cache.get().is_some().into()
124 }
125}
126
127pub struct DefIdCache<V> {
132 local: VecCache<DefIndex, V, DepNodeIndex>,
135 foreign: DefaultCache<DefId, V>,
136}
137
138impl<V> Default for DefIdCache<V> {
139 fn default() -> Self {
140 DefIdCache { local: Default::default(), foreign: Default::default() }
141 }
142}
143
144impl<V> QueryCache for DefIdCache<V>
145where
146 V: Copy,
147{
148 type Key = DefId;
149 type Value = V;
150
151 #[inline(always)]
152 fn lookup(&self, key: &DefId) -> Option<(V, DepNodeIndex)> {
153 if key.krate == LOCAL_CRATE {
154 self.local.lookup(&key.index)
155 } else {
156 self.foreign.lookup(key)
157 }
158 }
159
160 #[inline]
161 fn complete(&self, key: DefId, value: V, index: DepNodeIndex) {
162 if key.krate == LOCAL_CRATE {
163 self.local.complete(key.index, value, index)
164 } else {
165 self.foreign.complete(key, value, index)
166 }
167 }
168
169 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
170 self.local.iter(&mut |key, value, index| {
171 f(&DefId { krate: LOCAL_CRATE, index: *key }, value, index);
172 });
173 self.foreign.iter(f);
174 }
175
176 fn len(&self) -> usize {
177 self.local.len() + self.foreign.len()
178 }
179}
180
181impl<K, V> QueryCache for VecCache<K, V, DepNodeIndex>
182where
183 K: Idx + QueryCacheKey,
184 V: Copy,
185{
186 type Key = K;
187 type Value = V;
188
189 #[inline(always)]
190 fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
191 self.lookup(key)
192 }
193
194 #[inline]
195 fn complete(&self, key: K, value: V, index: DepNodeIndex) {
196 self.complete(key, value, index)
197 }
198
199 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
200 self.iter(f)
201 }
202
203 fn len(&self) -> usize {
204 self.len()
205 }
206}