[libcxx-commits] [libcxx] 7ba045a - Make basic_string::operator=() tail call properly
Martijn Vels via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Apr 10 16:42:26 PDT 2020
Author: Martijn Vels
Date: 2020-04-10T19:41:46-04:00
New Revision: 7ba045a430b9e3812c20a941f45addac0fd6afd7
URL: https://github.com/llvm/llvm-project/commit/7ba045a430b9e3812c20a941f45addac0fd6afd7
DIFF: https://github.com/llvm/llvm-project/commit/7ba045a430b9e3812c20a941f45addac0fd6afd7.diff
LOG: Make basic_string::operator=() tail call properly
Summary: We discovered that the compiler may chose not to inline the operator=, which leads to an expensive extra stack frame. This change makes __assign_no_alias always tail called.
Reviewers: EricWF, #libc!
Subscribers: libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D77913
Added:
Modified:
libcxx/include/__string
libcxx/include/string
Removed:
################################################################################
diff --git a/libcxx/include/__string b/libcxx/include/__string
index d81301453658..2c038ce493d2 100644
--- a/libcxx/include/__string
+++ b/libcxx/include/__string
@@ -164,8 +164,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
- _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
+ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
diff --git a/libcxx/include/string b/libcxx/include/string
index a60ffec0c472..6938ee48b0f8 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1585,7 +1585,7 @@ private:
// have proof that the input does not alias the current instance.
// For example, operator=(basic_string) performs a 'self' check.
template <bool __is_short>
- void __assign_no_alias(const value_type* __s, size_type __n);
+ basic_string& __assign_no_alias(const value_type* __s, size_type __n);
_LIBCPP_INLINE_VISIBILITY
void __erase_to_end(size_type __pos);
@@ -2253,7 +2253,8 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
template <class _CharT, class _Traits, class _Allocator>
template <bool __is_short>
-void basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
const value_type* __s, size_type __n) {
size_type __cap = __is_short ? __min_cap : __get_long_cap();
if (__n < __cap) {
@@ -2266,6 +2267,7 @@ void basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
size_type __sz = __is_short ? __get_short_size() : __get_long_size();
__grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
}
+ return *this;
}
template <class _CharT, class _Traits, class _Allocator>
@@ -2340,10 +2342,10 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
if (!__str.__is_long()) {
__r_.first().__r = __str.__r_.first().__r;
} else {
- __assign_no_alias<true>(__str.data(), __str.size());
+ return __assign_no_alias<true>(__str.data(), __str.size());
}
} else {
- __assign_no_alias<false>(__str.data(), __str.size());
+ return __assign_no_alias<false>(__str.data(), __str.size());
}
}
return *this;
More information about the libcxx-commits
mailing list