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