diff --git a/libcxx/cmake/caches/Apple.cmake b/libcxx/cmake/caches/Apple.cmake --- a/libcxx/cmake/caches/Apple.cmake +++ b/libcxx/cmake/caches/Apple.cmake @@ -7,7 +7,7 @@ set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "") -set(LIBCXX_PSTL_CPU_BACKEND libdispatch) +set(LIBCXX_PSTL_CPU_BACKEND libdispatch CACHE STRING "") set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h --- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h +++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H #include <__algorithm/lower_bound.h> +#include <__algorithm/max.h> #include <__algorithm/upper_bound.h> #include <__atomic/atomic.h> #include <__config> @@ -25,7 +26,9 @@ #include <__utility/terminate_on_exception.h> #include #include -#include + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 @@ -107,13 +110,20 @@ } using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>; + auto const __n_ranges = __partitions.__chunk_count_ + 1; - vector<__merge_range_t> __ranges; - __ranges.reserve(__partitions.__chunk_count_ + 1); + // TODO: use __uninitialized_buffer + auto __destroy = [=](__merge_range_t* __ptr) { + std::destroy_n(__ptr, __n_ranges); + std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges); + }; + unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges( + std::allocator<__merge_range_t>().allocate(__n_ranges), __destroy); // TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case std::__terminate_on_exception([&] { - __ranges.emplace_back(__first1, __first2, __result); + __merge_range_t* __r = __ranges.get(); + std::construct_at(__r++, __first1, __first2, __result); bool __iterate_first_range = __last1 - __first1 > __last2 - __first2; @@ -137,14 +147,14 @@ }; // handle first chunk - __ranges.emplace_back(__compute_chunk(__partitions.__first_chunk_size_)); + std::construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_)); // handle 2 -> N - 1 chunks for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i) - __ranges.emplace_back(__compute_chunk(__partitions.__chunk_size_)); + std::construct_at(__r++, __compute_chunk(__partitions.__chunk_size_)); // handle last chunk - __ranges.emplace_back(__last1, __last2, __result); + std::construct_at(__r, __last1, __last2, __result); __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) { auto __first_iters = __ranges[__index]; @@ -223,4 +233,6 @@ #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H diff --git a/libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp b/libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp --- a/libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp +++ b/libcxx/test/libcxx/vendor/apple/system-install-properties.sh.cpp @@ -42,3 +42,7 @@ // when they are loaded by dyld, if the compatibility version was bumped. // // RUN: otool -L "%{lib}/libc++.1.dylib" | grep "libc++.1.dylib" | grep "compatibility version 1.0.0" + +// Make sure we use the libdispatch backend for the PSTL. +// +// RUN: grep "%{include}/__config_site" -e '#define _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH'