diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 5e6572b1a82c4..27e681aeef22a 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -1161,6 +1161,24 @@ vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) { return this->__end_; } +// This makes the compiler inline `__else()` if `__cond` is known to be false. Currently LLVM doesn't do that without +// the `__builtin_constant_p`, since it considers `__else` unlikely even through it's known to be run. +// See https://llvm.org/PR154292 +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __if_likely_else(bool __cond, _If __if, _Else __else) { + if (__builtin_constant_p(__cond)) { + if (__cond) + __if(); + else + __else(); + } else { + if (__cond) [[__likely__]] + __if(); + else + __else(); + } +} + template template _LIBCPP_CONSTEXPR_SINCE_CXX20 inline @@ -1171,12 +1189,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline #endif vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) { pointer __end = this->__end_; - if (__end < this->__cap_) { - __emplace_back_assume_capacity(std::forward<_Args>(__args)...); - ++__end; - } else { - __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); - } + std::__if_likely_else( + __end < this->__cap_, + [&] { + __emplace_back_assume_capacity(std::forward<_Args>(__args)...); + ++__end; + }, + [&] { __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); }); + this->__end_ = __end; #if _LIBCPP_STD_VER >= 17 return *(__end - 1);