Avoid SmallVec::collect()
in SubstsRef::super_fold_with()
.
This commit reduces instruction counts for several benchmarks by up to 5%.
This commit is contained in:
parent
06c68947ad
commit
14192607d3
@ -383,14 +383,41 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
|
||||
|
||||
// If folding doesn't change the substs, it's faster to avoid
|
||||
// calling `mk_substs` and instead reuse the existing substs.
|
||||
if params[..] == self[..] {
|
||||
self
|
||||
} else {
|
||||
folder.tcx().intern_substs(¶ms)
|
||||
// This code is hot enough that it's worth specializing for the most
|
||||
// common length lists, to avoid the overhead of `SmallVec` creation.
|
||||
// The match arms are in order of frequency. The 1, 2, and 0 cases are
|
||||
// typically hit in 90--99.99% of cases. When folding doesn't change
|
||||
// the substs, it's faster to reuse the existing substs rather than
|
||||
// calling `intern_substs`.
|
||||
match self.len() {
|
||||
1 => {
|
||||
let param0 = self[0].fold_with(folder);
|
||||
if param0 == self[0] {
|
||||
self
|
||||
} else {
|
||||
folder.tcx().intern_substs(&[param0])
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
let param0 = self[0].fold_with(folder);
|
||||
let param1 = self[1].fold_with(folder);
|
||||
if param0 == self[0] && param1 == self[1] {
|
||||
self
|
||||
} else {
|
||||
folder.tcx().intern_substs(&[param0, param1])
|
||||
}
|
||||
}
|
||||
0 => {
|
||||
self
|
||||
}
|
||||
_ => {
|
||||
let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
|
||||
if params[..] == self[..] {
|
||||
self
|
||||
} else {
|
||||
folder.tcx().intern_substs(¶ms)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user