@@ -5,8 +5,12 @@ use crate::ty::TyCtxt;
5
5
6
6
use rustc_data_structures:: fx:: FxHashMap ;
7
7
use rustc_data_structures:: sharded:: Sharded ;
8
+ use rustc_hir:: def_id:: { DefId , DefIndex , LOCAL_CRATE } ;
9
+ use rustc_index:: vec:: IndexVec ;
10
+ use std:: cell:: RefCell ;
8
11
use std:: default:: Default ;
9
12
use std:: hash:: Hash ;
13
+ use std:: marker:: PhantomData ;
10
14
11
15
pub ( crate ) trait CacheSelector < K , V > {
12
16
type Cache : QueryCache < K , V > ;
@@ -54,13 +58,18 @@ pub(crate) trait QueryCache<K, V>: Default {
54
58
pub struct DefaultCacheSelector ;
55
59
56
60
impl < K : Eq + Hash , V : Clone > CacheSelector < K , V > for DefaultCacheSelector {
57
- type Cache = DefaultCache ;
61
+ type Cache = DefaultCache < ( ) > ;
58
62
}
59
63
60
- #[ derive( Default ) ]
61
- pub struct DefaultCache ;
64
+ pub struct DefaultCache < D > ( PhantomData < D > ) ;
62
65
63
- impl < K : Eq + Hash , V : Clone > QueryCache < K , V > for DefaultCache {
66
+ impl < D > Default for DefaultCache < D > {
67
+ fn default ( ) -> Self {
68
+ DefaultCache ( PhantomData )
69
+ }
70
+ }
71
+
72
+ impl < D , K : Eq + Hash , V : Clone > QueryCache < K , V > for DefaultCache < D > {
64
73
type Sharded = FxHashMap < K , ( V , DepNodeIndex ) > ;
65
74
66
75
#[ inline( always) ]
@@ -110,3 +119,88 @@ impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
110
119
f ( Box :: new ( results) )
111
120
}
112
121
}
122
+
123
+ #[ cfg( parallel_compiler) ]
124
+ pub type LocalDenseDefIdCacheSelector < V > = DefaultCache < V > ;
125
+ #[ cfg( not( parallel_compiler) ) ]
126
+ pub type LocalDenseDefIdCacheSelector < V > = LocalDenseDefIdCache < V > ;
127
+
128
+ pub struct LocalDenseDefIdCache < V > {
129
+ local : RefCell < IndexVec < DefIndex , Option < ( V , DepNodeIndex ) > > > ,
130
+ other : DefaultCache < ( ) > ,
131
+ }
132
+
133
+ impl < V > Default for LocalDenseDefIdCache < V > {
134
+ fn default ( ) -> Self {
135
+ LocalDenseDefIdCache { local : RefCell :: new ( IndexVec :: new ( ) ) , other : Default :: default ( ) }
136
+ }
137
+ }
138
+
139
+ impl < V : Clone > QueryCache < DefId , V > for LocalDenseDefIdCache < V > {
140
+ type Sharded = <DefaultCache < ( ) > as QueryCache < DefId , V > >:: Sharded ;
141
+
142
+ #[ inline( always) ]
143
+ fn lookup < ' tcx , R , GetCache , OnHit , OnMiss , Q > (
144
+ & self ,
145
+ state : & ' tcx QueryState < ' tcx , Q > ,
146
+ get_cache : GetCache ,
147
+ key : DefId ,
148
+ on_hit : OnHit ,
149
+ on_miss : OnMiss ,
150
+ ) -> R
151
+ where
152
+ Q : QueryAccessors < ' tcx > ,
153
+ GetCache : for < ' a > Fn ( & ' a mut QueryStateShard < ' tcx , Q > ) -> & ' a mut Self :: Sharded ,
154
+ OnHit : FnOnce ( & V , DepNodeIndex ) -> R ,
155
+ OnMiss : FnOnce ( DefId , QueryLookup < ' tcx , Q > ) -> R ,
156
+ {
157
+ if key. krate == LOCAL_CRATE {
158
+ let local = self . local . borrow ( ) ;
159
+ if let Some ( result) = local. get ( key. index ) . and_then ( |v| v. as_ref ( ) ) {
160
+ on_hit ( & result. 0 , result. 1 )
161
+ } else {
162
+ drop ( local) ;
163
+ let lookup = state. get_lookup ( & key) ;
164
+ on_miss ( key, lookup)
165
+ }
166
+ } else {
167
+ self . other . lookup ( state, get_cache, key, on_hit, on_miss)
168
+ }
169
+ }
170
+
171
+ #[ inline]
172
+ fn complete (
173
+ & self ,
174
+ tcx : TyCtxt < ' tcx > ,
175
+ lock_sharded_storage : & mut Self :: Sharded ,
176
+ key : DefId ,
177
+ value : V ,
178
+ index : DepNodeIndex ,
179
+ ) {
180
+ if key. krate == LOCAL_CRATE {
181
+ let mut local = self . local . borrow_mut ( ) ;
182
+ if local. raw . capacity ( ) == 0 {
183
+ * local = IndexVec :: from_elem_n ( None , tcx. hir ( ) . definitions ( ) . def_index_count ( ) ) ;
184
+ }
185
+ local[ key. index ] = Some ( ( value, index) ) ;
186
+ } else {
187
+ self . other . complete ( tcx, lock_sharded_storage, key, value, index) ;
188
+ }
189
+ }
190
+
191
+ fn iter < R , L > (
192
+ & self ,
193
+ shards : & Sharded < L > ,
194
+ get_shard : impl Fn ( & mut L ) -> & mut Self :: Sharded ,
195
+ f : impl for < ' a > FnOnce ( Box < dyn Iterator < Item = ( & ' a DefId , & ' a V , DepNodeIndex ) > + ' a > ) -> R ,
196
+ ) -> R {
197
+ let local = self . local . borrow ( ) ;
198
+ let local: Vec < ( DefId , & V , DepNodeIndex ) > = local
199
+ . iter_enumerated ( )
200
+ . filter_map ( |( i, e) | e. as_ref ( ) . map ( |e| ( DefId :: local ( i) , & e. 0 , e. 1 ) ) )
201
+ . collect ( ) ;
202
+ self . other . iter ( shards, get_shard, |results| {
203
+ f ( Box :: new ( results. chain ( local. iter ( ) . map ( |( id, v, i) | ( id, * v, * i) ) ) ) )
204
+ } )
205
+ }
206
+ }
0 commit comments