Skip to content

Commit 8deeac1

Browse files
authored
Rollup merge of #69910 - cjgillot:polym, r=Zoxc
Avoid query type in generics There are at the moment roughly 170 queries in librustc. The way ty::query is structured, a lot of code is duplicated for each query. I suspect this to be responsible for a part of librustc'c compile time. This PR reduces the amount of code generic on the query, replacing it by code generic on the key-value types. This is split out of #69808, and should not contain the perf regression. cc #65031
2 parents fd3f917 + 8aa1328 commit 8deeac1

File tree

6 files changed

+226
-201
lines changed

6 files changed

+226
-201
lines changed

src/librustc/ty/query/caches.rs

+34-22
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,94 @@
11
use crate::dep_graph::DepNodeIndex;
2-
use crate::ty::query::config::QueryAccessors;
32
use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard};
43
use crate::ty::TyCtxt;
54

65
use rustc_data_structures::fx::FxHashMap;
76
use rustc_data_structures::sharded::Sharded;
87
use std::default::Default;
98
use std::hash::Hash;
9+
use std::marker::PhantomData;
1010

1111
pub(crate) trait CacheSelector<K, V> {
12-
type Cache: QueryCache<K, V>;
12+
type Cache: QueryCache<Key = K, Value = V>;
1313
}
1414

15-
pub(crate) trait QueryCache<K, V>: Default {
15+
pub(crate) trait QueryCache: Default {
16+
type Key;
17+
type Value;
1618
type Sharded: Default;
1719

1820
/// Checks if the query is already computed and in the cache.
1921
/// It returns the shard index and a lock guard to the shard,
2022
/// which will be used if the query is not in the cache and we need
2123
/// to compute it.
22-
fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
24+
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
2325
&self,
24-
state: &'tcx QueryState<'tcx, Q>,
26+
state: &'tcx QueryState<'tcx, Self>,
2527
get_cache: GetCache,
26-
key: K,
28+
key: Self::Key,
2729
// `on_hit` can be called while holding a lock to the query state shard.
2830
on_hit: OnHit,
2931
on_miss: OnMiss,
3032
) -> R
3133
where
32-
Q: QueryAccessors<'tcx>,
33-
GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
34-
OnHit: FnOnce(&V, DepNodeIndex) -> R,
35-
OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R;
34+
GetCache: for<'a> Fn(
35+
&'a mut QueryStateShard<'tcx, Self::Key, Self::Sharded>,
36+
) -> &'a mut Self::Sharded,
37+
OnHit: FnOnce(&Self::Value, DepNodeIndex) -> R,
38+
OnMiss: FnOnce(Self::Key, QueryLookup<'tcx, Self::Key, Self::Sharded>) -> R;
3639

3740
fn complete(
3841
&self,
3942
tcx: TyCtxt<'tcx>,
4043
lock_sharded_storage: &mut Self::Sharded,
41-
key: K,
42-
value: V,
44+
key: Self::Key,
45+
value: Self::Value,
4346
index: DepNodeIndex,
4447
);
4548

4649
fn iter<R, L>(
4750
&self,
4851
shards: &Sharded<L>,
4952
get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
50-
f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
53+
f: impl for<'a> FnOnce(
54+
Box<dyn Iterator<Item = (&'a Self::Key, &'a Self::Value, DepNodeIndex)> + 'a>,
55+
) -> R,
5156
) -> R;
5257
}
5358

5459
pub struct DefaultCacheSelector;
5560

5661
impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
57-
type Cache = DefaultCache;
62+
type Cache = DefaultCache<K, V>;
5863
}
5964

60-
#[derive(Default)]
61-
pub struct DefaultCache;
65+
pub struct DefaultCache<K, V>(PhantomData<(K, V)>);
66+
67+
impl<K, V> Default for DefaultCache<K, V> {
68+
fn default() -> Self {
69+
DefaultCache(PhantomData)
70+
}
71+
}
6272

63-
impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
73+
impl<K: Eq + Hash, V: Clone> QueryCache for DefaultCache<K, V> {
74+
type Key = K;
75+
type Value = V;
6476
type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
6577

6678
#[inline(always)]
67-
fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
79+
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
6880
&self,
69-
state: &'tcx QueryState<'tcx, Q>,
81+
state: &'tcx QueryState<'tcx, Self>,
7082
get_cache: GetCache,
7183
key: K,
7284
on_hit: OnHit,
7385
on_miss: OnMiss,
7486
) -> R
7587
where
76-
Q: QueryAccessors<'tcx>,
77-
GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
88+
GetCache:
89+
for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded,
7890
OnHit: FnOnce(&V, DepNodeIndex) -> R,
79-
OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R,
91+
OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R,
8092
{
8193
let mut lookup = state.get_lookup(&key);
8294
let lock = &mut *lookup.lock;

src/librustc/ty/query/config.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::dep_graph::SerializedDepNodeIndex;
22
use crate::dep_graph::{DepKind, DepNode};
33
use crate::ty::query::caches::QueryCache;
44
use crate::ty::query::plumbing::CycleError;
5-
use crate::ty::query::{Query, QueryState};
5+
use crate::ty::query::QueryState;
66
use crate::ty::TyCtxt;
77
use rustc_data_structures::profiling::ProfileCategory;
88
use rustc_hir::def_id::DefId;
@@ -28,18 +28,15 @@ pub trait QueryConfig<'tcx> {
2828
pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
2929
const ANON: bool;
3030
const EVAL_ALWAYS: bool;
31+
const DEP_KIND: DepKind;
3132

32-
type Cache: QueryCache<Self::Key, Self::Value>;
33-
34-
fn query(key: Self::Key) -> Query<'tcx>;
33+
type Cache: QueryCache<Key = Self::Key, Value = Self::Value>;
3534

3635
// Don't use this method to access query results, instead use the methods on TyCtxt
37-
fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>;
36+
fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self::Cache>;
3837

3938
fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
4039

41-
fn dep_kind() -> DepKind;
42-
4340
// Don't use this method to compute query results, instead use the methods on TyCtxt
4441
fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value;
4542

@@ -62,10 +59,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
6259
}
6360
}
6461

65-
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M
66-
where
67-
<M as QueryAccessors<'tcx>>::Cache: QueryCache<DefId, <M as QueryConfig<'tcx>>::Value>,
68-
{
62+
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
6963
default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> {
7064
if !tcx.sess.verbose() {
7165
format!("processing `{}`", tcx.def_path_str(def_id)).into()

src/librustc/ty/query/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,12 @@ use rustc_span::symbol::Symbol;
5656
use rustc_span::{Span, DUMMY_SP};
5757
use std::borrow::Cow;
5858
use std::collections::BTreeMap;
59-
use std::convert::TryFrom;
6059
use std::ops::Deref;
6160
use std::sync::Arc;
6261

6362
#[macro_use]
6463
mod plumbing;
65-
pub use self::plumbing::CycleError;
64+
pub(crate) use self::plumbing::CycleError;
6665
use self::plumbing::*;
6766

6867
mod stats;

0 commit comments

Comments
 (0)