forked from OSchip/llvm-project
[Support] Move Parallel algorithms from LLD to LLVM.
Differential Revision: https://reviews.llvm.org/D33024 llvm-svn: 302748
This commit is contained in:
parent
ae0317e4a9
commit
3a57fbd6db
|
@ -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 <algorithm>
|
||||
#include <atomic>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <algorithm>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
#include "Config.h"
|
||||
|
||||
#include "lld/Core/Parallel.h"
|
||||
#include "llvm/Support/Parallel.h"
|
||||
#include <functional>
|
||||
|
||||
namespace lld {
|
||||
|
@ -70,17 +70,17 @@ namespace elf {
|
|||
template <class IterTy, class FuncTy>
|
||||
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<void(size_t)> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
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<std::mutex> lock(Mutex);
|
||||
++Count;
|
||||
}
|
||||
|
||||
void dec() {
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
if (--Count == 0)
|
||||
Cond.notify_all();
|
||||
}
|
||||
|
||||
void sync() const {
|
||||
std::unique_lock<std::mutex> 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<void()> F);
|
||||
|
||||
void sync() const { L.sync(); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -12,7 +12,6 @@ add_lld_library(lldCore
|
|||
Resolver.cpp
|
||||
SymbolTable.cpp
|
||||
TargetOptionsCommandFlags.cpp
|
||||
TaskGroup.cpp
|
||||
Writer.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
|
|
|
@ -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 <algorithm>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
@ -461,7 +461,7 @@ llvm::Error LayoutPass::perform(SimpleFile &mergedFile) {
|
|||
});
|
||||
|
||||
std::vector<LayoutPass::SortKey> 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);
|
||||
});
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
add_lld_unittest(CoreTests
|
||||
ParallelTest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(CoreTests
|
||||
lldCore ${LLVM_PTHREAD_LIB}
|
||||
)
|
|
@ -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 <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
#if defined(_MSC_VER) && LLVM_ENABLE_THREADS
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4530)
|
||||
#include <concrt.h>
|
||||
#include <ppl.h>
|
||||
#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<std::mutex> lock(Mutex);
|
||||
++Count;
|
||||
}
|
||||
|
||||
void dec() {
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
if (--Count == 0)
|
||||
Cond.notify_all();
|
||||
}
|
||||
|
||||
void sync() const {
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
Cond.wait(lock, [&] { return Count == 0; });
|
||||
}
|
||||
};
|
||||
|
||||
class TaskGroup {
|
||||
Latch L;
|
||||
|
||||
public:
|
||||
void spawn(std::function<void()> 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
|
|
@ -81,6 +81,7 @@ add_llvm_library(LLVMSupport
|
|||
MD5.cpp
|
||||
NativeFormatting.cpp
|
||||
Options.cpp
|
||||
Parallel.cpp
|
||||
PluginLoader.cpp
|
||||
PrettyStackTrace.cpp
|
||||
RandomNumberGenerator.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 <atomic>
|
||||
#include <stack>
|
||||
#include <thread>
|
||||
|
||||
#if defined(_MSC_VER) && LLVM_ENABLE_THREADS
|
||||
#include <concrt.h>
|
||||
#include <ppl.h>
|
||||
#endif
|
||||
|
||||
using namespace lld;
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -132,7 +127,7 @@ Executor *Executor::getDefaultExecutor() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void TaskGroup::spawn(std::function<void()> F) {
|
||||
void detail::TaskGroup::spawn(std::function<void()> F) {
|
||||
L.inc();
|
||||
Executor::getDefaultExecutor()->add([&, F] {
|
||||
F();
|
|
@ -36,6 +36,7 @@ add_llvm_unittest(SupportTests
|
|||
MemoryBufferTest.cpp
|
||||
MemoryTest.cpp
|
||||
NativeFormatTests.cpp
|
||||
ParallelTest.cpp
|
||||
Path.cpp
|
||||
ProcessTest.cpp
|
||||
ProgramTest.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 <array>
|
||||
#include <random>
|
||||
|
||||
uint32_t array[1024 * 1024];
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
TEST(Parallel, sort) {
|
||||
std::mt19937 randEngine;
|
||||
std::uniform_int_distribution<uint32_t> 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);
|
Loading…
Reference in New Issue