optimize TypeFoldable for 2 element tuples

This commit is contained in:
lcnr 2022-02-07 16:08:04 +01:00
parent 7d5d6c055b
commit 758f4e7158
2 changed files with 39 additions and 13 deletions

View File

@ -889,19 +889,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,

View File

@ -458,6 +458,45 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
// This code is fairly hot, though not as hot as `SubstsRef`.
//
// When compiling stage 2, I get the following results:
//
// len | total | %
// --- | --------- | -----
// 2 | 15083590 | 48.1
// 3 | 7540067 | 24.0
// 1 | 5300377 | 16.9
// 4 | 1351897 | 4.3
// 0 | 1256849 | 4.0
//
// I've tried it with some private repositories and got
// close to the same result, with 4 and 0 swapping places
// sometimes.
match self.len() {
2 => {
let param0 = self[0].try_fold_with(folder)?;
let param1 = self[1].try_fold_with(folder)?;
if param0 == self[0] && param1 == self[1] {
Ok(self)
} else {
Ok(folder.tcx().intern_type_list(&[param0, param1]))
}
}
_ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}
///////////////////////////////////////////////////////////////////////////
// Public trait `Subst`
//