libstdc++: Remove __find_if unrolling for random access iterators
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
I have some follow-up patches which are enabled by this, so that other
algos which use std::__find_if can benefit from the memchr optimizations
recently added to std::find. Currently, they can't benefit because they
use the internal __find_if and only std::find is optimized.
Tested x86_64-linux. I intend to push this in the next day or two.
-- >8 --
As the numbers in PR libstdc++/88545 show, the manual loop unrolling in
std::__find_if doesn't actually help these days, and it prevents the
compiler from auto-vectorizing.
Remove the dispatching on iterator_category and just use the simple loop
for all iterator categories.
libstdc++-v3/ChangeLog:
* include/bits/stl_algobase.h (__find_if): Remove overloads for
dispatching on iterator_category. Do not unroll loop manually.
* include/bits/stl_algo.h (__find_if_not): Remove
iterator_category argument from __find_if call.
---
libstdc++-v3/include/bits/stl_algo.h | 3 +-
libstdc++-v3/include/bits/stl_algobase.h | 70 ++----------------------
2 files changed, 5 insertions(+), 68 deletions(-)
@@ -110,8 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Predicate __pred)
{
return std::__find_if(__first, __last,
- __gnu_cxx::__ops::__negate(__pred),
- std::__iterator_category(__first));
+ __gnu_cxx::__ops::__negate(__pred));
}
/// Like find_if_not(), but uses and updates a count of the
@@ -2098,77 +2098,15 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_GLIBCXX_END_NAMESPACE_ALGO
- /// This is an overload used by find algos for the Input Iterator case.
- template<typename _InputIterator, typename _Predicate>
- _GLIBCXX20_CONSTEXPR
- inline _InputIterator
- __find_if(_InputIterator __first, _InputIterator __last,
- _Predicate __pred, input_iterator_tag)
- {
- while (__first != __last && !__pred(__first))
- ++__first;
- return __first;
- }
-
- /// This is an overload used by find algos for the RAI case.
- template<typename _RandomAccessIterator, typename _Predicate>
- _GLIBCXX20_CONSTEXPR
- _RandomAccessIterator
- __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Predicate __pred, random_access_iterator_tag)
- {
- typename iterator_traits<_RandomAccessIterator>::difference_type
- __trip_count = (__last - __first) >> 2;
-
- for (; __trip_count > 0; --__trip_count)
- {
- if (__pred(__first))
- return __first;
- ++__first;
-
- if (__pred(__first))
- return __first;
- ++__first;
-
- if (__pred(__first))
- return __first;
- ++__first;
-
- if (__pred(__first))
- return __first;
- ++__first;
- }
-
- switch (__last - __first)
- {
- case 3:
- if (__pred(__first))
- return __first;
- ++__first;
- // FALLTHRU
- case 2:
- if (__pred(__first))
- return __first;
- ++__first;
- // FALLTHRU
- case 1:
- if (__pred(__first))
- return __first;
- ++__first;
- // FALLTHRU
- case 0:
- default:
- return __last;
- }
- }
-
+ // Implementation of std::find_if, also used in std::remove_if and others.
template<typename _Iterator, typename _Predicate>
_GLIBCXX20_CONSTEXPR
inline _Iterator
__find_if(_Iterator __first, _Iterator __last, _Predicate __pred)
{
- return __find_if(__first, __last, __pred,
- std::__iterator_category(__first));
+ while (__first != __last && !__pred(__first))
+ ++__first;
+ return __first;
}
template<typename _InputIterator, typename _Predicate>