-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Improve code gen for string's operator== #100926
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
Conversation
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesIf the string is too long for a short string, we can simply check for the long bit. If that's false we can do an early return. This improves the code gen slightly. Full diff: https://github.com/llvm/llvm-project/pull/100926.diff 1 Files Affected:
diff --git a/libcxx/include/string b/libcxx/include/string
index 9fa979e3a5178..856e422d8c1e3 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2246,6 +2246,10 @@ private:
friend constexpr basic_string operator+ <>(const basic_string&, type_identity_t<__self_view>);
friend constexpr basic_string operator+ <>(type_identity_t<__self_view>, const basic_string&);
#endif
+
+ template <class _CharT2, class _Traits2, class _Allocator2>
+ friend inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
+ operator==(const basic_string<_CharT2, _Traits2, _Allocator2>&, const _CharT2*) _NOEXCEPT;
};
// These declarations must appear before any functions are implicitly used
@@ -3855,16 +3859,18 @@ operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Allocator>&
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
-#if _LIBCPP_STD_VER >= 20
- return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs);
-#else
- typedef basic_string<_CharT, _Traits, _Allocator> _String;
_LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
+
+ using _String = basic_string<_CharT, _Traits, _Allocator>;
+
size_t __rhs_len = _Traits::length(__rhs);
+ if (__builtin_constant_p(__rhs_len) && __rhs_len >= _String::__min_cap) {
+ if (!__lhs.__is_long())
+ return false;
+ }
if (__rhs_len != __lhs.size())
return false;
return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
-#endif
}
#if _LIBCPP_STD_VER >= 20
|
9d2d2dd
to
12afc0e
Compare
template <class _CharT2, class _Traits2, class _Allocator2> | ||
friend inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool | ||
operator==(const basic_string<_CharT2, _Traits2, _Allocator2>&, const _CharT2*) _NOEXCEPT; |
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.
Why not define the operator here instead?
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.
Because we wouldn't be conforming then. This operator==
isn't defined as a hidden friend in the standard.
#if _LIBCPP_STD_VER >= 20 | ||
return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); | ||
#else |
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.
What was the purpose of this #if
?
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.
AFAICT it only exists to match the standards wording.
If the string is too long for a short string, we can simply check for the long bit. If that's false we can do an early return. This improves the code gen slightly.