Skip to content

Commit e7efd37

Browse files
committed
Revert "Re-apply [ORC] Unify task dispatch across ExecutionSession and..."
This reverts commit 1effa19 while I investigate the test failure at https://lab.llvm.org/buildbot/#/builders/285/builds/888.
1 parent aa89c1b commit e7efd37

File tree

11 files changed

+61
-158
lines changed

11 files changed

+61
-158
lines changed

llvm/include/llvm/ExecutionEngine/Orc/Core.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,9 @@ class ExecutionSession {
14431443
/// Send a result to the remote.
14441444
using SendResultFunction = unique_function<void(shared::WrapperFunctionResult)>;
14451445

1446+
/// For dispatching ORC tasks (typically materialization tasks).
1447+
using DispatchTaskFunction = unique_function<void(std::unique_ptr<Task> T)>;
1448+
14461449
/// An asynchronous wrapper-function callable from the executor via
14471450
/// jit-dispatch.
14481451
using JITDispatchHandlerFunction = unique_function<void(
@@ -1565,6 +1568,12 @@ class ExecutionSession {
15651568
/// Unhandled errors can be sent here to log them.
15661569
void reportError(Error Err) { ReportError(std::move(Err)); }
15671570

1571+
/// Set the task dispatch function.
1572+
ExecutionSession &setDispatchTask(DispatchTaskFunction DispatchTask) {
1573+
this->DispatchTask = std::move(DispatchTask);
1574+
return *this;
1575+
}
1576+
15681577
/// Search the given JITDylibs to find the flags associated with each of the
15691578
/// given symbols.
15701579
void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
@@ -1639,7 +1648,7 @@ class ExecutionSession {
16391648
void dispatchTask(std::unique_ptr<Task> T) {
16401649
assert(T && "T must be non-null");
16411650
DEBUG_WITH_TYPE("orc", dumpDispatchInfo(*T));
1642-
EPC->getDispatcher().dispatch(std::move(T));
1651+
DispatchTask(std::move(T));
16431652
}
16441653

16451654
/// Run a wrapper function in the executor.
@@ -1753,6 +1762,8 @@ class ExecutionSession {
17531762
logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
17541763
}
17551764

1765+
static void runOnCurrentThread(std::unique_ptr<Task> T) { T->run(); }
1766+
17561767
void dispatchOutstandingMUs();
17571768

17581769
static std::unique_ptr<MaterializationResponsibility>
@@ -1858,6 +1869,7 @@ class ExecutionSession {
18581869
std::unique_ptr<ExecutorProcessControl> EPC;
18591870
std::unique_ptr<Platform> P;
18601871
ErrorReporter ReportError = logErrorsToStdErr;
1872+
DispatchTaskFunction DispatchTask = runOnCurrentThread;
18611873

18621874
std::vector<ResourceManager *> ResourceManagers;
18631875

llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ class LLJIT {
254254

255255
DataLayout DL;
256256
Triple TT;
257+
std::unique_ptr<DefaultThreadPool> CompileThreads;
257258

258259
std::unique_ptr<ObjectLayer> ObjLinkingLayer;
259260
std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
@@ -324,7 +325,6 @@ class LLJITBuilderState {
324325
PlatformSetupFunction SetUpPlatform;
325326
NotifyCreatedFunction NotifyCreated;
326327
unsigned NumCompileThreads = 0;
327-
std::optional<bool> SupportConcurrentCompilation;
328328

329329
/// Called prior to JIT class construcion to fix up defaults.
330330
Error prepareForConstruction();
@@ -333,7 +333,7 @@ class LLJITBuilderState {
333333
template <typename JITType, typename SetterImpl, typename State>
334334
class LLJITBuilderSetters {
335335
public:
336-
/// Set an ExecutorProcessControl for this instance.
336+
/// Set a ExecutorProcessControl for this instance.
337337
/// This should not be called if ExecutionSession has already been set.
338338
SetterImpl &
339339
setExecutorProcessControl(std::unique_ptr<ExecutorProcessControl> EPC) {
@@ -462,26 +462,19 @@ class LLJITBuilderSetters {
462462
///
463463
/// If this method is not called, behavior will be as if it were called with
464464
/// a zero argument.
465-
///
466-
/// This setting should not be used if a custom ExecutionSession or
467-
/// ExecutorProcessControl object is set: in those cases a custom
468-
/// TaskDispatcher should be used instead.
469465
SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
470466
impl().NumCompileThreads = NumCompileThreads;
471467
return impl();
472468
}
473469

474-
/// If set, this forces LLJIT concurrent compilation support to be either on
475-
/// or off. This controls the selection of compile function (concurrent vs
476-
/// single threaded) and whether or not sub-modules are cloned to new
477-
/// contexts for lazy emission.
470+
/// Set an ExecutorProcessControl object.
478471
///
479-
/// If not explicitly set then concurrency support will be turned on if
480-
/// NumCompileThreads is set to a non-zero value, or if a custom
481-
/// ExecutionSession or ExecutorProcessControl instance is provided.
482-
SetterImpl &setSupportConcurrentCompilation(
483-
std::optional<bool> SupportConcurrentCompilation) {
484-
impl().SupportConcurrentCompilation = SupportConcurrentCompilation;
472+
/// If the platform uses ObjectLinkingLayer by default and no
473+
/// ObjectLinkingLayerCreator has been set then the ExecutorProcessControl
474+
/// object will be used to supply the memory manager for the
475+
/// ObjectLinkingLayer.
476+
SetterImpl &setExecutorProcessControl(ExecutorProcessControl &EPC) {
477+
impl().EPC = &EPC;
485478
return impl();
486479
}
487480

llvm/include/llvm/ExecutionEngine/Orc/TaskDispatch.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
#if LLVM_ENABLE_THREADS
2525
#include <condition_variable>
26-
#include <deque>
2726
#include <mutex>
2827
#include <thread>
2928
#endif
@@ -115,20 +114,13 @@ class InPlaceTaskDispatcher : public TaskDispatcher {
115114

116115
class DynamicThreadPoolTaskDispatcher : public TaskDispatcher {
117116
public:
118-
DynamicThreadPoolTaskDispatcher(
119-
std::optional<size_t> MaxMaterializationThreads)
120-
: MaxMaterializationThreads(MaxMaterializationThreads) {}
121117
void dispatch(std::unique_ptr<Task> T) override;
122118
void shutdown() override;
123119
private:
124120
std::mutex DispatchMutex;
125121
bool Running = true;
126122
size_t Outstanding = 0;
127123
std::condition_variable OutstandingCV;
128-
129-
std::optional<size_t> MaxMaterializationThreads;
130-
size_t NumMaterializationThreads = 0;
131-
std::deque<std::unique_ptr<Task>> MaterializationTaskQueue;
132124
};
133125

134126
#endif // LLVM_ENABLE_THREADS

llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ SelfExecutorProcessControl::Create(
6363

6464
if (!D) {
6565
#if LLVM_ENABLE_THREADS
66-
D = std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt);
66+
D = std::make_unique<DynamicThreadPoolTaskDispatcher>();
6767
#else
6868
D = std::make_unique<InPlaceTaskDispatcher>();
6969
#endif

llvm/lib/ExecutionEngine/Orc/LLJIT.cpp

Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -667,37 +667,6 @@ Error LLJITBuilderState::prepareForConstruction() {
667667
return JTMBOrErr.takeError();
668668
}
669669

670-
if ((ES || EPC) && NumCompileThreads)
671-
return make_error<StringError>(
672-
"NumCompileThreads cannot be used with a custom ExecutionSession or "
673-
"ExecutorProcessControl",
674-
inconvertibleErrorCode());
675-
676-
#if !LLVM_ENABLE_THREADS
677-
if (NumCompileThreads)
678-
return make_error<StringError>(
679-
"LLJIT num-compile-threads is " + Twine(NumCompileThreads) +
680-
" but LLVM was compiled with LLVM_ENABLE_THREADS=Off",
681-
inconvertibleErrorCode());
682-
#endif // !LLVM_ENABLE_THREADS
683-
684-
bool ConcurrentCompilationSettingDefaulted = !SupportConcurrentCompilation;
685-
if (!SupportConcurrentCompilation) {
686-
#if LLVM_ENABLE_THREADS
687-
SupportConcurrentCompilation = NumCompileThreads || ES || EPC;
688-
#else
689-
SupportConcurrentCompilation = false;
690-
#endif // LLVM_ENABLE_THREADS
691-
} else {
692-
#if !LLVM_ENABLE_THREADS
693-
if (*SupportConcurrentCompilation)
694-
return make_error<StringError>(
695-
"LLJIT concurrent compilation support requested, but LLVM was built "
696-
"with LLVM_ENABLE_THREADS=Off",
697-
inconvertibleErrorCode());
698-
#endif // !LLVM_ENABLE_THREADS
699-
}
700-
701670
LLVM_DEBUG({
702671
dbgs() << " JITTargetMachineBuilder is "
703672
<< JITTargetMachineBuilderPrinter(*JTMB, " ")
@@ -715,13 +684,11 @@ Error LLJITBuilderState::prepareForConstruction() {
715684
<< (CreateCompileFunction ? "Yes" : "No") << "\n"
716685
<< " Custom platform-setup function: "
717686
<< (SetUpPlatform ? "Yes" : "No") << "\n"
718-
<< " Support concurrent compilation: "
719-
<< (*SupportConcurrentCompilation ? "Yes" : "No");
720-
if (ConcurrentCompilationSettingDefaulted)
721-
dbgs() << " (defaulted based on ES / EPC)\n";
687+
<< " Number of compile threads: " << NumCompileThreads;
688+
if (!NumCompileThreads)
689+
dbgs() << " (code will be compiled on the execution thread)\n";
722690
else
723691
dbgs() << "\n";
724-
dbgs() << " Number of compile threads: " << NumCompileThreads << "\n";
725692
});
726693

727694
// Create DL if not specified.
@@ -738,19 +705,7 @@ Error LLJITBuilderState::prepareForConstruction() {
738705
dbgs() << "ExecutorProcessControl not specified, "
739706
"Creating SelfExecutorProcessControl instance\n";
740707
});
741-
742-
std::unique_ptr<TaskDispatcher> D = nullptr;
743-
#if LLVM_ENABLE_THREADS
744-
if (*SupportConcurrentCompilation) {
745-
std::optional<size_t> NumThreads = std ::nullopt;
746-
if (NumCompileThreads)
747-
NumThreads = NumCompileThreads;
748-
D = std::make_unique<DynamicThreadPoolTaskDispatcher>(NumThreads);
749-
} else
750-
D = std::make_unique<InPlaceTaskDispatcher>();
751-
#endif // LLVM_ENABLE_THREADS
752-
if (auto EPCOrErr =
753-
SelfExecutorProcessControl::Create(nullptr, std::move(D), nullptr))
708+
if (auto EPCOrErr = SelfExecutorProcessControl::Create())
754709
EPC = std::move(*EPCOrErr);
755710
else
756711
return EPCOrErr.takeError();
@@ -835,6 +790,8 @@ Error LLJITBuilderState::prepareForConstruction() {
835790
}
836791

837792
LLJIT::~LLJIT() {
793+
if (CompileThreads)
794+
CompileThreads->wait();
838795
if (auto Err = ES->endSession())
839796
ES->reportError(std::move(Err));
840797
}
@@ -959,8 +916,9 @@ LLJIT::createCompileFunction(LLJITBuilderState &S,
959916
if (S.CreateCompileFunction)
960917
return S.CreateCompileFunction(std::move(JTMB));
961918

962-
// If using a custom EPC then use a ConcurrentIRCompiler by default.
963-
if (*S.SupportConcurrentCompilation)
919+
// Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
920+
// depending on the number of threads requested.
921+
if (S.NumCompileThreads > 0)
964922
return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB));
965923

966924
auto TM = JTMB.createTargetMachine();
@@ -1012,8 +970,21 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
1012970
std::make_unique<IRTransformLayer>(*ES, *TransformLayer);
1013971
}
1014972

1015-
if (*S.SupportConcurrentCompilation)
973+
if (S.NumCompileThreads > 0) {
1016974
InitHelperTransformLayer->setCloneToNewContextOnEmit(true);
975+
CompileThreads = std::make_unique<DefaultThreadPool>(
976+
hardware_concurrency(S.NumCompileThreads));
977+
ES->setDispatchTask([this](std::unique_ptr<Task> T) {
978+
// FIXME: We should be able to use move-capture here, but ThreadPool's
979+
// AsyncTaskTys are std::functions rather than unique_functions
980+
// (because MSVC's std::packaged_tasks don't support move-only types).
981+
// Fix this when all the above gets sorted out.
982+
CompileThreads->async([UnownedT = T.release()]() mutable {
983+
std::unique_ptr<Task> T(UnownedT);
984+
T->run();
985+
});
986+
});
987+
}
1017988

1018989
if (S.SetupProcessSymbolsJITDylib) {
1019990
if (auto ProcSymsJD = S.SetupProcessSymbolsJITDylib(*this)) {
@@ -1269,7 +1240,7 @@ LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
12691240
CODLayer = std::make_unique<CompileOnDemandLayer>(
12701241
*ES, *InitHelperTransformLayer, *LCTMgr, std::move(ISMBuilder));
12711242

1272-
if (*S.SupportConcurrentCompilation)
1243+
if (S.NumCompileThreads > 0)
12731244
CODLayer->setCloneToNewContextOnEmit(true);
12741245
}
12751246

llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
10-
#include "llvm/ExecutionEngine/Orc/Core.h"
1110

1211
namespace llvm {
1312
namespace orc {
@@ -25,52 +24,16 @@ void InPlaceTaskDispatcher::shutdown() {}
2524

2625
#if LLVM_ENABLE_THREADS
2726
void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
28-
bool IsMaterializationTask = isa<MaterializationTask>(*T);
29-
3027
{
3128
std::lock_guard<std::mutex> Lock(DispatchMutex);
32-
33-
if (IsMaterializationTask) {
34-
35-
// If this is a materialization task and there are too many running
36-
// already then queue this one up and return early.
37-
if (MaxMaterializationThreads &&
38-
NumMaterializationThreads == *MaxMaterializationThreads) {
39-
MaterializationTaskQueue.push_back(std::move(T));
40-
return;
41-
}
42-
43-
// Otherwise record that we have a materialization task running.
44-
++NumMaterializationThreads;
45-
}
46-
4729
++Outstanding;
4830
}
4931

50-
std::thread([this, T = std::move(T), IsMaterializationTask]() mutable {
51-
while (true) {
52-
53-
// Run the task.
54-
T->run();
55-
56-
std::lock_guard<std::mutex> Lock(DispatchMutex);
57-
if (!MaterializationTaskQueue.empty()) {
58-
// If there are any materialization tasks running then steal that work.
59-
T = std::move(MaterializationTaskQueue.front());
60-
MaterializationTaskQueue.pop_front();
61-
if (!IsMaterializationTask) {
62-
++NumMaterializationThreads;
63-
IsMaterializationTask = true;
64-
}
65-
} else {
66-
// Otherwise decrement work counters.
67-
if (IsMaterializationTask)
68-
--NumMaterializationThreads;
69-
--Outstanding;
70-
OutstandingCV.notify_all();
71-
return;
72-
}
73-
}
32+
std::thread([this, T = std::move(T)]() mutable {
33+
T->run();
34+
std::lock_guard<std::mutex> Lock(DispatchMutex);
35+
--Outstanding;
36+
OutstandingCV.notify_all();
7437
}).detach();
7538
}
7639

llvm/tools/llvm-jitlink/llvm-jitlink.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -807,8 +807,8 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
807807
S.CreateMemoryManager = createSharedMemoryManager;
808808

809809
return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
810-
std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt),
811-
std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
810+
std::make_unique<DynamicThreadPoolTaskDispatcher>(), std::move(S),
811+
FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
812812
#endif
813813
}
814814

@@ -897,7 +897,7 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
897897
S.CreateMemoryManager = createSharedMemoryManager;
898898

899899
return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
900-
std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt),
900+
std::make_unique<DynamicThreadPoolTaskDispatcher>(),
901901
std::move(S), *SockFD, *SockFD);
902902
#endif
903903
}

llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,11 +1005,11 @@ TEST_F(CoreAPIsStandardTest, RedefineBoundWeakSymbol) {
10051005

10061006
TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
10071007
bool ExpectNoMoreMaterialization = false;
1008-
DispatchOverride = [&](std::unique_ptr<Task> T) {
1008+
ES.setDispatchTask([&](std::unique_ptr<Task> T) {
10091009
if (ExpectNoMoreMaterialization && isa<MaterializationTask>(*T))
10101010
ADD_FAILURE() << "Unexpected materialization";
10111011
T->run();
1012-
};
1012+
});
10131013

10141014
auto MU = std::make_unique<SimpleMaterializationUnit>(
10151015
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
@@ -1403,7 +1403,7 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
14031403

14041404
std::mutex WorkThreadsMutex;
14051405
std::vector<std::thread> WorkThreads;
1406-
DispatchOverride = [&](std::unique_ptr<Task> T) {
1406+
ES.setDispatchTask([&](std::unique_ptr<Task> T) {
14071407
std::promise<void> WaitP;
14081408
std::lock_guard<std::mutex> Lock(WorkThreadsMutex);
14091409
WorkThreads.push_back(
@@ -1412,7 +1412,7 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
14121412
T->run();
14131413
}));
14141414
WaitP.set_value();
1415-
};
1415+
});
14161416

14171417
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
14181418

0 commit comments

Comments
 (0)