[libcxx-commits] [libcxx] [libc++] Use relocation in vector::emplace_back (PR #159365)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 29 23:42:33 PDT 2025
================
@@ -469,15 +487,60 @@ class vector {
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x) { emplace_back(std::move(__x)); }
template <class... _Args>
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference __emplace_back(_Args&&... __args) {
+ if constexpr (__libcpp_is_trivially_relocatable<value_type>::value &&
+ __allocator_has_trivial_move_construct_v<allocator_type, value_type> &&
+ __allocator_has_trivial_destroy_v<allocator_type, value_type>) {
+ // This path is written in a way to have the fast path as compact as possible. Specifically,
+ // there is a branch in case there isn't enough capacity left over, which will return to the same location within
+ // the function after growing the vector. This ensures that the relocation code exists only once and the
+ // reallocation path is common across all `vector` instantiations of trivially relocatable types.
+ union _Tmp {
+ _LIBCPP_DIAGNOSTIC_PUSH
+ // Clang complains about __exclude_from_explicit_instantiation__ on a local class member.
+ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wignored-attributes")
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tmp() {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~_Tmp() {}
+ _LIBCPP_DIAGNOSTIC_POP
+ value_type __val_;
+ };
+ _Tmp __tmp;
+
+ __alloc_traits::construct(__alloc_, std::addressof(__tmp.__val_), std::forward<_Args>(__args)...);
----------------
philnik777 wrote:
No. This is almost always still an improvement, since the compiler will often be able to lift the construction into registers and simply commit them to memory after the reallocation, leading to fewer branches.
https://github.com/llvm/llvm-project/pull/159365
More information about the libcxx-commits
mailing list