[lld] r302613 - [Core] Make parallel algorithms match C++ Parallelism TS.
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Wed May 10 09:39:17 PDT 2017
I just committed r302690
On Wed, May 10, 2017 at 9:34 AM, Hans Wennborg <hans at chromium.org> wrote:
> I think maybe we can just move the #ifdef a little so
> detail::DefComparator is always defined. I'm trying that right now.
>
> On Wed, May 10, 2017 at 9:29 AM, Zachary Turner <zturner at google.com> wrote:
>> I will try a build with LLVM_ENABLE_THREADS=0 locally and see if I can repro
>>
>> On Wed, May 10, 2017 at 9:28 AM Hans Wennborg <hans at chromium.org> wrote:
>>>
>>> Oh, it's because of #if LLVM_ENABLE_THREADS
>>>
>>> On Wed, May 10, 2017 at 9:27 AM, Hans Wennborg <hans at chromium.org> wrote:
>>> > This broke Chromium's lld builds, e.g.
>>> >
>>> > https://build.chromium.org/p/chromium.fyi/builders/ClangToTLinux/builds/8161
>>> >
>>> > I'm not sure why it's not a problem on the regular LLVM buildbots,
>>> > though.
>>> >
>>> > On Tue, May 9, 2017 at 6:16 PM, Zachary Turner via llvm-commits
>>> > <llvm-commits at lists.llvm.org> wrote:
>>> >> Author: zturner
>>> >> Date: Tue May 9 20:16:22 2017
>>> >> New Revision: 302613
>>> >>
>>> >> URL: http://llvm.org/viewvc/llvm-project?rev=302613&view=rev
>>> >> Log:
>>> >> [Core] Make parallel algorithms match C++ Parallelism TS.
>>> >>
>>> >> Differential Revision: https://reviews.llvm.org/D33016
>>> >>
>>> >> Modified:
>>> >> lld/trunk/COFF/ICF.cpp
>>> >> lld/trunk/COFF/MapFile.cpp
>>> >> lld/trunk/COFF/Writer.cpp
>>> >> lld/trunk/ELF/Threads.h
>>> >> lld/trunk/include/lld/Core/Parallel.h
>>> >> lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp
>>> >> lld/trunk/unittests/CoreTests/ParallelTest.cpp
>>> >>
>>> >> Modified: lld/trunk/COFF/ICF.cpp
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/COFF/ICF.cpp (original)
>>> >> +++ lld/trunk/COFF/ICF.cpp Tue May 9 20:16:22 2017
>>> >> @@ -192,7 +192,7 @@ void ICF::forEachClass(std::function<voi
>>> >> // Split sections into 256 shards and call Fn in parallel.
>>> >> size_t NumShards = 256;
>>> >> size_t Step = Chunks.size() / NumShards;
>>> >> - parallel_for(size_t(0), NumShards, [&](size_t I) {
>>> >> + for_each_n(parallel::par, size_t(0), NumShards, [&](size_t I) {
>>> >> forEachClassRange(I * Step, (I + 1) * Step, Fn);
>>> >> });
>>> >> forEachClassRange(Step * NumShards, Chunks.size(), Fn);
>>> >>
>>> >> Modified: lld/trunk/COFF/MapFile.cpp
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/MapFile.cpp?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/COFF/MapFile.cpp (original)
>>> >> +++ lld/trunk/COFF/MapFile.cpp Tue May 9 20:16:22 2017
>>> >> @@ -76,7 +76,7 @@ static SymbolMapTy getSectionSyms(ArrayR
>>> >> static DenseMap<DefinedRegular *, std::string>
>>> >> getSymbolStrings(ArrayRef<DefinedRegular *> Syms) {
>>> >> std::vector<std::string> Str(Syms.size());
>>> >> - parallel_for((size_t)0, Syms.size(), [&](size_t I) {
>>> >> + for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) {
>>> >> raw_string_ostream OS(Str[I]);
>>> >> writeHeader(OS, Syms[I]->getRVA(), 0, 0);
>>> >> OS << indent(2) << toString(*Syms[I]);
>>> >>
>>> >> Modified: lld/trunk/COFF/Writer.cpp
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/COFF/Writer.cpp (original)
>>> >> +++ lld/trunk/COFF/Writer.cpp Tue May 9 20:16:22 2017
>>> >> @@ -745,8 +745,8 @@ void Writer::writeSections() {
>>> >> // ADD instructions).
>>> >> if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE)
>>> >> memset(SecBuf, 0xCC, Sec->getRawSize());
>>> >> - parallel_for_each(Sec->getChunks().begin(),
>>> >> Sec->getChunks().end(),
>>> >> - [&](Chunk *C) { C->writeTo(SecBuf); });
>>> >> + for_each(parallel::par, Sec->getChunks().begin(),
>>> >> Sec->getChunks().end(),
>>> >> + [&](Chunk *C) { C->writeTo(SecBuf); });
>>> >> }
>>> >> }
>>> >>
>>> >> @@ -760,16 +760,14 @@ void Writer::sortExceptionTable() {
>>> >> uint8_t *End = Begin + Sec->getVirtualSize();
>>> >> if (Config->Machine == AMD64) {
>>> >> struct Entry { ulittle32_t Begin, End, Unwind; };
>>> >> - parallel_sort(
>>> >> - (Entry *)Begin, (Entry *)End,
>>> >> - [](const Entry &A, const Entry &B) { return A.Begin < B.Begin;
>>> >> });
>>> >> + sort(parallel::par, (Entry *)Begin, (Entry *)End,
>>> >> + [](const Entry &A, const Entry &B) { return A.Begin <
>>> >> B.Begin; });
>>> >> return;
>>> >> }
>>> >> if (Config->Machine == ARMNT) {
>>> >> struct Entry { ulittle32_t Begin, Unwind; };
>>> >> - parallel_sort(
>>> >> - (Entry *)Begin, (Entry *)End,
>>> >> - [](const Entry &A, const Entry &B) { return A.Begin < B.Begin;
>>> >> });
>>> >> + sort(parallel::par, (Entry *)Begin, (Entry *)End,
>>> >> + [](const Entry &A, const Entry &B) { return A.Begin <
>>> >> B.Begin; });
>>> >> return;
>>> >> }
>>> >> errs() << "warning: don't know how to handle .pdata.\n";
>>> >>
>>> >> Modified: lld/trunk/ELF/Threads.h
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Threads.h?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/ELF/Threads.h (original)
>>> >> +++ lld/trunk/ELF/Threads.h Tue May 9 20:16:22 2017
>>> >> @@ -71,19 +71,17 @@ namespace elf {
>>> >> template <class IterTy, class FuncTy>
>>> >> void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) {
>>> >> if (Config->Threads)
>>> >> - parallel_for_each(Begin, End, Fn);
>>> >> + for_each(parallel::par, Begin, End, Fn);
>>> >> else
>>> >> - std::for_each(Begin, End, Fn);
>>> >> + for_each(parallel::seq, Begin, End, Fn);
>>> >> }
>>> >>
>>> >> inline void parallelFor(size_t Begin, size_t End,
>>> >> std::function<void(size_t)> Fn) {
>>> >> - if (Config->Threads) {
>>> >> - parallel_for(Begin, End, Fn);
>>> >> - } else {
>>> >> - for (size_t I = Begin; I < End; ++I)
>>> >> - Fn(I);
>>> >> - }
>>> >> + if (Config->Threads)
>>> >> + for_each_n(parallel::par, Begin, End, Fn);
>>> >> + else
>>> >> + for_each_n(parallel::seq, Begin, End, Fn);
>>> >> }
>>> >> }
>>> >> }
>>> >>
>>> >> Modified: lld/trunk/include/lld/Core/Parallel.h
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Parallel.h?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/include/lld/Core/Parallel.h (original)
>>> >> +++ lld/trunk/include/lld/Core/Parallel.h Tue May 9 20:16:22 2017
>>> >> @@ -12,8 +12,9 @@
>>> >>
>>> >> #include "lld/Core/LLVM.h"
>>> >> #include "lld/Core/TaskGroup.h"
>>> >> -#include "llvm/Support/MathExtras.h"
>>> >> +#include "llvm/ADT/STLExtras.h"
>>> >> #include "llvm/Config/llvm-config.h"
>>> >> +#include "llvm/Support/MathExtras.h"
>>> >>
>>> >> #include <algorithm>
>>> >>
>>> >> @@ -24,25 +25,40 @@
>>> >>
>>> >> namespace lld {
>>> >>
>>> >> -#if !LLVM_ENABLE_THREADS
>>> >> -template <class RandomAccessIterator, class Comparator>
>>> >> -void parallel_sort(
>>> >> - RandomAccessIterator Start, RandomAccessIterator End,
>>> >> - const Comparator &Comp = std::less<
>>> >> - typename
>>> >> std::iterator_traits<RandomAccessIterator>::value_type>()) {
>>> >> - std::sort(Start, End, Comp);
>>> >> -}
>>> >> -#elif defined(_MSC_VER)
>>> >> -// Use ppl parallel_sort on Windows.
>>> >> +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{};
>>> >> +
>>> >> +#if LLVM_ENABLE_THREADS
>>> >> +
>>> >> +namespace detail {
>>> >> +
>>> >> +#if defined(_MSC_VER)
>>> >> template <class RandomAccessIterator, class Comparator>
>>> >> -void parallel_sort(
>>> >> - RandomAccessIterator Start, RandomAccessIterator End,
>>> >> - const Comparator &Comp = std::less<
>>> >> - typename
>>> >> std::iterator_traits<RandomAccessIterator>::value_type>()) {
>>> >> +void parallel_sort(RandomAccessIterator Start, RandomAccessIterator
>>> >> End,
>>> >> + const Comparator &Comp) {
>>> >> concurrency::parallel_sort(Start, End, Comp);
>>> >> }
>>> >> +template <class IterTy, class FuncTy>
>>> >> +void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
>>> >> + concurrency::parallel_for_each(Begin, End, Fn);
>>> >> +}
>>> >> +
>>> >> +template <class IndexTy, class FuncTy>
>>> >> +void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
>>> >> + concurrency::parallel_for(Begin, End, Fn);
>>> >> +}
>>> >> +
>>> >> #else
>>> >> -namespace detail {
>>> >> const ptrdiff_t MinParallelSize = 1024;
>>> >>
>>> >> /// \brief Inclusive median.
>>> >> @@ -83,46 +99,15 @@ void parallel_quick_sort(RandomAccessIte
>>> >> });
>>> >> parallel_quick_sort(Pivot + 1, End, Comp, TG, Depth - 1);
>>> >> }
>>> >> -}
>>> >>
>>> >> template <class RandomAccessIterator, class Comparator>
>>> >> -void parallel_sort(
>>> >> - RandomAccessIterator Start, RandomAccessIterator End,
>>> >> - const Comparator &Comp = std::less<
>>> >> - typename
>>> >> std::iterator_traits<RandomAccessIterator>::value_type>()) {
>>> >> +void parallel_sort(RandomAccessIterator Start, RandomAccessIterator
>>> >> End,
>>> >> + const Comparator &Comp) {
>>> >> TaskGroup TG;
>>> >> - detail::parallel_quick_sort(Start, End, Comp, TG,
>>> >> - llvm::Log2_64(std::distance(Start, End))
>>> >> + 1);
>>> >> -}
>>> >> -#endif
>>> >> -
>>> >> -template <class T> void parallel_sort(T *Start, T *End) {
>>> >> - parallel_sort(Start, End, std::less<T>());
>>> >> -}
>>> >> -
>>> >> -#if !LLVM_ENABLE_THREADS
>>> >> -template <class IterTy, class FuncTy>
>>> >> -void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
>>> >> - std::for_each(Begin, End, Fn);
>>> >> -}
>>> >> -
>>> >> -template <class IndexTy, class FuncTy>
>>> >> -void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
>>> >> - for (IndexTy I = Begin; I != End; ++I)
>>> >> - Fn(I);
>>> >> -}
>>> >> -#elif defined(_MSC_VER)
>>> >> -// Use ppl parallel_for_each on Windows.
>>> >> -template <class IterTy, class FuncTy>
>>> >> -void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
>>> >> - concurrency::parallel_for_each(Begin, End, Fn);
>>> >> + parallel_quick_sort(Start, End, Comp, TG,
>>> >> + llvm::Log2_64(std::distance(Start, End)) + 1);
>>> >> }
>>> >>
>>> >> -template <class IndexTy, class FuncTy>
>>> >> -void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
>>> >> - concurrency::parallel_for(Begin, End, Fn);
>>> >> -}
>>> >> -#else
>>> >> template <class IterTy, class FuncTy>
>>> >> void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
>>> >> // TaskGroup has a relatively high overhead, so we want to reduce
>>> >> @@ -142,7 +127,7 @@ void parallel_for_each(IterTy Begin, Ite
>>> >> }
>>> >>
>>> >> template <class IndexTy, class FuncTy>
>>> >> -void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
>>> >> +void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
>>> >> ptrdiff_t TaskSize = (End - Begin) / 1024;
>>> >> if (TaskSize == 0)
>>> >> TaskSize = 1;
>>> >> @@ -160,7 +145,65 @@ void parallel_for(IndexTy Begin, IndexTy
>>> >> Fn(J);
>>> >> });
>>> >> }
>>> >> +
>>> >> +#endif
>>> >> +
>>> >> +template <typename Iter>
>>> >> +using DefComparator =
>>> >> + std::less<typename std::iterator_traits<Iter>::value_type>;
>>> >> +
>>> >> +} // namespace detail
>>> >> #endif
>>> >> +
>>> >> +// 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!");
>>> >> + std::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!");
>>> >> + 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)
>>> >> + Fn(I);
>>> >> +}
>>> >> +
>>> >> +// Parallel algorithm implementations, only available when
>>> >> LLVM_ENABLE_THREADS
>>> >> +// is true.
>>> >> +#if defined(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);
>>> >> +}
>>> >> +
>>> >> +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 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
>>> >> } // End namespace lld
>>> >>
>>> >> #endif // LLD_CORE_PARALLEL_H
>>> >>
>>> >> Modified: lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp (original)
>>> >> +++ lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp Tue May 9 20:16:22
>>> >> 2017
>>> >> @@ -461,10 +461,10 @@ llvm::Error LayoutPass::perform(SimpleFi
>>> >> });
>>> >>
>>> >> std::vector<LayoutPass::SortKey> vec = decorate(atomRange);
>>> >> - parallel_sort(vec.begin(), vec.end(),
>>> >> - [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r)
>>> >> -> bool {
>>> >> - return compareAtoms(l, r, _customSorter);
>>> >> - });
>>> >> + sort(parallel::par, vec.begin(), vec.end(),
>>> >> + [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r)
>>> >> -> bool {
>>> >> + return compareAtoms(l, r, _customSorter);
>>> >> + });
>>> >> DEBUG(checkTransitivity(vec, _customSorter));
>>> >> undecorate(atomRange, vec);
>>> >>
>>> >>
>>> >> Modified: lld/trunk/unittests/CoreTests/ParallelTest.cpp
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/CoreTests/ParallelTest.cpp?rev=302613&r1=302612&r2=302613&view=diff
>>> >>
>>> >> ==============================================================================
>>> >> --- lld/trunk/unittests/CoreTests/ParallelTest.cpp (original)
>>> >> +++ lld/trunk/unittests/CoreTests/ParallelTest.cpp Tue May 9 20:16:22
>>> >> 2017
>>> >> @@ -26,7 +26,7 @@ TEST(Parallel, sort) {
>>> >> for (auto &i : array)
>>> >> i = dist(randEngine);
>>> >>
>>> >> - lld::parallel_sort(std::begin(array), std::end(array));
>>> >> + sort(lld::parallel::par, std::begin(array), std::end(array));
>>> >> ASSERT_TRUE(std::is_sorted(std::begin(array), std::end(array)));
>>> >> }
>>> >>
>>> >> @@ -36,7 +36,7 @@ TEST(Parallel, parallel_for) {
>>> >> // writing.
>>> >> uint32_t range[2050];
>>> >> std::fill(range, range + 2050, 1);
>>> >> - lld::parallel_for(0, 2049, [&range](size_t I) { ++range[I]; });
>>> >> + for_each_n(lld::parallel::par, 0, 2049, [&range](size_t I) {
>>> >> ++range[I]; });
>>> >>
>>> >> uint32_t expected[2049];
>>> >> std::fill(expected, expected + 2049, 2);
>>> >>
>>> >>
>>> >> _______________________________________________
>>> >> llvm-commits mailing list
>>> >> llvm-commits at lists.llvm.org
>>> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list