]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_query_system/src/query/caches.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_query_system / src / query / caches.rs
CommitLineData
74b04a01 1use crate::dep_graph::DepNodeIndex;
74b04a01
XL
2
3use rustc_data_structures::fx::FxHashMap;
5e7ed085
FG
4use rustc_data_structures::sharded;
5#[cfg(parallel_compiler)]
74b04a01 6use rustc_data_structures::sharded::Sharded;
5e7ed085 7use rustc_data_structures::sync::Lock;
49aad941 8use rustc_index::{Idx, IndexVec};
29967ef6 9use std::fmt::Debug;
74b04a01 10use std::hash::Hash;
ba9703b0 11use std::marker::PhantomData;
74b04a01 12
487cf647
FG
13pub trait CacheSelector<'tcx, V> {
14 type Cache
15 where
9ffffee4 16 V: Copy;
74b04a01
XL
17}
18
353b0b11 19pub trait QueryCache: Sized {
9ffffee4 20 type Key: Hash + Eq + Copy + Debug;
353b0b11 21 type Value: Copy;
74b04a01
XL
22
23 /// Checks if the query is already computed and in the cache.
9ffffee4 24 fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
74b04a01 25
9ffffee4 26 fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex);
74b04a01 27
5e7ed085 28 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
74b04a01
XL
29}
30
487cf647 31pub struct DefaultCacheSelector<K>(PhantomData<K>);
74b04a01 32
487cf647
FG
33impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<'tcx, V> for DefaultCacheSelector<K> {
34 type Cache = DefaultCache<K, V>
35 where
9ffffee4 36 V: Copy;
74b04a01
XL
37}
38
5e7ed085
FG
39pub struct DefaultCache<K, V> {
40 #[cfg(parallel_compiler)]
41 cache: Sharded<FxHashMap<K, (V, DepNodeIndex)>>,
42 #[cfg(not(parallel_compiler))]
43 cache: Lock<FxHashMap<K, (V, DepNodeIndex)>>,
44}
ba9703b0
XL
45
46impl<K, V> Default for DefaultCache<K, V> {
47 fn default() -> Self {
5e7ed085 48 DefaultCache { cache: Default::default() }
ba9703b0
XL
49 }
50}
74b04a01 51
29967ef6
XL
52impl<K, V> QueryCache for DefaultCache<K, V>
53where
9ffffee4 54 K: Eq + Hash + Copy + Debug,
353b0b11 55 V: Copy,
29967ef6 56{
ba9703b0 57 type Key = K;
353b0b11 58 type Value = V;
74b04a01
XL
59
60 #[inline(always)]
9ffffee4 61 fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
5e7ed085
FG
62 let key_hash = sharded::make_hash(key);
63 #[cfg(parallel_compiler)]
64 let lock = self.cache.get_shard_by_hash(key_hash).lock();
65 #[cfg(not(parallel_compiler))]
66 let lock = self.cache.lock();
67 let result = lock.raw_entry().from_key_hashed_nocheck(key_hash, key);
74b04a01 68
9ffffee4 69 if let Some((_, value)) = result { Some(*value) } else { None }
74b04a01
XL
70 }
71
72 #[inline]
9ffffee4 73 fn complete(&self, key: K, value: V, index: DepNodeIndex) {
5e7ed085
FG
74 #[cfg(parallel_compiler)]
75 let mut lock = self.cache.get_shard_by_value(&key).lock();
76 #[cfg(not(parallel_compiler))]
77 let mut lock = self.cache.lock();
9c376795 78 // We may be overwriting another value. This is all right, since the dep-graph
487cf647 79 // will check that the fingerprint matches.
9ffffee4 80 lock.insert(key, (value, index));
f9f354fc
XL
81 }
82
5e7ed085
FG
83 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
84 #[cfg(parallel_compiler)]
85 {
86 let shards = self.cache.lock_shards();
87 for shard in shards.iter() {
88 for (k, v) in shard.iter() {
89 f(k, &v.0, v.1);
90 }
91 }
92 }
93 #[cfg(not(parallel_compiler))]
94 {
95 let map = self.cache.lock();
96 for (k, v) in map.iter() {
cdc7bbd5
XL
97 f(k, &v.0, v.1);
98 }
99 }
f9f354fc
XL
100 }
101}
102
9ffffee4
FG
103pub struct SingleCacheSelector;
104
105impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector {
106 type Cache = SingleCache<V>
107 where
108 V: Copy;
f9f354fc
XL
109}
110
9ffffee4
FG
111pub struct SingleCache<V> {
112 cache: Lock<Option<(V, DepNodeIndex)>>,
113}
114
115impl<V> Default for SingleCache<V> {
f9f354fc 116 fn default() -> Self {
9ffffee4 117 SingleCache { cache: Lock::new(None) }
f9f354fc
XL
118 }
119}
120
9ffffee4 121impl<V> QueryCache for SingleCache<V>
29967ef6 122where
353b0b11 123 V: Copy,
29967ef6 124{
9ffffee4 125 type Key = ();
353b0b11 126 type Value = V;
f9f354fc
XL
127
128 #[inline(always)]
9ffffee4
FG
129 fn lookup(&self, _key: &()) -> Option<(V, DepNodeIndex)> {
130 *self.cache.lock()
f9f354fc
XL
131 }
132
133 #[inline]
9ffffee4
FG
134 fn complete(&self, _key: (), value: V, index: DepNodeIndex) {
135 *self.cache.lock() = Some((value, index));
74b04a01
XL
136 }
137
5e7ed085 138 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
353b0b11
FG
139 if let Some(value) = self.cache.lock().as_ref() {
140 f(&(), &value.0, value.1)
141 }
74b04a01
XL
142 }
143}
487cf647
FG
144
145pub struct VecCacheSelector<K>(PhantomData<K>);
146
147impl<'tcx, K: Idx, V: 'tcx> CacheSelector<'tcx, V> for VecCacheSelector<K> {
148 type Cache = VecCache<K, V>
149 where
9ffffee4 150 V: Copy;
487cf647
FG
151}
152
153pub struct VecCache<K: Idx, V> {
154 #[cfg(parallel_compiler)]
155 cache: Sharded<IndexVec<K, Option<(V, DepNodeIndex)>>>,
156 #[cfg(not(parallel_compiler))]
157 cache: Lock<IndexVec<K, Option<(V, DepNodeIndex)>>>,
158}
159
160impl<K: Idx, V> Default for VecCache<K, V> {
161 fn default() -> Self {
162 VecCache { cache: Default::default() }
163 }
164}
165
487cf647
FG
166impl<K, V> QueryCache for VecCache<K, V>
167where
9ffffee4 168 K: Eq + Idx + Copy + Debug,
353b0b11 169 V: Copy,
487cf647
FG
170{
171 type Key = K;
353b0b11 172 type Value = V;
487cf647
FG
173
174 #[inline(always)]
9ffffee4 175 fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
487cf647
FG
176 #[cfg(parallel_compiler)]
177 let lock = self.cache.get_shard_by_hash(key.index() as u64).lock();
178 #[cfg(not(parallel_compiler))]
179 let lock = self.cache.lock();
9ffffee4 180 if let Some(Some(value)) = lock.get(*key) { Some(*value) } else { None }
487cf647
FG
181 }
182
183 #[inline]
9ffffee4 184 fn complete(&self, key: K, value: V, index: DepNodeIndex) {
487cf647
FG
185 #[cfg(parallel_compiler)]
186 let mut lock = self.cache.get_shard_by_hash(key.index() as u64).lock();
187 #[cfg(not(parallel_compiler))]
188 let mut lock = self.cache.lock();
9ffffee4 189 lock.insert(key, (value, index));
487cf647
FG
190 }
191
192 fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
193 #[cfg(parallel_compiler)]
194 {
195 let shards = self.cache.lock_shards();
196 for shard in shards.iter() {
197 for (k, v) in shard.iter_enumerated() {
198 if let Some(v) = v {
199 f(&k, &v.0, v.1);
200 }
201 }
202 }
203 }
204 #[cfg(not(parallel_compiler))]
205 {
206 let map = self.cache.lock();
207 for (k, v) in map.iter_enumerated() {
208 if let Some(v) = v {
209 f(&k, &v.0, v.1);
210 }
211 }
212 }
213 }
214}