Skip to content

Commit

Permalink
Rollup merge of rust-lang#69910 - cjgillot:polym, r=Zoxc
Browse files Browse the repository at this point in the history
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 rust-lang#69808,
and should not contain the perf regression.

cc rust-lang#65031
  • Loading branch information
Centril authored Mar 19, 2020
2 parents 46d8095 + 8aa1328 commit 50656db
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 201 deletions.
56 changes: 34 additions & 22 deletions src/librustc/ty/query/caches.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,94 @@
use crate::dep_graph::DepNodeIndex;
use crate::ty::query::config::QueryAccessors;
use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard};
use crate::ty::TyCtxt;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sharded::Sharded;
use std::default::Default;
use std::hash::Hash;
use std::marker::PhantomData;

pub(crate) trait CacheSelector<K, V> {
type Cache: QueryCache<K, V>;
type Cache: QueryCache<Key = K, Value = V>;
}

pub(crate) trait QueryCache<K, V>: Default {
pub(crate) trait QueryCache: Default {
type Key;
type Value;
type Sharded: Default;

/// Checks if the query is already computed and in the cache.
/// It returns the shard index and a lock guard to the shard,
/// which will be used if the query is not in the cache and we need
/// to compute it.
fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
&self,
state: &'tcx QueryState<'tcx, Q>,
state: &'tcx QueryState<'tcx, Self>,
get_cache: GetCache,
key: K,
key: Self::Key,
// `on_hit` can be called while holding a lock to the query state shard.
on_hit: OnHit,
on_miss: OnMiss,
) -> R
where
Q: QueryAccessors<'tcx>,
GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
OnHit: FnOnce(&V, DepNodeIndex) -> R,
OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R;
GetCache: for<'a> Fn(
&'a mut QueryStateShard<'tcx, Self::Key, Self::Sharded>,
) -> &'a mut Self::Sharded,
OnHit: FnOnce(&Self::Value, DepNodeIndex) -> R,
OnMiss: FnOnce(Self::Key, QueryLookup<'tcx, Self::Key, Self::Sharded>) -> R;

fn complete(
&self,
tcx: TyCtxt<'tcx>,
lock_sharded_storage: &mut Self::Sharded,
key: K,
value: V,
key: Self::Key,
value: Self::Value,
index: DepNodeIndex,
);

fn iter<R, L>(
&self,
shards: &Sharded<L>,
get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
f: impl for<'a> FnOnce(
Box<dyn Iterator<Item = (&'a Self::Key, &'a Self::Value, DepNodeIndex)> + 'a>,
) -> R,
) -> R;
}

pub struct DefaultCacheSelector;

impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
type Cache = DefaultCache;
type Cache = DefaultCache<K, V>;
}

#[derive(Default)]
pub struct DefaultCache;
pub struct DefaultCache<K, V>(PhantomData<(K, V)>);

impl<K, V> Default for DefaultCache<K, V> {
fn default() -> Self {
DefaultCache(PhantomData)
}
}

impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
impl<K: Eq + Hash, V: Clone> QueryCache for DefaultCache<K, V> {
type Key = K;
type Value = V;
type Sharded = FxHashMap<K, (V, DepNodeIndex)>;

#[inline(always)]
fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
&self,
state: &'tcx QueryState<'tcx, Q>,
state: &'tcx QueryState<'tcx, Self>,
get_cache: GetCache,
key: K,
on_hit: OnHit,
on_miss: OnMiss,
) -> R
where
Q: QueryAccessors<'tcx>,
GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
GetCache:
for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded,
OnHit: FnOnce(&V, DepNodeIndex) -> R,
OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R,
OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R,
{
let mut lookup = state.get_lookup(&key);
let lock = &mut *lookup.lock;
Expand Down
16 changes: 5 additions & 11 deletions src/librustc/ty/query/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::dep_graph::SerializedDepNodeIndex;
use crate::dep_graph::{DepKind, DepNode};
use crate::ty::query::caches::QueryCache;
use crate::ty::query::plumbing::CycleError;
use crate::ty::query::{Query, QueryState};
use crate::ty::query::QueryState;
use crate::ty::TyCtxt;
use rustc_data_structures::profiling::ProfileCategory;
use rustc_hir::def_id::DefId;
Expand All @@ -28,18 +28,15 @@ pub trait QueryConfig<'tcx> {
pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
const ANON: bool;
const EVAL_ALWAYS: bool;
const DEP_KIND: DepKind;

type Cache: QueryCache<Self::Key, Self::Value>;

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

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

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

fn dep_kind() -> DepKind;

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

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

impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M
where
<M as QueryAccessors<'tcx>>::Cache: QueryCache<DefId, <M as QueryConfig<'tcx>>::Value>,
{
impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> {
if !tcx.sess.verbose() {
format!("processing `{}`", tcx.def_path_str(def_id)).into()
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,12 @@ use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::ops::Deref;
use std::sync::Arc;

#[macro_use]
mod plumbing;
pub use self::plumbing::CycleError;
pub(crate) use self::plumbing::CycleError;
use self::plumbing::*;

mod stats;
Expand Down
Loading

0 comments on commit 50656db

Please sign in to comment.