Skip to content

Commit 2e1eb89

Browse files
committed
Add LocalDenseDefIdCache
1 parent 97eda01 commit 2e1eb89

File tree

1 file changed

+98
-4
lines changed

1 file changed

+98
-4
lines changed

src/librustc/ty/query/caches.rs

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ use crate::ty::TyCtxt;
55

66
use rustc_data_structures::fx::FxHashMap;
77
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;
811
use std::default::Default;
912
use std::hash::Hash;
13+
use std::marker::PhantomData;
1014

1115
pub(crate) trait CacheSelector<K, V> {
1216
type Cache: QueryCache<K, V>;
@@ -54,13 +58,18 @@ pub(crate) trait QueryCache<K, V>: Default {
5458
pub struct DefaultCacheSelector;
5559

5660
impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
57-
type Cache = DefaultCache;
61+
type Cache = DefaultCache<()>;
5862
}
5963

60-
#[derive(Default)]
61-
pub struct DefaultCache;
64+
pub struct DefaultCache<D>(PhantomData<D>);
6265

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> {
6473
type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
6574

6675
#[inline(always)]
@@ -110,3 +119,88 @@ impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
110119
f(Box::new(results))
111120
}
112121
}
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

Comments
 (0)