Skip to content

Commit

Permalink
Auto merge of #37152 - arielb1:drop-cache, r=pnkfelix
Browse files Browse the repository at this point in the history
add a per-param-env cache to `impls_bound`

There used to be only a global cache, which led to uncached calls to
trait selection when there were type parameters.

This causes a 20% decrease in borrow-checking time and an overall 0.5% performance increase during bootstrapping (as borrow-checking tends to be a tiny part of compilation time).

Fixes #37106 (drop elaboration times are now ~half of borrow checking,
so might still be worthy of optimization, but not critical).

r? @pnkfelix
  • Loading branch information
bors authored Oct 15, 2016
2 parents 5bfe107 + a61d85b commit 98a3502
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.tcx
}

pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'tcx> {
pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'gcx> {
self.infcx.param_env()
}

Expand Down
16 changes: 14 additions & 2 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use util::nodemap::FnvHashMap;

use serialize::{self, Encodable, Encoder};
use std::borrow::Cow;
use std::cell::Cell;
use std::cell::{Cell, RefCell};
use std::hash::{Hash, Hasher};
use std::iter;
use std::ops::Deref;
Expand Down Expand Up @@ -1220,6 +1220,12 @@ pub struct ParameterEnvironment<'tcx> {
/// regions don't have this implicit scope and instead introduce
/// relationships in the environment.
pub free_id_outlive: CodeExtent,

/// A cache for `moves_by_default`.
pub is_copy_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,

/// A cache for `type_is_sized`
pub is_sized_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
}

impl<'a, 'tcx> ParameterEnvironment<'tcx> {
Expand All @@ -1232,6 +1238,8 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
implicit_region_bound: self.implicit_region_bound,
caller_bounds: caller_bounds,
free_id_outlive: self.free_id_outlive,
is_copy_cache: RefCell::new(FnvHashMap()),
is_sized_cache: RefCell::new(FnvHashMap()),
}
}

Expand Down Expand Up @@ -2773,7 +2781,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
free_substs: Substs::empty(self),
caller_bounds: Vec::new(),
implicit_region_bound: self.mk_region(ty::ReEmpty),
free_id_outlive: free_id_outlive
free_id_outlive: free_id_outlive,
is_copy_cache: RefCell::new(FnvHashMap()),
is_sized_cache: RefCell::new(FnvHashMap()),
}
}

Expand Down Expand Up @@ -2844,6 +2854,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)),
caller_bounds: predicates,
free_id_outlive: free_id_outlive,
is_copy_cache: RefCell::new(FnvHashMap()),
is_sized_cache: RefCell::new(FnvHashMap()),
};

let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps));
Expand Down
17 changes: 0 additions & 17 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,23 +901,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
}
}

impl<'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::ParameterEnvironment {
free_substs: self.free_substs.fold_with(folder),
implicit_region_bound: self.implicit_region_bound.fold_with(folder),
caller_bounds: self.caller_bounds.fold_with(folder),
free_id_outlive: self.free_id_outlive,
}
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.free_substs.visit_with(visitor) ||
self.implicit_region_bound.visit_with(visitor) ||
self.caller_bounds.visit_with(visitor)
}
}

impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::error::ExpectedFound {
Expand Down
31 changes: 25 additions & 6 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ use ty::{Disr, ParameterEnvironment};
use ty::fold::TypeVisitor;
use ty::layout::{Layout, LayoutError};
use ty::TypeVariants::*;
use util::nodemap::FnvHashMap;

use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};

use std::cell::RefCell;
use std::cmp;
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
Expand Down Expand Up @@ -579,11 +581,24 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
impl<'a, 'tcx> ty::TyS<'tcx> {
fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env: &ParameterEnvironment<'tcx>,
bound: ty::BuiltinBound, span: Span) -> bool
bound: ty::BuiltinBound,
cache: &RefCell<FnvHashMap<Ty<'tcx>, bool>>,
span: Span) -> bool
{
tcx.infer_ctxt(None, Some(param_env.clone()), Reveal::ExactMatch).enter(|infcx| {
traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span)
})
if self.has_param_types() || self.has_self_ty() {
if let Some(result) = cache.borrow().get(self) {
return *result;
}
}
let result =
tcx.infer_ctxt(None, Some(param_env.clone()), Reveal::ExactMatch)
.enter(|infcx| {
traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span)
});
if self.has_param_types() || self.has_self_ty() {
cache.borrow_mut().insert(self, result);
}
return result;
}

// FIXME (@jroesch): I made this public to use it, not sure if should be private
Expand All @@ -610,7 +625,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
TyArray(..) | TySlice(..) | TyTrait(..) | TyTuple(..) |
TyClosure(..) | TyAdt(..) | TyAnon(..) |
TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
}.unwrap_or_else(|| !self.impls_bound(tcx, param_env, ty::BoundCopy, span));
}.unwrap_or_else(|| {
!self.impls_bound(tcx, param_env, ty::BoundCopy, &param_env.is_copy_cache, span)
});

if !self.has_param_types() && !self.has_self_ty() {
self.flags.set(self.flags.get() | if result {
Expand Down Expand Up @@ -650,7 +667,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> {

TyAdt(..) | TyProjection(..) | TyParam(..) |
TyInfer(..) | TyAnon(..) | TyError => None
}.unwrap_or_else(|| self.impls_bound(tcx, param_env, ty::BoundSized, span));
}.unwrap_or_else(|| {
self.impls_bound(tcx, param_env, ty::BoundSized, &param_env.is_sized_cache, span)
});

if !self.has_param_types() && !self.has_self_ty() {
self.flags.set(self.flags.get() | if result {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}

pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> {
pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> {
&self.parameter_environment
}

Expand Down

0 comments on commit 98a3502

Please sign in to comment.