Skip to content

[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

Merged
merged 1 commit into from
Dec 23, 2023

Conversation

philnik777
Copy link
Contributor

@philnik777 philnik777 commented Oct 26, 2023

Fixes #70238

Copy link
Member

@ldionne ldionne left a 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.

@philnik777 philnik777 added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. performance labels Oct 27, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2023

@llvm/pr-subscribers-libcxx

Author: None (philnik777)

Changes

Fixes #70238


Full diff: https://github.com/llvm/llvm-project/pull/70345.diff

1 Files Affected:

  • (modified) libcxx/include/__algorithm/find.h (+13)
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>

@philnik777 philnik777 force-pushed the find_always_forward_if_integral branch 2 times, most recently from 77f44c4 to 165bfd2 Compare December 14, 2023 15:49
Copy link

github-actions bot commented Dec 14, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@ldionne ldionne left a 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.

@philnik777 philnik777 force-pushed the find_always_forward_if_integral branch from 165bfd2 to fa7c221 Compare December 21, 2023 14:57
@philnik777 philnik777 changed the title [libc++] Optimize std::find if types are integral [libc++] Optimize std::find if types are integral and have the same signedness Dec 21, 2023
@philnik777 philnik777 marked this pull request as ready for review December 21, 2023 14:58
@philnik777 philnik777 requested a review from a team as a code owner December 21, 2023 14:58
@philnik777 philnik777 force-pushed the find_always_forward_if_integral branch from fa7c221 to 78a2501 Compare December 21, 2023 15:40
@EricWF
Copy link
Member

EricWF commented Dec 21, 2023

Are there benchmark results for this?

@philnik777
Copy link
Contributor Author

Are there benchmark results for this?

https://reviews.llvm.org/D144394#4138976

Copy link
Member

@ldionne ldionne left a 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.

Copy link
Member

@ldionne ldionne left a 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.

@philnik777 philnik777 force-pushed the find_always_forward_if_integral branch from 78a2501 to df126e2 Compare December 23, 2023 10:21
@philnik777 philnik777 merged commit b203d53 into llvm:main Dec 23, 2023
@philnik777 philnik777 deleted the find_always_forward_if_integral branch December 23, 2023 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

libc++, find(char*, char*, int) does not optimize to memchr
4 participants