-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Optimize std::find if types are integral and have the same signedness #70345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++] Optimize std::find if types are integral and have the same signedness #70345
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I think this makes sense, but it's tricky so we really need some tests.
Also, this is the kind of stuff that I would really expect something like Clang IR to render completely obsolete (along with most of the memchr
-related optimizations, I guess). But we're not there yet I guess.
CC @bcardosolopes for awareness -- we have a bunch of these optimizations where we try to lower things like std::find(char*, char*, char)
to a call to memchr
, and we're thinking that Clang IR might make it easy for the compiler to understand that this optimization is possible without us telling it. In case you have thoughts about this, we'd love to hear them.
@llvm/pr-subscribers-libcxx Author: None (philnik777) ChangesFixes #70238 Full diff: https://github.com/llvm/llvm-project/pull/70345.diff 1 Files Affected:
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index d7c268bc6b338b0..019848158c174df 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -73,6 +73,19 @@ __find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class _Tp,
+ class _Up,
+ class _Proj,
+ __enable_if_t<__is_identity<_Proj>::value && !__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
+ is_integral<_Tp>::value && is_integral<_Up>::value,
+ int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
+__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) {
+ if (__value < numeric_limits<_Tp>::min() || __value > numeric_limits<_Tp>::max())
+ return __last;
+ return std::__find_impl(__first, __last, _Tp(__value), __proj);
+}
+
// __bit_iterator implementation
template <bool _ToFind, class _Cp, bool _IsConst>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
|
77f44c4
to
165bfd2
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it would be reasonable to land this improvement without handling different signedness for now.
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp
Outdated
Show resolved
Hide resolved
165bfd2
to
fa7c221
Compare
fa7c221
to
78a2501
Compare
Are there benchmark results for this? |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good to me if we have tests with other than 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I am going to approve this but please add the non-zero tests, and ping me again if you need to change the implementation when you add these tests.
78a2501
to
df126e2
Compare
Fixes #70238