Skip to content

Commit b261edf

Browse files
committed
Add a specialized version of shallow_resolve().
The super-hot call site of `inlined_shallow_resolve()` basically does `r.inlined_shallow_resolve(ty) != ty`. This commit introduces a version of that function specialized for that particular call pattern, `shallow_resolve_changed()`. Incredibly, this reduces the instruction count for `keccak` by 5%. The commit also renames `inlined_shallow_resolve()` as `shallow_resolve()` and removes the `inline(always)` annotation, as it's no longer nearly so hot.
1 parent be0a4f2 commit b261edf

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/librustc/infer/mod.rs

+38-6
Original file line numberDiff line numberDiff line change
@@ -1558,11 +1558,7 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
15581558
ShallowResolver { infcx }
15591559
}
15601560

1561-
// We have this force-inlined variant of `shallow_resolve` for the one
1562-
// callsite that is extremely hot. All other callsites use the normal
1563-
// variant.
1564-
#[inline(always)]
1565-
pub fn inlined_shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
1561+
pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
15661562
match typ.sty {
15671563
ty::Infer(ty::TyVar(v)) => {
15681564
// Not entirely obvious: if `typ` is a type variable,
@@ -1597,6 +1593,42 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
15971593
_ => typ,
15981594
}
15991595
}
1596+
1597+
// `resolver.shallow_resolve_changed(ty)` is equivalent to
1598+
// `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always
1599+
// inlined, despite being large, because it has a single call site that is
1600+
// extremely hot.
1601+
#[inline(always)]
1602+
pub fn shallow_resolve_changed(&mut self, typ: Ty<'tcx>) -> bool {
1603+
match typ.sty {
1604+
ty::Infer(ty::TyVar(v)) => {
1605+
use self::type_variable::TypeVariableValue;
1606+
1607+
// See the comment in `shallow_resolve()`.
1608+
match self.infcx.type_variables.borrow_mut().probe(v) {
1609+
TypeVariableValue::Known { value: t } => self.fold_ty(t) != typ,
1610+
TypeVariableValue::Unknown { .. } => false,
1611+
}
1612+
}
1613+
1614+
ty::Infer(ty::IntVar(v)) => {
1615+
match self.infcx.int_unification_table.borrow_mut().probe_value(v) {
1616+
Some(v) => v.to_type(self.infcx.tcx) != typ,
1617+
None => false,
1618+
}
1619+
}
1620+
1621+
ty::Infer(ty::FloatVar(v)) => {
1622+
match self.infcx.float_unification_table.borrow_mut().probe_value(v) {
1623+
Some(v) => v.to_type(self.infcx.tcx) != typ,
1624+
None => false,
1625+
}
1626+
}
1627+
1628+
_ => false,
1629+
}
1630+
}
1631+
16001632
}
16011633

16021634
impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
@@ -1605,7 +1637,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
16051637
}
16061638

16071639
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1608-
self.inlined_shallow_resolve(ty)
1640+
self.shallow_resolve(ty)
16091641
}
16101642

16111643
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {

src/librustc/traits/fulfill.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
262262
if !pending_obligation.stalled_on.is_empty() {
263263
let mut changed = false;
264264
for &ty in &pending_obligation.stalled_on {
265-
// Use the force-inlined variant of shallow_resolve() because this code is hot.
266-
let resolved = ShallowResolver::new(self.selcx.infcx()).inlined_shallow_resolve(ty);
267-
if resolved != ty {
265+
if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(ty) {
268266
changed = true;
269267
break;
270268
}

0 commit comments

Comments
 (0)