12
12
13
13
#include " lld/Core/LLVM.h"
14
14
#include " lld/Core/TaskGroup.h"
15
- #include " llvm/Support/MathExtras .h"
15
+ #include " llvm/ADT/STLExtras .h"
16
16
#include " llvm/Config/llvm-config.h"
17
+ #include " llvm/Support/MathExtras.h"
17
18
18
19
#include < algorithm>
19
20
24
25
25
26
namespace lld {
26
27
27
- #if !LLVM_ENABLE_THREADS
28
- template <class RandomAccessIterator , class Comparator >
29
- void parallel_sort (
30
- RandomAccessIterator Start, RandomAccessIterator End,
31
- const Comparator &Comp = std::less<
32
- typename std::iterator_traits<RandomAccessIterator>::value_type>()) {
33
- std::sort (Start, End, Comp);
34
- }
35
- #elif defined(_MSC_VER)
36
- // Use ppl parallel_sort on Windows.
28
+ namespace parallel {
29
+ struct sequential_execution_policy {};
30
+ struct parallel_execution_policy {};
31
+
32
+ template <typename T>
33
+ struct is_execution_policy
34
+ : public std::integral_constant<
35
+ bool , llvm::is_one_of<T, sequential_execution_policy,
36
+ parallel_execution_policy>::value> {};
37
+
38
+ constexpr sequential_execution_policy seq{};
39
+ constexpr parallel_execution_policy par{};
40
+
41
+ #if LLVM_ENABLE_THREADS
42
+
43
+ namespace detail {
44
+
45
+ #if defined(_MSC_VER)
37
46
template <class RandomAccessIterator , class Comparator >
38
- void parallel_sort (
39
- RandomAccessIterator Start, RandomAccessIterator End,
40
- const Comparator &Comp = std::less<
41
- typename std::iterator_traits<RandomAccessIterator>::value_type>()) {
47
+ void parallel_sort (RandomAccessIterator Start, RandomAccessIterator End,
48
+ const Comparator &Comp) {
42
49
concurrency::parallel_sort (Start, End, Comp);
43
50
}
51
+ template <class IterTy , class FuncTy >
52
+ void parallel_for_each (IterTy Begin, IterTy End, FuncTy Fn) {
53
+ concurrency::parallel_for_each (Begin, End, Fn);
54
+ }
55
+
56
+ template <class IndexTy , class FuncTy >
57
+ void parallel_for_each_n (IndexTy Begin, IndexTy End, FuncTy Fn) {
58
+ concurrency::parallel_for (Begin, End, Fn);
59
+ }
60
+
44
61
#else
45
- namespace detail {
46
62
const ptrdiff_t MinParallelSize = 1024 ;
47
63
48
64
// / \brief Inclusive median.
@@ -83,46 +99,15 @@ void parallel_quick_sort(RandomAccessIterator Start, RandomAccessIterator End,
83
99
});
84
100
parallel_quick_sort (Pivot + 1 , End, Comp, TG, Depth - 1 );
85
101
}
86
- }
87
102
88
103
template <class RandomAccessIterator , class Comparator >
89
- void parallel_sort (
90
- RandomAccessIterator Start, RandomAccessIterator End,
91
- const Comparator &Comp = std::less<
92
- typename std::iterator_traits<RandomAccessIterator>::value_type>()) {
104
+ void parallel_sort (RandomAccessIterator Start, RandomAccessIterator End,
105
+ const Comparator &Comp) {
93
106
TaskGroup TG;
94
- detail::parallel_quick_sort (Start, End, Comp, TG,
95
- llvm::Log2_64 (std::distance (Start, End)) + 1 );
96
- }
97
- #endif
98
-
99
- template <class T > void parallel_sort (T *Start, T *End) {
100
- parallel_sort (Start, End, std::less<T>());
107
+ parallel_quick_sort (Start, End, Comp, TG,
108
+ llvm::Log2_64 (std::distance (Start, End)) + 1 );
101
109
}
102
110
103
- #if !LLVM_ENABLE_THREADS
104
- template <class IterTy , class FuncTy >
105
- void parallel_for_each (IterTy Begin, IterTy End, FuncTy Fn) {
106
- std::for_each (Begin, End, Fn);
107
- }
108
-
109
- template <class IndexTy , class FuncTy >
110
- void parallel_for (IndexTy Begin, IndexTy End, FuncTy Fn) {
111
- for (IndexTy I = Begin; I != End; ++I)
112
- Fn (I);
113
- }
114
- #elif defined(_MSC_VER)
115
- // Use ppl parallel_for_each on Windows.
116
- template <class IterTy , class FuncTy >
117
- void parallel_for_each (IterTy Begin, IterTy End, FuncTy Fn) {
118
- concurrency::parallel_for_each (Begin, End, Fn);
119
- }
120
-
121
- template <class IndexTy , class FuncTy >
122
- void parallel_for (IndexTy Begin, IndexTy End, FuncTy Fn) {
123
- concurrency::parallel_for (Begin, End, Fn);
124
- }
125
- #else
126
111
template <class IterTy , class FuncTy >
127
112
void parallel_for_each (IterTy Begin, IterTy End, FuncTy Fn) {
128
113
// TaskGroup has a relatively high overhead, so we want to reduce
@@ -142,7 +127,7 @@ void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
142
127
}
143
128
144
129
template <class IndexTy , class FuncTy >
145
- void parallel_for (IndexTy Begin, IndexTy End, FuncTy Fn) {
130
+ void parallel_for_each_n (IndexTy Begin, IndexTy End, FuncTy Fn) {
146
131
ptrdiff_t TaskSize = (End - Begin) / 1024 ;
147
132
if (TaskSize == 0 )
148
133
TaskSize = 1 ;
@@ -160,7 +145,65 @@ void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
160
145
Fn (J);
161
146
});
162
147
}
148
+
149
+ #endif
150
+
151
+ template <typename Iter>
152
+ using DefComparator =
153
+ std::less<typename std::iterator_traits<Iter>::value_type>;
154
+
155
+ } // namespace detail
163
156
#endif
157
+
158
+ // sequential algorithm implementations.
159
+ template <class Policy , class RandomAccessIterator ,
160
+ class Comparator = detail::DefComparator<RandomAccessIterator>>
161
+ void sort (Policy policy, RandomAccessIterator Start, RandomAccessIterator End,
162
+ const Comparator &Comp = Comparator()) {
163
+ static_assert (is_execution_policy<Policy>::value,
164
+ " Invalid execution policy!" );
165
+ std::sort (Start, End, Comp);
166
+ }
167
+
168
+ template <class Policy , class IterTy , class FuncTy >
169
+ void for_each (Policy policy, IterTy Begin, IterTy End, FuncTy Fn) {
170
+ static_assert (is_execution_policy<Policy>::value,
171
+ " Invalid execution policy!" );
172
+ std::for_each (Begin, End, Fn);
173
+ }
174
+
175
+ template <class Policy , class IndexTy , class FuncTy >
176
+ void for_each_n (Policy policy, IndexTy Begin, IndexTy End, FuncTy Fn) {
177
+ static_assert (is_execution_policy<Policy>::value,
178
+ " Invalid execution policy!" );
179
+ for (IndexTy I = Begin; I != End; ++I)
180
+ Fn (I);
181
+ }
182
+
183
+ // Parallel algorithm implementations, only available when LLVM_ENABLE_THREADS
184
+ // is true.
185
+ #if defined(LLVM_ENABLE_THREADS)
186
+ template <class RandomAccessIterator ,
187
+ class Comparator = detail::DefComparator<RandomAccessIterator>>
188
+ void sort (parallel_execution_policy policy, RandomAccessIterator Start,
189
+ RandomAccessIterator End, const Comparator &Comp = Comparator()) {
190
+ detail::parallel_sort (Start, End, Comp);
191
+ }
192
+
193
+ template <class IterTy , class FuncTy >
194
+ void for_each (parallel_execution_policy policy, IterTy Begin, IterTy End,
195
+ FuncTy Fn) {
196
+ detail::parallel_for_each (Begin, End, Fn);
197
+ }
198
+
199
+ template <class IndexTy , class FuncTy >
200
+ void for_each_n (parallel_execution_policy policy, IndexTy Begin, IndexTy End,
201
+ FuncTy Fn) {
202
+ detail::parallel_for_each_n (Begin, End, Fn);
203
+ }
204
+ #endif
205
+
206
+ } // namespace parallel
164
207
} // End namespace lld
165
208
166
209
#endif // LLD_CORE_PARALLEL_H
0 commit comments