mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 00:01:21 +08:00
PR libstdc++/91788 improve codegen for std::variant<T...>::index()
If __index_type is a smaller type than size_t, then the result of size_t(__index_type(-1)) is not equal to size_t(-1), but to an incorrect value such as size_t(255) or size_t(65535). The old implementation of variant<T...>::index() uses (size_t(__index_type(_M_index + 1)) - 1) which is always correct, but generates suboptimal code for many common cases. When the __index_type is size_t or valueless variants are not possible we can just return the value directly. When the number of alternatives is sufficiently small the result of converting the _M_index value to the corresponding signed type will be either non-negative or -1. In those cases converting to the signed type and then to size_t will either produce the correct positive value or will sign extend -1 to (size_t)-1 as desired. For the remaining case we keep the existing arithmetic operations to ensure the correct result. PR libstdc++/91788 (partial) * include/std/variant (variant::index()): Improve codegen for cases where conversion to size_t already works correctly. From-SVN: r276056
This commit is contained in:
parent
fa87544ca1
commit
1e8822d360
@ -1,3 +1,9 @@
|
||||
2019-09-23 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/91788 (partial)
|
||||
* include/std/variant (variant::index()): Improve codegen for cases
|
||||
where conversion to size_t already works correctly.
|
||||
|
||||
2019-09-23 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* config/abi/post/riscv64-linux-gnu/baseline_symbols.txt: Update.
|
||||
|
@ -1518,7 +1518,17 @@ namespace __variant
|
||||
{ return !this->_M_valid(); }
|
||||
|
||||
constexpr size_t index() const noexcept
|
||||
{ return size_t(typename _Base::__index_type(this->_M_index + 1)) - 1; }
|
||||
{
|
||||
using __index_type = typename _Base::__index_type;
|
||||
if constexpr (is_same_v<__index_type, size_t>)
|
||||
return this->_M_index;
|
||||
else if constexpr (__detail::__variant::__never_valueless<_Types...>())
|
||||
return this->_M_index;
|
||||
else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2)
|
||||
return make_signed_t<__index_type>(this->_M_index);
|
||||
else
|
||||
return size_t(__index_type(this->_M_index + 1)) - 1;
|
||||
}
|
||||
|
||||
void
|
||||
swap(variant& __rhs)
|
||||
|
Loading…
x
Reference in New Issue
Block a user