Skip to content

Commit 6846af7

Browse files
vtjnashKristofferC
authored andcommitted
Fix LLVM TaskDispatcher implementation issues (#58950)
Fixes #58229 (LLVM JITLink stack overflow issue) I tried submitting this promise/future implementation upstream (llvm/llvm-project@main...vtjnash:llvm-project:jn/cowait-jit) so that I would not need to duplicate nearly as much code here to fix this bug, but upstream is currently opposed to fixing this bug and instead insists it is preferable for each downstream project to implement this fix themselves adding extra maintenance burden for us for now. Sigh. (cherry picked from commit 00351da)
1 parent 7190fac commit 6846af7

File tree

3 files changed

+474
-16
lines changed

3 files changed

+474
-16
lines changed

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ $(BUILDDIR)/gc-alloc-profiler.o $(BUILDDIR)/gc-alloc-profiler.dbg.obj: $(SRCDIR)
349349
$(BUILDDIR)/gc-page-profiler.o $(BUILDDIR)/gc-page-profiler.dbg.obj: $(SRCDIR)/gc-page-profiler.h
350350
$(BUILDDIR)/init.o $(BUILDDIR)/init.dbg.obj: $(SRCDIR)/builtin_proto.h
351351
$(BUILDDIR)/interpreter.o $(BUILDDIR)/interpreter.dbg.obj: $(SRCDIR)/builtin_proto.h
352-
$(BUILDDIR)/jitlayers.o $(BUILDDIR)/jitlayers.dbg.obj: $(SRCDIR)/jitlayers.h $(SRCDIR)/llvm-codegen-shared.h
352+
$(BUILDDIR)/jitlayers.o $(BUILDDIR)/jitlayers.dbg.obj: $(SRCDIR)/jitlayers.h $(SRCDIR)/llvm-codegen-shared.h $(SRCDIR)/llvm-julia-task-dispatcher.h
353353
$(BUILDDIR)/jltypes.o $(BUILDDIR)/jltypes.dbg.obj: $(SRCDIR)/builtin_proto.h
354354
$(build_shlibdir)/libllvmcalltest.$(SHLIB_EXT): $(SRCDIR)/llvm-codegen-shared.h $(BUILDDIR)/julia_version.h
355355
$(BUILDDIR)/llvm-alloc-helpers.o $(BUILDDIR)/llvm-alloc-helpers.dbg.obj: $(SRCDIR)/llvm-codegen-shared.h $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-alloc-helpers.h

src/jitlayers.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <string>
77

88
#include "llvm/IR/Mangler.h"
9+
#include <llvm/ADT/BitmaskEnum.h>
910
#include <llvm/ADT/Statistic.h>
1011
#include <llvm/ADT/StringMap.h>
1112
#include <llvm/Analysis/TargetLibraryInfo.h>
@@ -46,6 +47,7 @@ using namespace llvm;
4647
#include "jitlayers.h"
4748
#include "julia_assert.h"
4849
#include "processor.h"
50+
#include "llvm-julia-task-dispatcher.h"
4951

5052
#if JL_LLVM_VERSION >= 180000
5153
# include <llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h>
@@ -666,17 +668,8 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst)
666668
if (!decls.specFunctionObject.empty())
667669
NewDefs.push_back(decls.specFunctionObject);
668670
}
669-
// Split batches to avoid stack overflow in the JIT linker.
670-
// FIXME: Patch ORCJITs InPlaceTaskDispatcher to not recurse on task dispatches but
671-
// push the tasks to a queue to be drained later. This avoids the stackoverflow caused by recursion
672-
// in the linker when compiling a large number of functions at once.
673-
SmallVector<uint64_t, 0> Addrs;
674-
for (size_t i = 0; i < NewDefs.size(); i += 1000) {
675-
auto end = std::min(i + 1000, NewDefs.size());
676-
SmallVector<StringRef> batch(NewDefs.begin() + i, NewDefs.begin() + end);
677-
auto AddrsBatch = jl_ExecutionEngine->findSymbols(batch);
678-
Addrs.append(AddrsBatch);
679-
}
671+
auto Addrs = jl_ExecutionEngine->findSymbols(NewDefs);
672+
680673
size_t nextaddr = 0;
681674
for (auto &this_code : linkready) {
682675
auto it = invokenames.find(this_code);
@@ -1841,7 +1834,7 @@ llvm::DataLayout jl_create_datalayout(TargetMachine &TM) {
18411834
JuliaOJIT::JuliaOJIT()
18421835
: TM(createTargetMachine()),
18431836
DL(jl_create_datalayout(*TM)),
1844-
ES(cantFail(orc::SelfExecutorProcessControl::Create())),
1837+
ES(cantFail(orc::SelfExecutorProcessControl::Create(nullptr, std::make_unique<::JuliaTaskDispatcher>()))),
18451838
GlobalJD(ES.createBareJITDylib("JuliaGlobals")),
18461839
JD(ES.createBareJITDylib("JuliaOJIT")),
18471840
ExternalJD(ES.createBareJITDylib("JuliaExternal")),
@@ -2098,7 +2091,7 @@ SmallVector<uint64_t> JuliaOJIT::findSymbols(ArrayRef<StringRef> Names)
20982091
Unmangled[NonOwningSymbolStringPtr(Mangled)] = Unmangled.size();
20992092
Exports.add(std::move(Mangled));
21002093
}
2101-
SymbolMap Syms = cantFail(ES.lookup(orc::makeJITDylibSearchOrder(ArrayRef(&JD)), std::move(Exports)));
2094+
SymbolMap Syms = cantFail(::safelookup(ES, orc::makeJITDylibSearchOrder(ArrayRef(&JD)), std::move(Exports)));
21022095
SmallVector<uint64_t> Addrs(Names.size());
21032096
for (auto it : Syms) {
21042097
Addrs[Unmangled.at(orc::NonOwningSymbolStringPtr(it.first))] = it.second.getAddress().getValue();
@@ -2110,7 +2103,7 @@ Expected<ExecutorSymbolDef> JuliaOJIT::findSymbol(StringRef Name, bool ExportedS
21102103
{
21112104
orc::JITDylib* SearchOrders[3] = {&JD, &GlobalJD, &ExternalJD};
21122105
ArrayRef<orc::JITDylib*> SearchOrder = ArrayRef<orc::JITDylib*>(&SearchOrders[0], ExportedSymbolsOnly ? 3 : 1);
2113-
auto Sym = ES.lookup(SearchOrder, Name);
2106+
auto Sym = ::safelookup(ES, SearchOrder, Name);
21142107
return Sym;
21152108
}
21162109

@@ -2123,7 +2116,7 @@ Expected<ExecutorSymbolDef> JuliaOJIT::findExternalJDSymbol(StringRef Name, bool
21232116
{
21242117
orc::JITDylib* SearchOrders[3] = {&ExternalJD, &GlobalJD, &JD};
21252118
ArrayRef<orc::JITDylib*> SearchOrder = ArrayRef<orc::JITDylib*>(&SearchOrders[0], ExternalJDOnly ? 1 : 3);
2126-
auto Sym = ES.lookup(SearchOrder, getMangledName(Name));
2119+
auto Sym = ::safelookup(ES, SearchOrder, getMangledName(Name));
21272120
return Sym;
21282121
}
21292122

0 commit comments

Comments
 (0)