@@ -1161,6 +1161,24 @@ vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) {
11611161 return this ->__end_ ;
11621162}
11631163
1164+ // This makes the compiler inline `__else()` if `__cond` is known to be false. Currently LLVM doesn't do that without
1165+ // the `__builtin_constant_p`, since it considers `__else` unlikely even through it's known to be run.
1166+ // See https://llvm.org/PR154292
1167+ template <class _If , class _Else >
1168+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __if_likely_else (bool __cond, _If __if, _Else __else) {
1169+ if (__builtin_constant_p (__cond)) {
1170+ if (__cond)
1171+ __if ();
1172+ else
1173+ __else ();
1174+ } else {
1175+ if (__cond) [[__likely__]]
1176+ __if ();
1177+ else
1178+ __else ();
1179+ }
1180+ }
1181+
11641182template <class _Tp , class _Allocator >
11651183template <class ... _Args>
11661184_LIBCPP_CONSTEXPR_SINCE_CXX20 inline
@@ -1171,12 +1189,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline
11711189#endif
11721190 vector<_Tp, _Allocator>::emplace_back (_Args&&... __args) {
11731191 pointer __end = this ->__end_ ;
1174- if (__end < this ->__cap_ ) {
1175- __emplace_back_assume_capacity (std::forward<_Args>(__args)...);
1176- ++__end;
1177- } else {
1178- __end = __emplace_back_slow_path (std::forward<_Args>(__args)...);
1179- }
1192+ std::__if_likely_else (
1193+ __end < this ->__cap_ ,
1194+ [&] {
1195+ __emplace_back_assume_capacity (std::forward<_Args>(__args)...);
1196+ ++__end;
1197+ },
1198+ [&] { __end = __emplace_back_slow_path (std::forward<_Args>(__args)...); });
1199+
11801200 this ->__end_ = __end;
11811201#if _LIBCPP_STD_VER >= 17
11821202 return *(__end - 1 );
0 commit comments