From 3a57fbd6db74b2eb5cd2789036c521f702cb323e Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 11 May 2017 00:03:52 +0000 Subject: [PATCH] [Support] Move Parallel algorithms from LLD to LLVM. Differential Revision: https://reviews.llvm.org/D33024 llvm-svn: 302748 --- lld/COFF/ICF.cpp | 2 +- lld/COFF/MapFile.cpp | 2 +- lld/COFF/Writer.cpp | 2 +- lld/ELF/Threads.h | 10 +-- lld/include/lld/Core/TaskGroup.h | 65 ------------------- lld/lib/Core/CMakeLists.txt | 1 - lld/lib/ReaderWriter/MachO/LayoutPass.cpp | 4 +- lld/unittests/CMakeLists.txt | 1 - lld/unittests/CoreTests/CMakeLists.txt | 7 -- .../include/llvm/Support}/Parallel.h | 59 ++++++++++++++--- llvm/lib/Support/CMakeLists.txt | 1 + .../lib/Support/Parallel.cpp | 15 ++--- llvm/unittests/Support/CMakeLists.txt | 1 + .../unittests/Support}/ParallelTest.cpp | 10 +-- 14 files changed, 73 insertions(+), 107 deletions(-) delete mode 100644 lld/include/lld/Core/TaskGroup.h delete mode 100644 lld/unittests/CoreTests/CMakeLists.txt rename {lld/include/lld/Core => llvm/include/llvm/Support}/Parallel.h (85%) rename lld/lib/Core/TaskGroup.cpp => llvm/lib/Support/Parallel.cpp (90%) rename {lld/unittests/CoreTests => llvm/unittests/Support}/ParallelTest.cpp (82%) diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index e3a7d27c39b1..3b7cc424f0a2 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -21,9 +21,9 @@ #include "Chunks.h" #include "Error.h" #include "Symbols.h" -#include "lld/Core/Parallel.h" #include "llvm/ADT/Hashing.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Parallel.h" #include "llvm/Support/raw_ostream.h" #include #include diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp index 7df88f38879f..b63d4672c7d5 100644 --- a/lld/COFF/MapFile.cpp +++ b/lld/COFF/MapFile.cpp @@ -25,7 +25,7 @@ #include "Symbols.h" #include "Writer.h" -#include "lld/Core/Parallel.h" +#include "llvm/Support/Parallel.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index d61d87172f43..5c9c8375dadc 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -17,13 +17,13 @@ #include "PDB.h" #include "SymbolTable.h" #include "Symbols.h" -#include "lld/Core/Parallel.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/Parallel.h" #include "llvm/Support/RandomNumberGenerator.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/lld/ELF/Threads.h b/lld/ELF/Threads.h index 0c291c7b703a..e01afd4d3fc9 100644 --- a/lld/ELF/Threads.h +++ b/lld/ELF/Threads.h @@ -61,7 +61,7 @@ #include "Config.h" -#include "lld/Core/Parallel.h" +#include "llvm/Support/Parallel.h" #include namespace lld { @@ -70,17 +70,17 @@ namespace elf { template void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) { if (Config->Threads) - for_each(parallel::par, Begin, End, Fn); + for_each(llvm::parallel::par, Begin, End, Fn); else - for_each(parallel::seq, Begin, End, Fn); + for_each(llvm::parallel::seq, Begin, End, Fn); } inline void parallelForEachN(size_t Begin, size_t End, std::function Fn) { if (Config->Threads) - for_each_n(parallel::par, Begin, End, Fn); + for_each_n(llvm::parallel::par, Begin, End, Fn); else - for_each_n(parallel::seq, Begin, End, Fn); + for_each_n(llvm::parallel::seq, Begin, End, Fn); } } } diff --git a/lld/include/lld/Core/TaskGroup.h b/lld/include/lld/Core/TaskGroup.h deleted file mode 100644 index 6cd173ebbbb6..000000000000 --- a/lld/include/lld/Core/TaskGroup.h +++ /dev/null @@ -1,65 +0,0 @@ -//===- lld/Core/TaskGroup.h - Task Group ----------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_CORE_TASKGROUP_H -#define LLD_CORE_TASKGROUP_H - -#include "lld/Core/LLVM.h" - -#include -#include -#include - -namespace lld { -/// \brief Allows one or more threads to wait on a potentially unknown number of -/// events. -/// -/// A latch starts at \p count. inc() increments this, and dec() decrements it. -/// All calls to sync() will block while the count is not 0. -/// -/// Calling dec() on a Latch with a count of 0 has undefined behaivor. -class Latch { - uint32_t Count; - mutable std::mutex Mutex; - mutable std::condition_variable Cond; - -public: - explicit Latch(uint32_t count = 0) : Count(count) {} - ~Latch() { sync(); } - - void inc() { - std::unique_lock lock(Mutex); - ++Count; - } - - void dec() { - std::unique_lock lock(Mutex); - if (--Count == 0) - Cond.notify_all(); - } - - void sync() const { - std::unique_lock lock(Mutex); - Cond.wait(lock, [&] { return Count == 0; }); - } -}; - -/// \brief Allows launching a number of tasks and waiting for them to finish -/// either explicitly via sync() or implicitly on destruction. -class TaskGroup { - Latch L; - -public: - void spawn(std::function F); - - void sync() const { L.sync(); } -}; -} - -#endif diff --git a/lld/lib/Core/CMakeLists.txt b/lld/lib/Core/CMakeLists.txt index cdd4e679ffa2..f2bf90509295 100644 --- a/lld/lib/Core/CMakeLists.txt +++ b/lld/lib/Core/CMakeLists.txt @@ -12,7 +12,6 @@ add_lld_library(lldCore Resolver.cpp SymbolTable.cpp TargetOptionsCommandFlags.cpp - TaskGroup.cpp Writer.cpp ADDITIONAL_HEADER_DIRS diff --git a/lld/lib/ReaderWriter/MachO/LayoutPass.cpp b/lld/lib/ReaderWriter/MachO/LayoutPass.cpp index 2b5a46cc98fb..7bca07eb16d6 100644 --- a/lld/lib/ReaderWriter/MachO/LayoutPass.cpp +++ b/lld/lib/ReaderWriter/MachO/LayoutPass.cpp @@ -9,12 +9,12 @@ #include "LayoutPass.h" #include "lld/Core/Instrumentation.h" -#include "lld/Core/Parallel.h" #include "lld/Core/PassManager.h" #include "lld/ReaderWriter/MachOLinkingContext.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Parallel.h" #include #include #include @@ -461,7 +461,7 @@ llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { }); std::vector vec = decorate(atomRange); - sort(parallel::par, vec.begin(), vec.end(), + sort(llvm::parallel::par, vec.begin(), vec.end(), [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r) -> bool { return compareAtoms(l, r, _customSorter); }); diff --git a/lld/unittests/CMakeLists.txt b/lld/unittests/CMakeLists.txt index 9cd085398c37..84d35d43f4e8 100644 --- a/lld/unittests/CMakeLists.txt +++ b/lld/unittests/CMakeLists.txt @@ -12,6 +12,5 @@ function(add_lld_unittest test_dirname) target_link_libraries(${test_dirname} ${LLVM_COMMON_LIBS}) endfunction() -add_subdirectory(CoreTests) add_subdirectory(DriverTests) add_subdirectory(MachOTests) diff --git a/lld/unittests/CoreTests/CMakeLists.txt b/lld/unittests/CoreTests/CMakeLists.txt deleted file mode 100644 index 9f68f56a6c03..000000000000 --- a/lld/unittests/CoreTests/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_lld_unittest(CoreTests - ParallelTest.cpp - ) - -target_link_libraries(CoreTests - lldCore ${LLVM_PTHREAD_LIB} - ) diff --git a/lld/include/lld/Core/Parallel.h b/llvm/include/llvm/Support/Parallel.h similarity index 85% rename from lld/include/lld/Core/Parallel.h rename to llvm/include/llvm/Support/Parallel.h index 20b774112ca5..aca972eb490c 100644 --- a/lld/include/lld/Core/Parallel.h +++ b/llvm/include/llvm/Support/Parallel.h @@ -1,29 +1,70 @@ -//===- lld/Core/Parallel.h - Parallel utilities ---------------------------===// +//===- llvm/Support/Parallel.h - Parallel algorithms ----------------------===// // -// The LLVM Linker +// The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef LLD_CORE_PARALLEL_H -#define LLD_CORE_PARALLEL_H +#ifndef LLVM_SUPPORT_PARALLEL_H +#define LLVM_SUPPORT_PARALLEL_H -#include "lld/Core/LLVM.h" -#include "lld/Core/TaskGroup.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/MathExtras.h" #include +#include +#include +#include #if defined(_MSC_VER) && LLVM_ENABLE_THREADS +#pragma warning(push) +#pragma warning(disable : 4530) #include #include +#pragma warning(pop) #endif -namespace lld { +namespace llvm { + +namespace detail { +class Latch { + uint32_t Count; + mutable std::mutex Mutex; + mutable std::condition_variable Cond; + +public: + explicit Latch(uint32_t count = 0) : Count(Count) {} + ~Latch() { sync(); } + + void inc() { + std::unique_lock lock(Mutex); + ++Count; + } + + void dec() { + std::unique_lock lock(Mutex); + if (--Count == 0) + Cond.notify_all(); + } + + void sync() const { + std::unique_lock lock(Mutex); + Cond.wait(lock, [&] { return Count == 0; }); + } +}; + +class TaskGroup { + Latch L; + +public: + void spawn(std::function f); + + void sync() const { L.sync(); } +}; +} namespace parallel { struct sequential_execution_policy {}; @@ -205,6 +246,6 @@ void for_each_n(parallel_execution_policy policy, IndexTy Begin, IndexTy End, #endif } // namespace parallel -} // End namespace lld +} // namespace llvm -#endif // LLD_CORE_PARALLEL_H +#endif // LLVM_SUPPORT_PARALLEL_H diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 63c440037c22..83376284548f 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -81,6 +81,7 @@ add_llvm_library(LLVMSupport MD5.cpp NativeFormatting.cpp Options.cpp + Parallel.cpp PluginLoader.cpp PrettyStackTrace.cpp RandomNumberGenerator.cpp diff --git a/lld/lib/Core/TaskGroup.cpp b/llvm/lib/Support/Parallel.cpp similarity index 90% rename from lld/lib/Core/TaskGroup.cpp rename to llvm/lib/Support/Parallel.cpp index 6cd5d22b7e8e..04fb1c95533c 100644 --- a/lld/lib/Core/TaskGroup.cpp +++ b/llvm/lib/Support/Parallel.cpp @@ -1,25 +1,20 @@ -//===- lld/Core/TaskGroup.cpp - Task Group --------------------------------===// +//===- llvm/Support/Parallel.cpp - Parallel algorithms --------------------===// // -// The LLVM Linker +// The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#include "lld/Core/TaskGroup.h" +#include "llvm/Support/Parallel.h" #include "llvm/Config/llvm-config.h" #include #include #include -#if defined(_MSC_VER) && LLVM_ENABLE_THREADS -#include -#include -#endif - -using namespace lld; +using namespace llvm; namespace { @@ -132,7 +127,7 @@ Executor *Executor::getDefaultExecutor() { #endif } -void TaskGroup::spawn(std::function F) { +void detail::TaskGroup::spawn(std::function F) { L.inc(); Executor::getDefaultExecutor()->add([&, F] { F(); diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt index 1f677100dcef..f8d3c1c9a8c7 100644 --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -36,6 +36,7 @@ add_llvm_unittest(SupportTests MemoryBufferTest.cpp MemoryTest.cpp NativeFormatTests.cpp + ParallelTest.cpp Path.cpp ProcessTest.cpp ProgramTest.cpp diff --git a/lld/unittests/CoreTests/ParallelTest.cpp b/llvm/unittests/Support/ParallelTest.cpp similarity index 82% rename from lld/unittests/CoreTests/ParallelTest.cpp rename to llvm/unittests/Support/ParallelTest.cpp index 601a2b0839b0..f381631ac3a2 100644 --- a/lld/unittests/CoreTests/ParallelTest.cpp +++ b/llvm/unittests/Support/ParallelTest.cpp @@ -1,4 +1,4 @@ -//===- lld/unittest/ParallelTest.cpp --------------------------------------===// +//===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===// // // The LLVM Compiler Infrastructure // @@ -12,13 +12,15 @@ /// //===----------------------------------------------------------------------===// +#include "llvm/Support/Parallel.h" #include "gtest/gtest.h" -#include "lld/Core/Parallel.h" #include #include uint32_t array[1024 * 1024]; +using namespace llvm; + TEST(Parallel, sort) { std::mt19937 randEngine; std::uniform_int_distribution dist; @@ -26,7 +28,7 @@ TEST(Parallel, sort) { for (auto &i : array) i = dist(randEngine); - sort(lld::parallel::par, std::begin(array), std::end(array)); + sort(parallel::par, std::begin(array), std::end(array)); ASSERT_TRUE(std::is_sorted(std::begin(array), std::end(array))); } @@ -36,7 +38,7 @@ TEST(Parallel, parallel_for) { // writing. uint32_t range[2050]; std::fill(range, range + 2050, 1); - for_each_n(lld::parallel::par, 0, 2049, [&range](size_t I) { ++range[I]; }); + for_each_n(parallel::par, 0, 2049, [&range](size_t I) { ++range[I]; }); uint32_t expected[2049]; std::fill(expected, expected + 2049, 2);