diff options
| author | bors <bors@rust-lang.org> | 2019-09-30 09:52:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-09-30 09:52:29 +0000 |
| commit | e0436d912df090b0c3cba9a8b818aab408756e49 (patch) | |
| tree | 48d50edb6ab8a2c03fe86b4f2c76e676d2cf4e61 | |
| parent | bf8491e72ef0d5ea0ef683e9d149408a717545e4 (diff) | |
| parent | 6ac64abd6d4fdd60c6ee34fb1a14d2eaa9faed16 (diff) | |
| download | rust-e0436d912df090b0c3cba9a8b818aab408756e49.tar.gz rust-e0436d912df090b0c3cba9a8b818aab408756e49.zip | |
Auto merge of #64600 - scottmcm:no-slice-tryfold-unroll, r=bluss
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). --- For context see https://github.com/rust-lang/rust/pull/64572#issuecomment-532961046
| -rw-r--r-- | src/libcore/slice/mod.rs | 69 |
1 files changed, 1 insertions, 68 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 5ec21e6d928..b5462d98837 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -28,7 +28,7 @@ use crate::fmt; use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null}; use crate::isize; use crate::iter::*; -use crate::ops::{FnMut, Try, self}; +use crate::ops::{FnMut, self}; use crate::option::Option; use crate::option::Option::{None, Some}; use crate::result::Result; @@ -3181,39 +3181,6 @@ macro_rules! iterator { } #[inline] - fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> - { - // manual unrolling is needed when there are conditional exits from the loop - let mut accum = init; - unsafe { - while len!(self) >= 4 { - accum = f(accum, next_unchecked!(self))?; - accum = f(accum, next_unchecked!(self))?; - accum = f(accum, next_unchecked!(self))?; - accum = f(accum, next_unchecked!(self))?; - } - while !is_empty!(self) { - accum = f(accum, next_unchecked!(self))?; - } - } - Try::from_ok(accum) - } - - #[inline] - fn fold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - // Let LLVM unroll this, rather than using the default - // impl that would force the manual unrolling above - let mut accum = init; - while let Some(x) = self.next() { - accum = f(accum, x); - } - accum - } - - #[inline] #[rustc_inherit_overflow_checks] fn position<P>(&mut self, mut predicate: P) -> Option<usize> where Self: Sized, @@ -3283,40 +3250,6 @@ macro_rules! iterator { Some(next_back_unchecked!(self)) } } - - #[inline] - fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> - { - // manual unrolling is needed when there are conditional exits from the loop - let mut accum = init; - unsafe { - while len!(self) >= 4 { - accum = f(accum, next_back_unchecked!(self))?; - accum = f(accum, next_back_unchecked!(self))?; - accum = f(accum, next_back_unchecked!(self))?; - accum = f(accum, next_back_unchecked!(self))?; - } - // inlining is_empty everywhere makes a huge performance difference - while !is_empty!(self) { - accum = f(accum, next_back_unchecked!(self))?; - } - } - Try::from_ok(accum) - } - - #[inline] - fn rfold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - // Let LLVM unroll this, rather than using the default - // impl that would force the manual unrolling above - let mut accum = init; - while let Some(x) = self.next_back() { - accum = f(accum, x); - } - accum - } } #[stable(feature = "fused", since = "1.26.0")] |
