Skip to content

Commit 92e91f7

Browse files
committed
Remove manual unrolling from slice::Iter(Mut)::try_fold
While this definitely helps sometimes (particularly for trivial closures), it's also a pessimization sometimes, so it's better to leave this to (hypothetical) future LLVM improvements instead of forcing this on everyone. I think it's better for the advice to be that sometimes you need to unroll manually than you sometimes need to not-unroll manually (like #64545).
1 parent eceec57 commit 92e91f7

File tree

1 file changed

+7
-13
lines changed

1 file changed

+7
-13
lines changed

src/libcore/slice/mod.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -3184,18 +3184,14 @@ macro_rules! iterator {
31843184
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
31853185
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
31863186
{
3187-
// manual unrolling is needed when there are conditional exits from the loop
3187+
// This method historically was unrolled, for as of 2019-09 LLVM
3188+
// is not capable of unrolling or vectorizing multiple-exit loops.
3189+
// However, doing it always proved to often be a pessimization,
3190+
// especially when called with large closures, so it was removed.
3191+
31883192
let mut accum = init;
3189-
unsafe {
3190-
while len!(self) >= 4 {
3191-
accum = f(accum, next_unchecked!(self))?;
3192-
accum = f(accum, next_unchecked!(self))?;
3193-
accum = f(accum, next_unchecked!(self))?;
3194-
accum = f(accum, next_unchecked!(self))?;
3195-
}
3196-
while !is_empty!(self) {
3197-
accum = f(accum, next_unchecked!(self))?;
3198-
}
3193+
while let Some(x) = self.next() {
3194+
accum = f(accum, x)?;
31993195
}
32003196
Try::from_ok(accum)
32013197
}
@@ -3204,8 +3200,6 @@ macro_rules! iterator {
32043200
fn fold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
32053201
where Fold: FnMut(Acc, Self::Item) -> Acc,
32063202
{
3207-
// Let LLVM unroll this, rather than using the default
3208-
// impl that would force the manual unrolling above
32093203
let mut accum = init;
32103204
while let Some(x) = self.next() {
32113205
accum = f(accum, x);

0 commit comments

Comments
 (0)