[ORC] Replace the LLJIT/LLLazyJIT Create methods with Builder utilities.

LLJITBuilder and LLLazyJITBuilder construct LLJIT and LLLazyJIT instances
respectively. Over time these will allow more configurable options to be
added while remaining easy to use in the default case, which for default
in-process JITing is now:

auto J = ExitOnErr(LLJITBuilder.create());

llvm-svn: 359511
This commit is contained in:
Lang Hames 2019-04-29 22:37:27 +00:00
parent 6f3eeff762
commit eb14dc7585
3 changed files with 295 additions and 154 deletions

View File

@ -20,31 +20,34 @@
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/Support/ThreadPool.h"
namespace llvm {
namespace orc {
class LLJITBuilderState;
class LLLazyJITBuilderState;
/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
///
/// Create instances using LLJITBuilder.
class LLJIT {
template <typename, typename, typename> friend class LLJITBuilderSetters;
public:
static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);
/// Destruct this instance. If a multi-threaded instance, waits for all
/// compile threads to complete.
~LLJIT();
/// Create an LLJIT instance.
/// If NumCompileThreads is not equal to zero, creates a multi-threaded
/// LLJIT with the given number of compile threads.
static Expected<std::unique_ptr<LLJIT>>
Create(JITTargetMachineBuilder JTMB, DataLayout DL,
unsigned NumCompileThreads = 0);
/// Returns the ExecutionSession for this instance.
ExecutionSession &getExecutionSession() { return *ES; }
/// Returns a reference to the DataLayout for this instance.
const DataLayout &getDataLayout() const { return DL; }
/// Returns a reference to the JITDylib representing the JIT'd main program.
JITDylib &getMainJITDylib() { return Main; }
@ -103,17 +106,14 @@ public:
Error runDestructors() { return DtorRunner.run(); }
/// Returns a reference to the ObjLinkingLayer
RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; }
ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
protected:
static std::unique_ptr<ObjectLayer>
createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
/// Create an LLJIT instance with a single compile thread.
LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
DataLayout DL);
/// Create an LLJIT instance with multiple compile threads.
LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
DataLayout DL, unsigned NumCompileThreads);
LLJIT(LLJITBuilderState &S, Error &Err);
std::string mangle(StringRef UnmangledName);
@ -127,8 +127,8 @@ protected:
DataLayout DL;
std::unique_ptr<ThreadPool> CompileThreads;
RTDyldObjectLinkingLayer ObjLinkingLayer;
IRCompileLayer CompileLayer;
std::unique_ptr<ObjectLayer> ObjLinkingLayer;
std::unique_ptr<IRCompileLayer> CompileLayer;
CtorDtorRunner CtorRunner, DtorRunner;
};
@ -136,25 +136,20 @@ protected:
/// An extended version of LLJIT that supports lazy function-at-a-time
/// compilation of LLVM IR.
class LLLazyJIT : public LLJIT {
public:
template <typename, typename, typename> friend class LLJITBuilderSetters;
/// Create an LLLazyJIT instance.
/// If NumCompileThreads is not equal to zero, creates a multi-threaded
/// LLLazyJIT with the given number of compile threads.
static Expected<std::unique_ptr<LLLazyJIT>>
Create(JITTargetMachineBuilder JTMB, DataLayout DL,
JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0);
public:
/// Set an IR transform (e.g. pass manager pipeline) to run on each function
/// when it is compiled.
void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
TransformLayer.setTransform(std::move(Transform));
TransformLayer->setTransform(std::move(Transform));
}
/// Sets the partition function.
void
setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
CODLayer.setPartitionFunction(std::move(Partition));
CODLayer->setPartitionFunction(std::move(Partition));
}
/// Add a module to be lazily compiled to JITDylib JD.
@ -168,24 +163,144 @@ public:
private:
// Create a single-threaded LLLazyJIT instance.
LLLazyJIT(std::unique_ptr<ExecutionSession> ES,
std::unique_ptr<TargetMachine> TM, DataLayout DL,
std::unique_ptr<LazyCallThroughManager> LCTMgr,
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
// Create a multi-threaded LLLazyJIT instance.
LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
DataLayout DL, unsigned NumCompileThreads,
std::unique_ptr<LazyCallThroughManager> LCTMgr,
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
std::unique_ptr<LazyCallThroughManager> LCTMgr;
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
IRTransformLayer TransformLayer;
CompileOnDemandLayer CODLayer;
std::unique_ptr<IRTransformLayer> TransformLayer;
std::unique_ptr<CompileOnDemandLayer> CODLayer;
};
class LLJITBuilderState {
public:
using CreateObjectLinkingLayerFunction =
std::function<std::unique_ptr<ObjectLayer>(ExecutionSession &)>;
std::unique_ptr<ExecutionSession> ES;
Optional<JITTargetMachineBuilder> JTMB;
CreateObjectLinkingLayerFunction CreateObjectLinkingLayer;
unsigned NumCompileThreads = 0;
/// Called prior to JIT class construcion to fix up defaults.
Error prepareForConstruction();
};
template <typename JITType, typename SetterImpl, typename State>
class LLJITBuilderSetters {
public:
/// Set the JITTargetMachineBuilder for this instance.
///
/// If this method is not called, JITTargetMachineBuilder::detectHost will be
/// used to construct a default target machine builder for the host platform.
SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
impl().JTMB = std::move(JTMB);
return impl();
}
/// Return a reference to the JITTargetMachineBuilder.
///
Optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
return impl().JTMB;
}
/// Set an ObjectLinkingLayer creation function.
///
/// If this method is not called, a default creation function will be used
/// that will construct an RTDyldObjectLinkingLayer.
SetterImpl &setCreateObjectLinkingLayer(
LLJITBuilderState::CreateObjectLinkingLayerFunction
CreateObjectLinkingLayer) {
impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
return impl();
}
/// Set the number of compile threads to use.
///
/// If set to zero, compilation will be performed on the execution thread when
/// JITing in-process. If set to any other number N, a thread pool of N
/// threads will be created for compilation.
///
/// If this method is not called, behavior will be as if it were called with
/// a zero argument.
SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
impl().NumCompileThreads = NumCompileThreads;
return impl();
}
/// Create an instance of the JIT.
Expected<std::unique_ptr<JITType>> create() {
if (auto Err = impl().prepareForConstruction())
return std::move(Err);
Error Err = Error::success();
std::unique_ptr<JITType> J(new JITType(impl(), Err));
if (Err)
return std::move(Err);
return std::move(J);
}
protected:
SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
};
/// Constructs LLJIT instances.
class LLJITBuilder
: public LLJITBuilderState,
public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
class LLLazyJITBuilderState : public LLJITBuilderState {
friend class LLLazyJIT;
public:
using IndirectStubsManagerBuilderFunction =
std::function<std::unique_ptr<IndirectStubsManager>()>;
Triple TT;
JITTargetAddress LazyCompileFailureAddr = 0;
std::unique_ptr<LazyCallThroughManager> LCTMgr;
IndirectStubsManagerBuilderFunction ISMBuilder;
Error prepareForConstruction();
};
template <typename JITType, typename SetterImpl, typename State>
class LLLazyJITBuilderSetters
: public LLJITBuilderSetters<JITType, SetterImpl, State> {
public:
/// Set the address in the target address to call if a lazy compile fails.
///
/// If this method is not called then the value will default to 0.
SetterImpl &setLazyCompileFailureAddr(JITTargetAddress Addr) {
this->impl().LazyCompileFailureAddr = Addr;
return this->impl();
}
/// Set the lazy-callthrough manager.
///
/// If this method is not called then a default, in-process lazy callthrough
/// manager for the host platform will be used.
SetterImpl &
setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
this->impl().LCTMgr = std::move(LCTMgr);
return this->impl();
}
/// Set the IndirectStubsManager builder function.
///
/// If this method is not called then a default, in-process
/// IndirectStubsManager builder for the host platform will be used.
SetterImpl &setIndirectStubsManagerBuilder(
LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
this->impl().ISMBuilder = std::move(ISMBuilder);
return this->impl();
}
};
/// Constructs LLLazyJIT instances.
class LLLazyJITBuilder
: public LLLazyJITBuilderState,
public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
LLLazyJITBuilderState> {};
} // End namespace orc
} // End namespace llvm

View File

@ -8,6 +8,7 @@
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/Mangler.h"
@ -29,29 +30,23 @@ namespace {
namespace llvm {
namespace orc {
Error LLJITBuilderState::prepareForConstruction() {
if (!JTMB) {
if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
JTMB = std::move(*JTMBOrErr);
else
return JTMBOrErr.takeError();
}
return Error::success();
}
LLJIT::~LLJIT() {
if (CompileThreads)
CompileThreads->wait();
}
Expected<std::unique_ptr<LLJIT>>
LLJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
unsigned NumCompileThreads) {
if (NumCompileThreads == 0) {
// If NumCompileThreads == 0 then create a single-threaded LLJIT instance.
auto TM = JTMB.createTargetMachine();
if (!TM)
return TM.takeError();
return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
std::move(*TM), std::move(DL)));
}
return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
std::move(JTMB), std::move(DL),
NumCompileThreads));
}
Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
auto InternedName = ES->intern(Name);
SymbolMap Symbols({{InternedName, Sym}});
@ -64,13 +59,13 @@ Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
if (auto Err = applyDataLayout(*TSM.getModule()))
return Err;
return CompileLayer.add(JD, std::move(TSM), ES->allocateVModule());
return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
}
Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
assert(Obj && "Can not add null object");
return ObjLinkingLayer.add(JD, std::move(Obj), ES->allocateVModule());
return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
}
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
@ -78,42 +73,70 @@ Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
}
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
std::unique_ptr<TargetMachine> TM, DataLayout DL)
: ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
ObjLinkingLayer(
*this->ES,
[]() { return llvm::make_unique<SectionMemoryManager>(); }),
CompileLayer(*this->ES, ObjLinkingLayer,
TMOwningSimpleCompiler(std::move(TM))),
CtorRunner(Main), DtorRunner(Main) {}
std::unique_ptr<ObjectLayer>
LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
DataLayout DL, unsigned NumCompileThreads)
: ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
ObjLinkingLayer(
*this->ES,
[]() { return llvm::make_unique<SectionMemoryManager>(); }),
CompileLayer(*this->ES, ObjLinkingLayer,
ConcurrentIRCompiler(std::move(JTMB))),
CtorRunner(Main), DtorRunner(Main) {
assert(NumCompileThreads != 0 &&
"Multithreaded LLJIT instance can not be created with 0 threads");
// If the config state provided an ObjectLinkingLayer factory then use it.
if (S.CreateObjectLinkingLayer)
return S.CreateObjectLinkingLayer(ES);
// Move modules to new contexts when they're emitted so that we can compile
// them in parallel.
CompileLayer.setCloneToNewContextOnEmit(true);
// Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
// a new SectionMemoryManager for each object.
auto GetMemMgr = []() { return llvm::make_unique<SectionMemoryManager>(); };
return llvm::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
}
// Create a thread pool to compile on and set the execution session
// dispatcher to use the thread pool.
CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);
this->ES->setDispatchMaterialization(
[this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
// FIXME: Switch to move capture once we have c++14.
auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
CompileThreads->async(std::move(Work));
});
LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
: ES(S.ES ? std::move(S.ES) : llvm::make_unique<ExecutionSession>()),
Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main),
DtorRunner(Main) {
ErrorAsOutParameter _(&Err);
ObjLinkingLayer = createObjectLinkingLayer(S, *ES);
if (S.NumCompileThreads > 0) {
// Configure multi-threaded.
if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
DL = std::move(*DLOrErr);
else {
Err = DLOrErr.takeError();
return;
}
{
auto TmpCompileLayer = llvm::make_unique<IRCompileLayer>(
*ES, *ObjLinkingLayer, ConcurrentIRCompiler(std::move(*S.JTMB)));
TmpCompileLayer->setCloneToNewContextOnEmit(true);
CompileLayer = std::move(TmpCompileLayer);
}
CompileThreads = llvm::make_unique<ThreadPool>(S.NumCompileThreads);
ES->setDispatchMaterialization(
[this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
// FIXME: Switch to move capture once we have c++14.
auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
CompileThreads->async(std::move(Work));
});
} else {
// Configure single-threaded.
auto TM = S.JTMB->createTargetMachine();
if (!TM) {
Err = TM.takeError();
return;
}
DL = (*TM)->createDataLayout();
CompileLayer = llvm::make_unique<IRCompileLayer>(
*ES, *ObjLinkingLayer, TMOwningSimpleCompiler(std::move(*TM)));
}
}
std::string LLJIT::mangle(StringRef UnmangledName) {
@ -142,35 +165,11 @@ void LLJIT::recordCtorDtors(Module &M) {
DtorRunner.add(getDestructors(M));
}
Expected<std::unique_ptr<LLLazyJIT>>
LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
JITTargetAddress ErrorAddr, unsigned NumCompileThreads) {
auto ES = llvm::make_unique<ExecutionSession>();
const Triple &TT = JTMB.getTargetTriple();
auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, ErrorAddr);
if (!LCTMgr)
return LCTMgr.takeError();
auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
if (!ISMBuilder)
return make_error<StringError>(
std::string("No indirect stubs manager builder for ") + TT.str(),
inconvertibleErrorCode());
if (NumCompileThreads == 0) {
auto TM = JTMB.createTargetMachine();
if (!TM)
return TM.takeError();
return std::unique_ptr<LLLazyJIT>(
new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),
std::move(*LCTMgr), std::move(ISMBuilder)));
}
return std::unique_ptr<LLLazyJIT>(new LLLazyJIT(
std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads,
std::move(*LCTMgr), std::move(ISMBuilder)));
Error LLLazyJITBuilderState::prepareForConstruction() {
if (auto Err = LLJITBuilderState::prepareForConstruction())
return Err;
TT = JTMB->getTargetTriple();
return Error::success();
}
Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
@ -181,28 +180,55 @@ Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
recordCtorDtors(*TSM.getModule());
return CODLayer.add(JD, std::move(TSM), ES->allocateVModule());
return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
}
LLLazyJIT::LLLazyJIT(
std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
: LLJIT(std::move(ES), std::move(TM), std::move(DL)),
LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
std::move(ISMBuilder)) {}
LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
LLLazyJIT::LLLazyJIT(
std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
DataLayout DL, unsigned NumCompileThreads,
std::unique_ptr<LazyCallThroughManager> LCTMgr,
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
: LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),
LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
std::move(ISMBuilder)) {
CODLayer.setCloneToNewContextOnEmit(true);
// If LLJIT construction failed then bail out.
if (Err)
return;
ErrorAsOutParameter _(&Err);
/// Take/Create the lazy-compile callthrough manager.
if (S.LCTMgr)
LCTMgr = std::move(S.LCTMgr);
else {
if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
S.TT, *ES, S.LazyCompileFailureAddr))
LCTMgr = std::move(*LCTMgrOrErr);
else {
Err = LCTMgrOrErr.takeError();
return;
}
}
// Take/Create the indirect stubs manager builder.
auto ISMBuilder = std::move(S.ISMBuilder);
// If none was provided, try to build one.
if (!ISMBuilder)
ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);
// No luck. Bail out.
if (!ISMBuilder) {
Err = make_error<StringError>("Could not construct "
"IndirectStubsManagerBuilder for target " +
S.TT.str(),
inconvertibleErrorCode());
return;
}
// Create the transform layer.
TransformLayer = llvm::make_unique<IRTransformLayer>(*ES, *CompileLayer);
// Create the COD layer.
CODLayer = llvm::make_unique<CompileOnDemandLayer>(
*ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
if (S.NumCompileThreads > 0)
CODLayer->setCloneToNewContextOnEmit(true);
}
} // End namespace orc.

