mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[Support] Move LLD's parallel algorithm wrappers to support
Essentially takes the lld/Common/Threads.h wrappers and moves them to the llvm/Support/Paralle.h algorithm header. The changes are: - Remove policy parameter, since all clients use `par`. - Rename the methods to `parallelSort` etc to match LLVM style, since they are no longer C++17 pstl compatible. - Move algorithms from llvm::parallel:: to llvm::, since they have "parallel" in the name and are no longer overloads of the regular algorithms. - Add range overloads - Use the sequential algorithm directly when 1 thread is requested (skips task grouping) - Fix the index type of parallelForEachN to size_t. Nobody in LLVM was using any other parameter, and it made overload resolution hard for for_each_n(par, 0, foo.size(), ...) because 0 is int, not size_t. Remove Threads.h and update LLD for that. This is a prerequisite for parallel public symbol processing in the PDB library, which is in LLVM. Reviewed By: MaskRay, aganea Differential Revision: https://reviews.llvm.org/D79390
This commit is contained in:
parent
9628857335
commit
6064535152
@ -22,17 +22,6 @@
|
||||
namespace llvm {
|
||||
|
||||
namespace parallel {
|
||||
struct sequential_execution_policy {};
|
||||
struct parallel_execution_policy {};
|
||||
|
||||
template <typename T>
|
||||
struct is_execution_policy
|
||||
: public std::integral_constant<
|
||||
bool, llvm::is_one_of<T, sequential_execution_policy,
|
||||
parallel_execution_policy>::value> {};
|
||||
|
||||
constexpr sequential_execution_policy seq{};
|
||||
constexpr parallel_execution_policy par{};
|
||||
|
||||
// Strategy for the default executor used by the parallel routines provided by
|
||||
// this file. It defaults to using all hardware threads and should be
|
||||
@ -169,61 +158,58 @@ void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Iter>
|
||||
using DefComparator =
|
||||
std::less<typename std::iterator_traits<Iter>::value_type>;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace parallel
|
||||
|
||||
// sequential algorithm implementations.
|
||||
template <class Policy, class RandomAccessIterator,
|
||||
class Comparator = detail::DefComparator<RandomAccessIterator>>
|
||||
void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End,
|
||||
const Comparator &Comp = Comparator()) {
|
||||
static_assert(is_execution_policy<Policy>::value,
|
||||
"Invalid execution policy!");
|
||||
template <class RandomAccessIterator,
|
||||
class Comparator = std::less<
|
||||
typename std::iterator_traits<RandomAccessIterator>::value_type>>
|
||||
void parallelSort(RandomAccessIterator Start, RandomAccessIterator End,
|
||||
const Comparator &Comp = Comparator()) {
|
||||
#if LLVM_ENABLE_THREADS
|
||||
if (parallel::strategy.ThreadsRequested != 1) {
|
||||
parallel::detail::parallel_sort(Start, End, Comp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
llvm::sort(Start, End, Comp);
|
||||
}
|
||||
|
||||
template <class Policy, class IterTy, class FuncTy>
|
||||
void for_each(Policy policy, IterTy Begin, IterTy End, FuncTy Fn) {
|
||||
static_assert(is_execution_policy<Policy>::value,
|
||||
"Invalid execution policy!");
|
||||
template <class IterTy, class FuncTy>
|
||||
void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) {
|
||||
#if LLVM_ENABLE_THREADS
|
||||
if (parallel::strategy.ThreadsRequested != 1) {
|
||||
parallel::detail::parallel_for_each(Begin, End, Fn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
std::for_each(Begin, End, Fn);
|
||||
}
|
||||
|
||||
template <class Policy, class IndexTy, class FuncTy>
|
||||
void for_each_n(Policy policy, IndexTy Begin, IndexTy End, FuncTy Fn) {
|
||||
static_assert(is_execution_policy<Policy>::value,
|
||||
"Invalid execution policy!");
|
||||
for (IndexTy I = Begin; I != End; ++I)
|
||||
template <class FuncTy>
|
||||
void parallelForEachN(size_t Begin, size_t End, FuncTy Fn) {
|
||||
#if LLVM_ENABLE_THREADS
|
||||
if (parallel::strategy.ThreadsRequested != 1) {
|
||||
parallel::detail::parallel_for_each_n(Begin, End, Fn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
for (size_t I = Begin; I != End; ++I)
|
||||
Fn(I);
|
||||
}
|
||||
|
||||
// Parallel algorithm implementations, only available when LLVM_ENABLE_THREADS
|
||||
// is true.
|
||||
#if LLVM_ENABLE_THREADS
|
||||
template <class RandomAccessIterator,
|
||||
class Comparator = detail::DefComparator<RandomAccessIterator>>
|
||||
void sort(parallel_execution_policy policy, RandomAccessIterator Start,
|
||||
RandomAccessIterator End, const Comparator &Comp = Comparator()) {
|
||||
detail::parallel_sort(Start, End, Comp);
|
||||
// Range wrappers.
|
||||
template <class RangeTy,
|
||||
class Comparator = std::less<decltype(*std::begin(RangeTy()))>>
|
||||
void parallelSort(RangeTy &&R, const Comparator &Comp = Comparator()) {
|
||||
parallelSort(std::begin(R), std::end(R), Comp);
|
||||
}
|
||||
|
||||
template <class IterTy, class FuncTy>
|
||||
void for_each(parallel_execution_policy policy, IterTy Begin, IterTy End,
|
||||
FuncTy Fn) {
|
||||
detail::parallel_for_each(Begin, End, Fn);
|
||||
template <class RangeTy, class FuncTy>
|
||||
void parallelForEach(RangeTy &&R, FuncTy Fn) {
|
||||
parallelForEach(std::begin(R), std::end(R), Fn);
|
||||
}
|
||||
|
||||
template <class IndexTy, class FuncTy>
|
||||
void for_each_n(parallel_execution_policy policy, IndexTy Begin, IndexTy End,
|
||||
FuncTy Fn) {
|
||||
detail::parallel_for_each_n(Begin, End, Fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace parallel
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_SUPPORT_PARALLEL_H
|
||||
|
@ -30,7 +30,7 @@ TEST(Parallel, sort) {
|
||||
for (auto &i : array)
|
||||
i = dist(randEngine);
|
||||
|
||||
sort(parallel::par, std::begin(array), std::end(array));
|
||||
parallelSort(std::begin(array), std::end(array));
|
||||
ASSERT_TRUE(llvm::is_sorted(array));
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ TEST(Parallel, parallel_for) {
|
||||
// writing.
|
||||
uint32_t range[2050];
|
||||
std::fill(range, range + 2050, 1);
|
||||
for_each_n(parallel::par, 0, 2049, [&range](size_t I) { ++range[I]; });
|
||||
parallelForEachN(0, 2049, [&range](size_t I) { ++range[I]; });
|
||||
|
||||
uint32_t expected[2049];
|
||||
std::fill(expected, expected + 2049, 2);
|
||||
|
Loading…
Reference in New Issue
Block a user