Skip to content

Commit

Permalink
Use a more lightweight cache for erase_regions
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Mar 29, 2019
1 parent 237bf32 commit b72ca1e
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 30 deletions.
51 changes: 51 additions & 0 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,43 @@ impl DepGraph {
DepGraphQuery::new(&nodes[..], &edges[..])
}

pub fn debug_assert_no_deps<OP, R>(op: OP) -> R
where OP: FnOnce() -> R
{
if cfg!(debug_assertions) {
ty::tls::with_context(|icx| {
let task_deps = Lock::new(TaskDeps {
#[cfg(debug_assertions)]
node: None,
#[cfg(debug_assertions)]
no_deps: true,
reads: SmallVec::new(),
read_set: Default::default(),
});
let icx = ty::tls::ImplicitCtxt {
task_deps: Some(&task_deps),
..icx.clone()
};

let r = ty::tls::enter_context(&icx, |_| {
op()
});

for read in &task_deps.lock().reads {
icx.tcx.dep_graph.data.as_ref().map(|graph| {
eprintln!("read: {:?}", graph.current.lock().data[*read].node);
});
}
// Ensure no dependencies were recorded
assert_eq!(task_deps.into_inner().reads, SmallVec::<[DepNodeIndex; 8]>::new());

r
})
} else {
op()
}
}

pub fn assert_ignored(&self)
{
if let Some(..) = self.data {
Expand Down Expand Up @@ -203,6 +240,8 @@ impl DepGraph {
|_key| Some(TaskDeps {
#[cfg(debug_assertions)]
node: Some(_key),
#[cfg(debug_assertions)]
no_deps: false,
reads: SmallVec::new(),
read_set: Default::default(),
}),
Expand Down Expand Up @@ -345,6 +384,8 @@ impl DepGraph {
let task_deps = Lock::new(TaskDeps {
#[cfg(debug_assertions)]
node: None,
#[cfg(debug_assertions)]
no_deps: false,
reads: SmallVec::new(),
read_set: Default::default(),
});
Expand Down Expand Up @@ -1109,6 +1150,14 @@ impl DepGraphData {
let icx = if let Some(icx) = icx { icx } else { return };
if let Some(task_deps) = icx.task_deps {
let mut task_deps = task_deps.lock();

#[cfg(debug_assertions)]
{
if task_deps.no_deps {
panic!("tried to add dependency, but no dependencies are allowed");
}
}

if cfg!(debug_assertions) {
self.current.lock().total_read_count += 1;
}
Expand Down Expand Up @@ -1140,6 +1189,8 @@ impl DepGraphData {
pub struct TaskDeps {
#[cfg(debug_assertions)]
node: Option<DepNode>,
#[cfg(debug_assertions)]
no_deps: bool,
reads: SmallVec<[DepNodeIndex; 8]>,
read_set: FxHashSet<DepNodeIndex>,
}
Expand Down
17 changes: 1 addition & 16 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::ty::query::QueryDescription;
use crate::ty::query::queries;
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::{self, TyCtxt};
use crate::hir::def_id::{DefId, CrateNum};
use crate::dep_graph::SerializedDepNodeIndex;
use crate::traits;
Expand Down Expand Up @@ -113,21 +113,6 @@ rustc_queries! {
}

TypeChecking {
// Erases regions from `ty` to yield a new type.
// Normally you would just use `tcx.erase_regions(&value)`,
// however, which uses this query as a kind of cache.
query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
// This query is not expected to have input -- as a result, it
// is not a good candidates for "replay" because it is essentially a
// pure function of its input (and hence the expectation is that
// no caller would be green **apart** from just these
// queries). Making it anonymous avoids hashing the result, which
// may save a bit of time.
anon
no_force
desc { "erasing regions from `{:?}`", ty }
}

query program_clauses_for(_: DefId) -> Clauses<'tcx> {
desc { "generating chalk-style clauses" }
}
Expand Down
13 changes: 11 additions & 2 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,8 @@ pub struct GlobalCtxt<'tcx> {
/// Common types, pre-interned for your convenience.
pub types: CommonTypes<'tcx>,

pub(in crate::ty) erased_region_cache: Lock<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,

/// Map indicating what traits are in scope for places where this
/// is relevant; generated by resolve.
trait_map: FxHashMap<DefIndex,
Expand Down Expand Up @@ -1250,6 +1252,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
global_interners: interners,
dep_graph,
types: common_types,
erased_region_cache: Default::default(),
trait_map,
export_map: resolutions.export_map.into_iter().map(|(k, v)| {
(k, Lrc::new(v))
Expand Down Expand Up @@ -2727,8 +2730,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

pub fn intern_existential_predicates(self, eps: &[ExistentialPredicate<'tcx>])
-> &'tcx List<ExistentialPredicate<'tcx>> {
assert!(!eps.is_empty());
assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, &w[1]) != Ordering::Greater));
if cfg!(debug_assertions) {
assert!(!eps.is_empty());
self.dep_graph.with_ignore(|| {
assert!(eps.windows(2).all(|w| {
w[0].stable_cmp(self, &w[1]) != Ordering::Greater
}));
});
}
self._intern_existential_predicates(eps)
}

Expand Down
23 changes: 12 additions & 11 deletions src/librustc/ty/erase_regions.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use crate::ty::{self, Ty, TyCtxt, TypeFlags};
use crate::ty::fold::{TypeFolder, TypeFoldable};

pub(super) fn provide(providers: &mut ty::query::Providers<'_>) {
*providers = ty::query::Providers {
erase_regions_ty,
..*providers
};
}
use crate::dep_graph::DepGraph;

fn erase_regions_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
// N.B., use `super_fold_with` here. If we used `fold_with`, it
// could invoke the `erase_regions_ty` query recursively.
ty.super_fold_with(&mut RegionEraserVisitor { tcx })
if let Some(ty) = tcx.erased_region_cache.lock().get(ty) {
return ty;
}
let result = DepGraph::debug_assert_no_deps(|| {
// N.B., use `super_fold_with` here. If we used `fold_with`, it
// could invoke the `erase_regions_ty` function recursively.
ty.super_fold_with(&mut RegionEraserVisitor { tcx })
});
tcx.erased_region_cache.lock().insert(ty, result);
result
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
Expand Down Expand Up @@ -43,7 +44,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionEraserVisitor<'a, 'gcx, 't

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let Some(ty_lifted) = self.tcx.lift_to_global(&ty) {
self.tcx.erase_regions_ty(ty_lifted)
erase_regions_ty(self.tcx.global_tcx(), ty_lifted)
} else {
ty.super_fold_with(self)
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3345,7 +3345,6 @@ fn issue33140_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

pub fn provide(providers: &mut ty::query::Providers<'_>) {
context::provide(providers);
erase_regions::provide(providers);
layout::provide(providers);
util::provide(providers);
constness::provide(providers);
Expand Down

0 comments on commit b72ca1e

Please sign in to comment.