View File

@ -763,14 +763,17 @@ int runOrcLazyJIT(const char *ProgName) {
reportError(Err, ProgName);
const auto &TT = MainModule.getModule()->getTargetTriple();
orc::JITTargetMachineBuilder JTMB =
orc::LLLazyJITBuilder Builder;
Builder.setJITTargetMachineBuilder(
TT.empty() ? ExitOnErr(orc::JITTargetMachineBuilder::detectHost())
: orc::JITTargetMachineBuilder(Triple(TT));
: orc::JITTargetMachineBuilder(Triple(TT)));
if (!MArch.empty())
JTMB.getTargetTriple().setArchName(MArch);
Builder.getJITTargetMachineBuilder()->getTargetTriple().setArchName(MArch);
JTMB.setCPU(getCPUStr())
Builder.getJITTargetMachineBuilder()
->setCPU(getCPUStr())
.addFeatures(getFeatureList())
.setRelocationModel(RelocModel.getNumOccurrences()
? Optional<Reloc::Model>(RelocModel)
@ -779,12 +782,11 @@ int runOrcLazyJIT(const char *ProgName) {
? Optional<CodeModel::Model>(CMModel)
: None);
DataLayout DL = ExitOnErr(JTMB.getDefaultDataLayoutForTarget());
Builder.setLazyCompileFailureAddr(
pointerToJITTargetAddress(exitOnLazyCallThroughFailure));
Builder.setNumCompileThreads(LazyJITCompileThreads);
auto J = ExitOnErr(orc::LLLazyJIT::Create(
std::move(JTMB), DL,
pointerToJITTargetAddress(exitOnLazyCallThroughFailure),
LazyJITCompileThreads));
auto J = ExitOnErr(Builder.create());
if (PerModuleLazy)
J->setPartitionFunction(orc::CompileOnDemandLayer::compileWholeModule);
@ -801,9 +803,9 @@ int runOrcLazyJIT(const char *ProgName) {
});
J->getMainJITDylib().setGenerator(
ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
DL.getGlobalPrefix())));
J->getDataLayout().getGlobalPrefix())));
orc::MangleAndInterner Mangle(J->getExecutionSession(), DL);
orc::MangleAndInterner Mangle(J->getExecutionSession(), J->getDataLayout());
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
ExitOnErr(CXXRuntimeOverrides.enable(J->getMainJITDylib(), Mangle));
@ -863,8 +865,6 @@ int runOrcLazyJIT(const char *ProgName) {
AltEntryThreads.push_back(std::thread([EntryPoint]() { EntryPoint(); }));
}
J->getExecutionSession().dump(llvm::dbgs());
// Run main.
auto MainSym = ExitOnErr(J->lookup("main"));
typedef int (*MainFnPtr)(int, const char *[]);