Skip to content

Optimize shallow_resolve_changed #67079

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1618,37 +1618,37 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
// inlined, despite being large, because it has only two call sites that
// are extremely hot.
#[inline(always)]
pub fn shallow_resolve_changed(&mut self, typ: Ty<'tcx>) -> bool {
match typ.kind {
ty::Infer(ty::TyVar(v)) => {
pub fn shallow_resolve_changed(&self, infer: ty::InferTy) -> bool {
match infer {
ty::TyVar(v) => {
use self::type_variable::TypeVariableValue;

// See the comment in `shallow_resolve()`.
// If `inlined_probe` returns a `Known` value its `kind` never
// matches `infer`.
match self.infcx.type_variables.borrow_mut().inlined_probe(v) {
TypeVariableValue::Known { value: t } => self.fold_ty(t) != typ,
TypeVariableValue::Unknown { .. } => false,
TypeVariableValue::Known { .. } => true,
}
}

ty::Infer(ty::IntVar(v)) => {
match self.infcx.int_unification_table.borrow_mut().inlined_probe_value(v) {
Some(v) => v.to_type(self.infcx.tcx) != typ,
None => false,
}
ty::IntVar(v) => {
// If inlined_probe_value returns a value it's always a
// `ty::Int(_)` or `ty::UInt(_)`, which nevers matches a
// `ty::Infer(_)`.
self.infcx.int_unification_table.borrow_mut().inlined_probe_value(v).is_some()
}

ty::Infer(ty::FloatVar(v)) => {
ty::FloatVar(v) => {
// If inlined_probe_value returns a value it's always a
// `ty::Float(_)`, which nevers matches a `ty::Infer(_)`.
//
// Not `inlined_probe_value(v)` because this call site is colder.
match self.infcx.float_unification_table.borrow_mut().probe_value(v) {
Some(v) => v.to_type(self.infcx.tcx) != typ,
None => false,
}
self.infcx.float_unification_table.borrow_mut().probe_value(v).is_some()
}

_ => false,
_ => unreachable!(),
}
}

}

impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
Expand Down
30 changes: 19 additions & 11 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub struct FulfillmentContext<'tcx> {
#[derive(Clone, Debug)]
pub struct PendingPredicateObligation<'tcx> {
pub obligation: PredicateObligation<'tcx>,
pub stalled_on: Vec<Ty<'tcx>>,
pub stalled_on: Vec<ty::InferTy>,
}

// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
Expand Down Expand Up @@ -263,8 +263,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
// Match arms are in order of frequency, which matters because this
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
1 => {
let ty = pending_obligation.stalled_on[0];
ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(ty)
let infer = pending_obligation.stalled_on[0];
ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer)
}
0 => {
// In this case we haven't changed, but wish to make a change.
Expand All @@ -274,8 +274,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
// This `for` loop was once a call to `all()`, but this lower-level
// form was a perf win. See #64545 for details.
(|| {
for &ty in &pending_obligation.stalled_on {
if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(ty) {
for &infer in &pending_obligation.stalled_on {
if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) {
return true;
}
}
Expand Down Expand Up @@ -305,6 +305,13 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {

debug!("process_obligation: obligation = {:?} cause = {:?}", obligation, obligation.cause);

fn infer_ty(ty: Ty<'tcx>) -> ty::InferTy {
match ty.kind {
ty::Infer(infer) => infer,
_ => panic!(),
}
}

match obligation.predicate {
ty::Predicate::Trait(ref data) => {
let trait_obligation = obligation.with(data.clone());
Expand Down Expand Up @@ -459,7 +466,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
obligation.cause.span,
) {
None => {
pending_obligation.stalled_on = vec![ty];
pending_obligation.stalled_on = vec![infer_ty(ty)];
ProcessResult::Unchanged
}
Some(os) => ProcessResult::Changed(mk_pending(os))
Expand All @@ -472,8 +479,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
subtype) {
None => {
// None means that both are unresolved.
pending_obligation.stalled_on = vec![subtype.skip_binder().a,
subtype.skip_binder().b];
pending_obligation.stalled_on = vec![infer_ty(subtype.skip_binder().a),
infer_ty(subtype.skip_binder().b)];
ProcessResult::Unchanged
}
Some(Ok(ok)) => {
Expand Down Expand Up @@ -517,7 +524,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
))
}
} else {
pending_obligation.stalled_on = substs.types().collect();
pending_obligation.stalled_on =
substs.types().map(|ty| infer_ty(ty)).collect();
ProcessResult::Unchanged
}
}
Expand All @@ -542,13 +550,13 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
fn trait_ref_type_vars<'a, 'tcx>(
selcx: &mut SelectionContext<'a, 'tcx>,
t: ty::PolyTraitRef<'tcx>,
) -> Vec<Ty<'tcx>> {
) -> Vec<ty::InferTy> {
t.skip_binder() // ok b/c this check doesn't care about regions
.input_types()
.map(|t| selcx.infcx().resolve_vars_if_possible(&t))
.filter(|t| t.has_infer_types())
.flat_map(|t| t.walk())
.filter(|t| match t.kind { ty::Infer(_) => true, _ => false })
.filter_map(|t| match t.kind { ty::Infer(infer) => Some(infer), _ => None })
.collect()
}

Expand Down