Revert "[ORC] LLJIT updates: ExecutorNativePlatform, default link order, ..."
This reverts commit 371cb1af61, which broke some
unit tests (see e.g. https://lab.llvm.org/buildbot#builders/139/builds/38754).
This commit is contained in:
@@ -39,14 +39,6 @@ public:
|
||||
|
||||
/// Try to create a COFFPlatform instance, adding the ORC runtime to the
|
||||
/// given JITDylib.
|
||||
static Expected<std::unique_ptr<COFFPlatform>>
|
||||
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD,
|
||||
std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false,
|
||||
const char *VCRuntimePath = nullptr,
|
||||
std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
|
||||
|
||||
static Expected<std::unique_ptr<COFFPlatform>>
|
||||
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
@@ -144,14 +136,10 @@ private:
|
||||
|
||||
static bool supportedTarget(const Triple &TT);
|
||||
|
||||
COFFPlatform(
|
||||
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD,
|
||||
std::unique_ptr<StaticLibraryDefinitionGenerator> OrcRuntimeGenerator,
|
||||
std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
|
||||
std::unique_ptr<object::Archive> OrcRuntimeArchive,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath, Error &Err);
|
||||
COFFPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynamicLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath, Error &Err);
|
||||
|
||||
// Associate COFFPlatform JIT-side runtime support functions with handlers.
|
||||
Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
|
||||
|
||||
@@ -37,7 +37,7 @@ class ExecutorProcessControl;
|
||||
class LLJIT {
|
||||
template <typename, typename, typename> friend class LLJITBuilderSetters;
|
||||
|
||||
friend Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
|
||||
friend void setUpGenericLLVMIRPlatform(LLJIT &J);
|
||||
|
||||
public:
|
||||
/// Initializer support for LLJIT.
|
||||
@@ -70,20 +70,6 @@ public:
|
||||
/// Returns a reference to the JITDylib representing the JIT'd main program.
|
||||
JITDylib &getMainJITDylib() { return *Main; }
|
||||
|
||||
/// Returns the ProcessSymbols JITDylib, which by default reflects non-JIT'd
|
||||
/// symbols in the host process.
|
||||
///
|
||||
/// Note: JIT'd code should not be added to the ProcessSymbols JITDylib. Use
|
||||
/// the main JITDylib or a custom JITDylib instead.
|
||||
JITDylibSP getProcessSymbolsJITDylib();
|
||||
|
||||
/// Returns the Platform JITDylib, which will contain the ORC runtime (if
|
||||
/// given) and any platform symbols.
|
||||
///
|
||||
/// Note: JIT'd code should not be added to the Platform JITDylib. Use the
|
||||
/// main JITDylib or a custom JITDylib instead.
|
||||
JITDylibSP getPlatformJITDylib();
|
||||
|
||||
/// Returns the JITDylib with the given name, or nullptr if no JITDylib with
|
||||
/// that name exists.
|
||||
JITDylib *getJITDylibByName(StringRef Name) {
|
||||
@@ -122,12 +108,9 @@ public:
|
||||
/// input or elsewhere in the environment then the client should check
|
||||
/// (e.g. by calling getJITDylibByName) that the given name is not already in
|
||||
/// use.
|
||||
Expected<JITDylib &> createJITDylib(std::string Name);
|
||||
|
||||
/// Returns the default link order for this LLJIT instance. This link order
|
||||
/// will be appended to the link order of JITDylibs created by LLJIT's
|
||||
/// createJITDylib method.
|
||||
JITDylibSearchOrder defaultLinkOrder() { return DefaultLinks; }
|
||||
Expected<JITDylib &> createJITDylib(std::string Name) {
|
||||
return ES->createJITDylib(std::move(Name));
|
||||
}
|
||||
|
||||
/// Adds an IR module with the given ResourceTracker.
|
||||
Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
|
||||
@@ -246,10 +229,6 @@ protected:
|
||||
std::unique_ptr<PlatformSupport> PS;
|
||||
|
||||
JITDylib *Main = nullptr;
|
||||
JITDylib *ProcessSymbols = nullptr;
|
||||
JITDylib *Platform = nullptr;
|
||||
|
||||
JITDylibSearchOrder DefaultLinks;
|
||||
|
||||
DataLayout DL;
|
||||
Triple TT;
|
||||
@@ -305,17 +284,12 @@ public:
|
||||
std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
|
||||
JITTargetMachineBuilder JTMB)>;
|
||||
|
||||
using ProcessSymbolsJITDylibSetupFunction =
|
||||
std::function<Error(JITDylib &JD)>;
|
||||
|
||||
using PlatformSetupFunction = unique_function<Expected<JITDylibSP>(LLJIT &J)>;
|
||||
using PlatformSetupFunction = std::function<Error(LLJIT &J)>;
|
||||
|
||||
std::unique_ptr<ExecutorProcessControl> EPC;
|
||||
std::unique_ptr<ExecutionSession> ES;
|
||||
std::optional<JITTargetMachineBuilder> JTMB;
|
||||
std::optional<DataLayout> DL;
|
||||
bool LinkProcessSymbolsByDefault = true;
|
||||
ProcessSymbolsJITDylibSetupFunction SetupProcessSymbolsJITDylib;
|
||||
ObjectLinkingLayerCreator CreateObjectLinkingLayer;
|
||||
CompileFunctionCreator CreateCompileFunction;
|
||||
PlatformSetupFunction SetUpPlatform;
|
||||
@@ -368,28 +342,6 @@ public:
|
||||
return impl();
|
||||
}
|
||||
|
||||
/// The LinkProcessSymbolsDyDefault flag determines whether the "Process"
|
||||
/// JITDylib will be added to the default link order at LLJIT construction
|
||||
/// time. If true, the Process JITDylib will be added as the last item in the
|
||||
/// default link order. If false (or if the Process JITDylib is disabled via
|
||||
/// setProcessSymbolsJITDylibSetup) then the Process JITDylib will not appear
|
||||
/// in the default link order.
|
||||
SetterImpl &setLinkProcessSymbolsByDefault(bool LinkProcessSymbolsByDefault) {
|
||||
impl().LinkProcessSymbolsByDefault = LinkProcessSymbolsByDefault;
|
||||
return impl();
|
||||
}
|
||||
|
||||
/// Set a setup function for the process symbols dylib. If not provided,
|
||||
/// but LinkProcessSymbolsJITDylibByDefault is true, then the process-symbols
|
||||
/// JITDylib will be configured with a DynamicLibrarySearchGenerator with a
|
||||
/// default symbol filter.
|
||||
SetterImpl &setProcessSymbolsJITDylibSetup(
|
||||
LLJITBuilderState::ProcessSymbolsJITDylibSetupFunction
|
||||
SetupProcessSymbolsJITDylib) {
|
||||
impl().SetupProcessSymbolsJITDylib = std::move(SetupProcessSymbolsJITDylib);
|
||||
return impl();
|
||||
}
|
||||
|
||||
/// Set an ObjectLinkingLayer creation function.
|
||||
///
|
||||
/// If this method is not called, a default creation function will be used
|
||||
@@ -521,49 +473,20 @@ class LLLazyJITBuilder
|
||||
public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
|
||||
LLLazyJITBuilderState> {};
|
||||
|
||||
/// Configure the LLJIT instance to use orc runtime support. This overload
|
||||
/// assumes that the client has manually configured a Platform object.
|
||||
Error setUpOrcPlatformManually(LLJIT &J);
|
||||
|
||||
/// Configure the LLJIT instance to use the ORC runtime and the detected
|
||||
/// native target for the executor.
|
||||
class ExecutorNativePlatform {
|
||||
public:
|
||||
/// Set up using path to Orc runtime.
|
||||
ExecutorNativePlatform(std::string OrcRuntimePath)
|
||||
: OrcRuntime(std::move(OrcRuntimePath)) {}
|
||||
|
||||
/// Set up using the given memory buffer.
|
||||
ExecutorNativePlatform(std::unique_ptr<MemoryBuffer> OrcRuntimeMB)
|
||||
: OrcRuntime(std::move(OrcRuntimeMB)) {}
|
||||
|
||||
// TODO: add compiler-rt.
|
||||
|
||||
/// Add a path to the VC runtime.
|
||||
ExecutorNativePlatform &addVCRuntime(std::string VCRuntimePath,
|
||||
bool StaticVCRuntime) {
|
||||
VCRuntime = {std::move(VCRuntimePath), StaticVCRuntime};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expected<JITDylibSP> operator()(LLJIT &J);
|
||||
|
||||
private:
|
||||
std::variant<std::string, std::unique_ptr<MemoryBuffer>> OrcRuntime;
|
||||
std::optional<std::pair<std::string, bool>> VCRuntime;
|
||||
};
|
||||
/// Configure the LLJIT instance to use orc runtime support.
|
||||
Error setUpOrcPlatform(LLJIT& J);
|
||||
|
||||
/// Configure the LLJIT instance to scrape modules for llvm.global_ctors and
|
||||
/// llvm.global_dtors variables and (if present) build initialization and
|
||||
/// deinitialization functions. Platform specific initialization configurations
|
||||
/// should be preferred where available.
|
||||
Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
|
||||
void setUpGenericLLVMIRPlatform(LLJIT &J);
|
||||
|
||||
/// Configure the LLJIT instance to disable platform support explicitly. This is
|
||||
/// useful in two cases: for platforms that don't have such requirements and for
|
||||
/// platforms, that we have no explicit support yet and that don't work well
|
||||
/// with the generic IR platform.
|
||||
Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J);
|
||||
Error setUpInactivePlatform(LLJIT &J);
|
||||
|
||||
} // End namespace orc
|
||||
} // End namespace llvm
|
||||
|
||||
@@ -159,11 +159,12 @@ private:
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
Expected<std::unique_ptr<COFFPlatform>> COFFPlatform::Create(
|
||||
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath, std::optional<SymbolAliasMap> RuntimeAliases) {
|
||||
Expected<std::unique_ptr<COFFPlatform>>
|
||||
COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath,
|
||||
std::optional<SymbolAliasMap> RuntimeAliases) {
|
||||
|
||||
// If the target is not supported then bail out immediately.
|
||||
if (!supportedTarget(ES.getTargetTriple()))
|
||||
@@ -173,22 +174,6 @@ Expected<std::unique_ptr<COFFPlatform>> COFFPlatform::Create(
|
||||
|
||||
auto &EPC = ES.getExecutorProcessControl();
|
||||
|
||||
auto GeneratorArchive =
|
||||
object::Archive::create(OrcRuntimeArchiveBuffer->getMemBufferRef());
|
||||
if (!GeneratorArchive)
|
||||
return GeneratorArchive.takeError();
|
||||
|
||||
auto OrcRuntimeArchiveGenerator = StaticLibraryDefinitionGenerator::Create(
|
||||
ObjLinkingLayer, nullptr, std::move(*GeneratorArchive));
|
||||
if (!OrcRuntimeArchiveGenerator)
|
||||
return OrcRuntimeArchiveGenerator.takeError();
|
||||
|
||||
// We need a second instance of the archive (for now) for the Platform. We
|
||||
// can `cantFail` this call, since if it were going to fail it would have
|
||||
// failed above.
|
||||
auto RuntimeArchive = cantFail(
|
||||
object::Archive::create(OrcRuntimeArchiveBuffer->getMemBufferRef()));
|
||||
|
||||
// Create default aliases if the caller didn't supply any.
|
||||
if (!RuntimeAliases)
|
||||
RuntimeAliases = standardPlatformAliases(ES);
|
||||
@@ -214,30 +199,13 @@ Expected<std::unique_ptr<COFFPlatform>> COFFPlatform::Create(
|
||||
// Create the instance.
|
||||
Error Err = Error::success();
|
||||
auto P = std::unique_ptr<COFFPlatform>(new COFFPlatform(
|
||||
ES, ObjLinkingLayer, PlatformJD, std::move(*OrcRuntimeArchiveGenerator),
|
||||
std::move(OrcRuntimeArchiveBuffer), std::move(RuntimeArchive),
|
||||
ES, ObjLinkingLayer, PlatformJD, OrcRuntimePath,
|
||||
std::move(LoadDynLibrary), StaticVCRuntime, VCRuntimePath, Err));
|
||||
if (Err)
|
||||
return std::move(Err);
|
||||
return std::move(P);
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<COFFPlatform>>
|
||||
COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath,
|
||||
std::optional<SymbolAliasMap> RuntimeAliases) {
|
||||
|
||||
auto ArchiveBuffer = MemoryBuffer::getFile(OrcRuntimePath);
|
||||
if (!ArchiveBuffer)
|
||||
return createFileError(OrcRuntimePath, ArchiveBuffer.getError());
|
||||
|
||||
return Create(ES, ObjLinkingLayer, PlatformJD, std::move(*ArchiveBuffer),
|
||||
std::move(LoadDynLibrary), StaticVCRuntime, VCRuntimePath,
|
||||
std::move(RuntimeAliases));
|
||||
}
|
||||
|
||||
Expected<MemoryBufferRef> COFFPlatform::getPerJDObjectFile() {
|
||||
auto PerJDObj = OrcRuntimeArchive->findSym("__orc_rt_coff_per_jd_marker");
|
||||
if (!PerJDObj)
|
||||
@@ -381,22 +349,37 @@ bool COFFPlatform::supportedTarget(const Triple &TT) {
|
||||
}
|
||||
}
|
||||
|
||||
COFFPlatform::COFFPlatform(
|
||||
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD,
|
||||
std::unique_ptr<StaticLibraryDefinitionGenerator> OrcRuntimeGenerator,
|
||||
std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
|
||||
std::unique_ptr<object::Archive> OrcRuntimeArchive,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath, Error &Err)
|
||||
COFFPlatform::COFFPlatform(ExecutionSession &ES,
|
||||
ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynamicLibrary,
|
||||
bool StaticVCRuntime, const char *VCRuntimePath,
|
||||
Error &Err)
|
||||
: ES(ES), ObjLinkingLayer(ObjLinkingLayer),
|
||||
LoadDynLibrary(std::move(LoadDynLibrary)),
|
||||
OrcRuntimeArchiveBuffer(std::move(OrcRuntimeArchiveBuffer)),
|
||||
OrcRuntimeArchive(std::move(OrcRuntimeArchive)),
|
||||
LoadDynLibrary(std::move(LoadDynamicLibrary)),
|
||||
StaticVCRuntime(StaticVCRuntime),
|
||||
COFFHeaderStartSymbol(ES.intern("__ImageBase")) {
|
||||
ErrorAsOutParameter _(&Err);
|
||||
|
||||
// Create a generator for the ORC runtime archive.
|
||||
auto OrcRuntimeArchiveGenerator =
|
||||
StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer, OrcRuntimePath);
|
||||
if (!OrcRuntimeArchiveGenerator) {
|
||||
Err = OrcRuntimeArchiveGenerator.takeError();
|
||||
return;
|
||||
}
|
||||
|
||||
auto ArchiveBuffer = MemoryBuffer::getFile(OrcRuntimePath);
|
||||
if (!ArchiveBuffer) {
|
||||
Err = createFileError(OrcRuntimePath, ArchiveBuffer.getError());
|
||||
return;
|
||||
}
|
||||
OrcRuntimeArchiveBuffer = std::move(*ArchiveBuffer);
|
||||
OrcRuntimeArchive =
|
||||
std::make_unique<object::Archive>(*OrcRuntimeArchiveBuffer, Err);
|
||||
if (Err)
|
||||
return;
|
||||
|
||||
Bootstrapping.store(true);
|
||||
ObjLinkingLayer.addPlugin(std::make_unique<COFFPlatformPlugin>(*this));
|
||||
|
||||
@@ -409,7 +392,7 @@ COFFPlatform::COFFPlatform(
|
||||
}
|
||||
VCRuntimeBootstrap = std::move(*VCRT);
|
||||
|
||||
for (auto &Lib : OrcRuntimeGenerator->getImportedDynamicLibraries())
|
||||
for (auto &Lib : (*OrcRuntimeArchiveGenerator)->getImportedDynamicLibraries())
|
||||
DylibsToPreload.insert(Lib);
|
||||
|
||||
auto ImportedLibs =
|
||||
@@ -423,7 +406,7 @@ COFFPlatform::COFFPlatform(
|
||||
for (auto &Lib : *ImportedLibs)
|
||||
DylibsToPreload.insert(Lib);
|
||||
|
||||
PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
|
||||
PlatformJD.addGenerator(std::move(*OrcRuntimeArchiveGenerator));
|
||||
|
||||
// PlatformJD hasn't been set up by the platform yet (since we're creating
|
||||
// the platform now), so set it up.
|
||||
@@ -433,10 +416,10 @@ COFFPlatform::COFFPlatform(
|
||||
}
|
||||
|
||||
for (auto& Lib : DylibsToPreload)
|
||||
if (auto E2 = this->LoadDynLibrary(PlatformJD, Lib)) {
|
||||
Err = std::move(E2);
|
||||
return;
|
||||
}
|
||||
if (auto E2 = LoadDynLibrary(PlatformJD, Lib)) {
|
||||
Err = std::move(E2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (StaticVCRuntime)
|
||||
if (auto E2 = VCRuntimeBootstrap->initializeStaticVCRuntime(PlatformJD)) {
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
|
||||
#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
|
||||
#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
|
||||
@@ -101,16 +99,10 @@ public:
|
||||
ORC_RT_RTLD_GLOBAL = 0x8
|
||||
};
|
||||
|
||||
auto &ES = J.getExecutionSession();
|
||||
auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo(
|
||||
[](const JITDylibSearchOrder &SO) { return SO; });
|
||||
|
||||
if (auto WrapperAddr =
|
||||
ES.lookup(MainSearchOrder,
|
||||
J.mangleAndIntern("__orc_rt_jit_dlopen_wrapper"))) {
|
||||
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
|
||||
DSOHandles[&JD], JD.getName(),
|
||||
int32_t(ORC_RT_RTLD_LAZY));
|
||||
if (auto WrapperAddr = J.lookup("__orc_rt_jit_dlopen_wrapper")) {
|
||||
return J.getExecutionSession().callSPSWrapper<SPSDLOpenSig>(
|
||||
*WrapperAddr, DSOHandles[&JD], JD.getName(),
|
||||
int32_t(ORC_RT_RTLD_LAZY));
|
||||
} else
|
||||
return WrapperAddr.takeError();
|
||||
}
|
||||
@@ -119,16 +111,10 @@ public:
|
||||
using llvm::orc::shared::SPSExecutorAddr;
|
||||
using SPSDLCloseSig = int32_t(SPSExecutorAddr);
|
||||
|
||||
auto &ES = J.getExecutionSession();
|
||||
auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo(
|
||||
[](const JITDylibSearchOrder &SO) { return SO; });
|
||||
|
||||
if (auto WrapperAddr =
|
||||
ES.lookup(MainSearchOrder,
|
||||
J.mangleAndIntern("__orc_rt_jit_dlclose_wrapper"))) {
|
||||
if (auto WrapperAddr = J.lookup("__orc_rt_jit_dlclose_wrapper")) {
|
||||
int32_t result;
|
||||
auto E = J.getExecutionSession().callSPSWrapper<SPSDLCloseSig>(
|
||||
WrapperAddr->getAddress(), result, DSOHandles[&JD]);
|
||||
*WrapperAddr, result, DSOHandles[&JD]);
|
||||
if (E)
|
||||
return E;
|
||||
else if (result)
|
||||
@@ -191,7 +177,7 @@ private:
|
||||
/// some runtime API, including __cxa_atexit, dlopen, and dlclose.
|
||||
class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport {
|
||||
public:
|
||||
GenericLLVMIRPlatformSupport(LLJIT &J, JITDylib &PlatformJD)
|
||||
GenericLLVMIRPlatformSupport(LLJIT &J)
|
||||
: J(J), InitFunctionPrefix(J.mangle("__orc_init_func.")),
|
||||
DeInitFunctionPrefix(J.mangle("__orc_deinit_func.")) {
|
||||
|
||||
@@ -208,9 +194,10 @@ public:
|
||||
StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] = {
|
||||
ExecutorAddr::fromPtr(registerCxaAtExitHelper), JITSymbolFlags()};
|
||||
|
||||
cantFail(PlatformJD.define(absoluteSymbols(std::move(StdInterposes))));
|
||||
cantFail(setupJITDylib(PlatformJD));
|
||||
cantFail(J.addIRModule(PlatformJD, createPlatformRuntimeModule()));
|
||||
cantFail(
|
||||
J.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes))));
|
||||
cantFail(setupJITDylib(J.getMainJITDylib()));
|
||||
cantFail(J.addIRModule(J.getMainJITDylib(), createPlatformRuntimeModule()));
|
||||
}
|
||||
|
||||
ExecutionSession &getExecutionSession() { return J.getExecutionSession(); }
|
||||
@@ -767,19 +754,6 @@ LLJIT::~LLJIT() {
|
||||
ES->reportError(std::move(Err));
|
||||
}
|
||||
|
||||
JITDylibSP LLJIT::getProcessSymbolsJITDylib() { return ProcessSymbols; }
|
||||
|
||||
JITDylibSP LLJIT::getPlatformJITDylib() { return Platform; }
|
||||
|
||||
Expected<JITDylib &> LLJIT::createJITDylib(std::string Name) {
|
||||
auto JD = ES->createJITDylib(std::move(Name));
|
||||
if (!JD)
|
||||
return JD.takeError();
|
||||
|
||||
JD->addToLinkOrder(DefaultLinks);
|
||||
return JD;
|
||||
}
|
||||
|
||||
Expected<JITDylib &> LLJIT::loadPlatformDynamicLibrary(const char *Path) {
|
||||
auto G = EPCDynamicLibrarySearchGenerator::Load(*ES, Path);
|
||||
if (!G)
|
||||
@@ -919,6 +893,13 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
|
||||
}
|
||||
}
|
||||
|
||||
if (auto MainOrErr = this->ES->createJITDylib("main"))
|
||||
Main = &*MainOrErr;
|
||||
else {
|
||||
Err = MainOrErr.takeError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (S.DL)
|
||||
DL = std::move(*S.DL);
|
||||
else if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
|
||||
@@ -966,47 +947,10 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
|
||||
});
|
||||
}
|
||||
|
||||
if (S.LinkProcessSymbolsByDefault && !S.SetupProcessSymbolsJITDylib)
|
||||
S.SetupProcessSymbolsJITDylib = [this](JITDylib &JD) -> Error {
|
||||
auto G = orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
|
||||
DL.getGlobalPrefix());
|
||||
if (!G)
|
||||
return G.takeError();
|
||||
JD.addGenerator(std::move(*G));
|
||||
return Error::success();
|
||||
};
|
||||
|
||||
if (S.SetupProcessSymbolsJITDylib) {
|
||||
ProcessSymbols = &ES->createBareJITDylib("<Process Symbols>");
|
||||
if (auto Err2 = S.SetupProcessSymbolsJITDylib(*ProcessSymbols)) {
|
||||
Err = std::move(Err2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!S.SetUpPlatform)
|
||||
S.SetUpPlatform = setUpGenericLLVMIRPlatform;
|
||||
|
||||
if (auto PlatformJDOrErr = S.SetUpPlatform(*this)) {
|
||||
Platform = PlatformJDOrErr->get();
|
||||
if (Platform)
|
||||
DefaultLinks.push_back(
|
||||
{Platform, JITDylibLookupFlags::MatchExportedSymbolsOnly});
|
||||
} else {
|
||||
Err = PlatformJDOrErr.takeError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (S.LinkProcessSymbolsByDefault)
|
||||
DefaultLinks.push_back(
|
||||
{ProcessSymbols, JITDylibLookupFlags::MatchExportedSymbolsOnly});
|
||||
|
||||
if (auto MainOrErr = createJITDylib("main"))
|
||||
Main = &*MainOrErr;
|
||||
else {
|
||||
Err = MainOrErr.takeError();
|
||||
return;
|
||||
}
|
||||
if (S.SetUpPlatform)
|
||||
Err = S.SetUpPlatform(*this);
|
||||
else
|
||||
setUpGenericLLVMIRPlatform(*this);
|
||||
}
|
||||
|
||||
std::string LLJIT::mangle(StringRef UnmangledName) const {
|
||||
@@ -1032,136 +976,24 @@ Error LLJIT::applyDataLayout(Module &M) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error setUpOrcPlatformManually(LLJIT &J) {
|
||||
LLVM_DEBUG({ dbgs() << "Setting up orc platform support for LLJIT\n"; });
|
||||
J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
class LoadAndLinkDynLibrary {
|
||||
public:
|
||||
LoadAndLinkDynLibrary(LLJIT &J) : J(J) {}
|
||||
Error operator()(JITDylib &JD, StringRef DLLName) {
|
||||
if (!DLLName.endswith_insensitive(".dll"))
|
||||
return make_error<StringError>("DLLName not ending with .dll",
|
||||
inconvertibleErrorCode());
|
||||
auto DLLNameStr = DLLName.str(); // Guarantees null-termination.
|
||||
auto DLLJD = J.loadPlatformDynamicLibrary(DLLNameStr.c_str());
|
||||
if (!DLLJD)
|
||||
return DLLJD.takeError();
|
||||
JD.addToLinkOrder(*DLLJD);
|
||||
Error setUpOrcPlatform(LLJIT& J) {
|
||||
LLVM_DEBUG(
|
||||
{ dbgs() << "Setting up orc platform support for LLJIT\n"; });
|
||||
J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
private:
|
||||
LLJIT &J;
|
||||
};
|
||||
|
||||
Expected<JITDylibSP> ExecutorNativePlatform::operator()(LLJIT &J) {
|
||||
auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib();
|
||||
if (!ProcessSymbolsJD)
|
||||
return make_error<StringError>(
|
||||
"Native platforms require a process symbols JITDylib",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
const Triple &TT = J.getTargetTriple();
|
||||
ObjectLinkingLayer *ObjLinkingLayer =
|
||||
dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer());
|
||||
|
||||
if (!ObjLinkingLayer)
|
||||
return make_error<StringError>(
|
||||
"SetUpTargetPlatform requires ObjectLinkingLayer",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
std::unique_ptr<MemoryBuffer> RuntimeArchiveBuffer;
|
||||
if (OrcRuntime.index() == 0) {
|
||||
auto A = errorOrToExpected(MemoryBuffer::getFile(std::get<0>(OrcRuntime)));
|
||||
if (!A)
|
||||
return A.takeError();
|
||||
RuntimeArchiveBuffer = std::move(*A);
|
||||
} else
|
||||
RuntimeArchiveBuffer = std::move(std::get<1>(OrcRuntime));
|
||||
|
||||
auto &ES = J.getExecutionSession();
|
||||
auto &PlatformJD = ES.createBareJITDylib("<Platform>");
|
||||
PlatformJD.addToLinkOrder(*ProcessSymbolsJD);
|
||||
|
||||
J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));
|
||||
|
||||
switch (TT.getObjectFormat()) {
|
||||
case Triple::COFF: {
|
||||
const char *VCRuntimePath = nullptr;
|
||||
bool StaticVCRuntime = false;
|
||||
if (VCRuntime) {
|
||||
VCRuntimePath = VCRuntime->first.c_str();
|
||||
StaticVCRuntime = VCRuntime->second;
|
||||
}
|
||||
if (auto P = COFFPlatform::Create(
|
||||
ES, *ObjLinkingLayer, PlatformJD, std::move(RuntimeArchiveBuffer),
|
||||
LoadAndLinkDynLibrary(J), StaticVCRuntime, VCRuntimePath))
|
||||
J.getExecutionSession().setPlatform(std::move(*P));
|
||||
else
|
||||
return P.takeError();
|
||||
break;
|
||||
}
|
||||
case Triple::ELF: {
|
||||
auto G = StaticLibraryDefinitionGenerator::Create(
|
||||
*ObjLinkingLayer, std::move(RuntimeArchiveBuffer));
|
||||
if (!G)
|
||||
return G.takeError();
|
||||
|
||||
if (auto P = ELFNixPlatform::Create(ES, *ObjLinkingLayer, PlatformJD,
|
||||
std::move(*G)))
|
||||
J.getExecutionSession().setPlatform(std::move(*P));
|
||||
else
|
||||
return P.takeError();
|
||||
break;
|
||||
}
|
||||
case Triple::MachO: {
|
||||
auto G = StaticLibraryDefinitionGenerator::Create(
|
||||
*ObjLinkingLayer, std::move(RuntimeArchiveBuffer));
|
||||
if (!G)
|
||||
return G.takeError();
|
||||
|
||||
if (auto P = MachOPlatform::Create(ES, *ObjLinkingLayer, PlatformJD,
|
||||
std::move(*G)))
|
||||
ES.setPlatform(std::move(*P));
|
||||
else
|
||||
return P.takeError();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return make_error<StringError>("Unsupported object format in triple " +
|
||||
TT.str(),
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
return &PlatformJD;
|
||||
}
|
||||
|
||||
Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) {
|
||||
void setUpGenericLLVMIRPlatform(LLJIT &J) {
|
||||
LLVM_DEBUG(
|
||||
{ dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; });
|
||||
auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib();
|
||||
if (!ProcessSymbolsJD)
|
||||
return make_error<StringError>(
|
||||
"Native platforms require a process symbols JITDylib",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
auto &PlatformJD = J.getExecutionSession().createBareJITDylib("<Platform>");
|
||||
PlatformJD.addToLinkOrder(*ProcessSymbolsJD);
|
||||
|
||||
J.setPlatformSupport(
|
||||
std::make_unique<GenericLLVMIRPlatformSupport>(J, PlatformJD));
|
||||
|
||||
return &PlatformJD;
|
||||
J.setPlatformSupport(std::make_unique<GenericLLVMIRPlatformSupport>(J));
|
||||
}
|
||||
|
||||
Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J) {
|
||||
Error setUpInactivePlatform(LLJIT &J) {
|
||||
LLVM_DEBUG(
|
||||
{ dbgs() << "Explicitly deactivated platform support for LLJIT\n"; });
|
||||
J.setPlatformSupport(std::make_unique<InactivePlatformSupport>());
|
||||
return nullptr;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error LLLazyJITBuilderState::prepareForConstruction() {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
; LoongArch does not support emulated tls.
|
||||
; UNSUPPORTED: target=loongarch{{.*}}
|
||||
|
||||
; RUN: not lli -no-process-syms -lljit-platform=Inactive -emulated-tls \
|
||||
; RUN: -jit-kind=orc-lazy %s 2>&1 | FileCheck %s
|
||||
; RUN: not lli -no-process-syms -emulated-tls -jit-kind=orc-lazy %s 2>&1 \
|
||||
; RUN: | FileCheck %s
|
||||
;
|
||||
; Test that emulated-tls does not generate any unexpected errors.
|
||||
;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "llvm/ExecutionEngine/ObjectCache.h"
|
||||
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
|
||||
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
|
||||
@@ -34,6 +35,7 @@
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
|
||||
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
|
||||
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
|
||||
@@ -234,22 +236,20 @@ namespace {
|
||||
cl::desc("Do not resolve lli process symbols in JIT'd code"),
|
||||
cl::init(false));
|
||||
|
||||
enum class LLJITPlatform { Inactive, Auto, ExecutorNative, GenericIR };
|
||||
enum class LLJITPlatform { Inactive, DetectHost, ORC, GenericIR };
|
||||
|
||||
cl::opt<LLJITPlatform> Platform(
|
||||
"lljit-platform", cl::desc("Platform to use with LLJIT"),
|
||||
cl::init(LLJITPlatform::Auto),
|
||||
cl::values(clEnumValN(LLJITPlatform::Auto, "Auto",
|
||||
"Like 'ExecutorNative' if ORC runtime "
|
||||
"provided, otherwise like 'GenericIR'"),
|
||||
clEnumValN(LLJITPlatform::ExecutorNative, "ExecutorNative",
|
||||
"Use the native platform for the executor."
|
||||
"Requires -orc-runtime"),
|
||||
clEnumValN(LLJITPlatform::GenericIR, "GenericIR",
|
||||
"Use LLJITGenericIRPlatform"),
|
||||
clEnumValN(LLJITPlatform::Inactive, "Inactive",
|
||||
"Disable platform support explicitly")),
|
||||
cl::Hidden);
|
||||
cl::opt<LLJITPlatform>
|
||||
Platform("lljit-platform", cl::desc("Platform to use with LLJIT"),
|
||||
cl::init(LLJITPlatform::DetectHost),
|
||||
cl::values(clEnumValN(LLJITPlatform::DetectHost, "DetectHost",
|
||||
"Select based on JIT target triple"),
|
||||
clEnumValN(LLJITPlatform::ORC, "ORC",
|
||||
"Use ORCPlatform with the ORC runtime"),
|
||||
clEnumValN(LLJITPlatform::GenericIR, "GenericIR",
|
||||
"Use LLJITGenericIRPlatform"),
|
||||
clEnumValN(LLJITPlatform::Inactive, "Inactive",
|
||||
"Disable platform support explicitly")),
|
||||
cl::Hidden);
|
||||
|
||||
enum class DumpKind {
|
||||
NoDump,
|
||||
@@ -864,9 +864,6 @@ int runOrcJIT(const char *ProgName) {
|
||||
.setRelocationModel(codegen::getExplicitRelocModel())
|
||||
.setCodeModel(codegen::getExplicitCodeModel());
|
||||
|
||||
// Link process symbols unless NoProcessSymbols is set.
|
||||
Builder.setLinkProcessSymbolsByDefault(!NoProcessSymbols);
|
||||
|
||||
// FIXME: Setting a dummy call-through manager in non-lazy mode prevents the
|
||||
// JIT builder to instantiate a default (which would fail with an error for
|
||||
// unsupported architectures).
|
||||
@@ -908,15 +905,17 @@ int runOrcJIT(const char *ProgName) {
|
||||
|
||||
// Set up LLJIT platform.
|
||||
LLJITPlatform P = Platform;
|
||||
if (P == LLJITPlatform::Auto)
|
||||
P = OrcRuntime.empty() ? LLJITPlatform::GenericIR
|
||||
: LLJITPlatform::ExecutorNative;
|
||||
|
||||
switch (P) {
|
||||
case LLJITPlatform::ExecutorNative: {
|
||||
Builder.setPlatformSetUp(orc::ExecutorNativePlatform(OrcRuntime));
|
||||
break;
|
||||
if (P == LLJITPlatform::DetectHost) {
|
||||
if (JITLinker == JITLinkerKind::JITLink && !OrcRuntime.empty() &&
|
||||
(TT->isOSBinFormatMachO() || TT->isOSBinFormatELF()))
|
||||
P = LLJITPlatform::ORC;
|
||||
else
|
||||
P = LLJITPlatform::GenericIR;
|
||||
}
|
||||
switch (P) {
|
||||
case LLJITPlatform::ORC:
|
||||
Builder.setPlatformSetUp(orc::setUpOrcPlatform);
|
||||
break;
|
||||
case LLJITPlatform::GenericIR:
|
||||
// Nothing to do: LLJITBuilder will use this by default.
|
||||
break;
|
||||
@@ -935,7 +934,7 @@ int runOrcJIT(const char *ProgName) {
|
||||
Builder.setObjectLinkingLayerCreator([&EPC, &P](orc::ExecutionSession &ES,
|
||||
const Triple &TT) {
|
||||
auto L = std::make_unique<orc::ObjectLinkingLayer>(ES, EPC->getMemMgr());
|
||||
if (P != LLJITPlatform::ExecutorNative) {
|
||||
if (P != LLJITPlatform::ORC) {
|
||||
L->addPlugin(std::make_unique<orc::EHFrameRegistrationPlugin>(
|
||||
ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES))));
|
||||
L->addPlugin(std::make_unique<orc::DebugObjectManagerPlugin>(
|
||||
@@ -983,12 +982,46 @@ int runOrcJIT(const char *ProgName) {
|
||||
return TSM;
|
||||
});
|
||||
|
||||
if (GenerateBuiltinFunctions.size() > 0) {
|
||||
// Add LLI builtins.
|
||||
orc::MangleAndInterner Mangle(J->getExecutionSession(), J->getDataLayout());
|
||||
orc::MangleAndInterner Mangle(J->getExecutionSession(), J->getDataLayout());
|
||||
|
||||
// Unless they've been explicitly disabled, make process symbols available to
|
||||
// JIT'd code.
|
||||
if (!NoProcessSymbols)
|
||||
J->getMainJITDylib().addGenerator(
|
||||
ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
|
||||
J->getDataLayout().getGlobalPrefix(),
|
||||
[MainName = Mangle("main")](const orc::SymbolStringPtr &Name) {
|
||||
return Name != MainName;
|
||||
})));
|
||||
|
||||
if (GenerateBuiltinFunctions.size() > 0)
|
||||
J->getMainJITDylib().addGenerator(
|
||||
std::make_unique<LLIBuiltinFunctionGenerator>(GenerateBuiltinFunctions,
|
||||
Mangle));
|
||||
|
||||
if (P == LLJITPlatform::ORC) {
|
||||
if (auto *OLL = llvm::dyn_cast<llvm::orc::ObjectLinkingLayer>(ObjLayer)) {
|
||||
auto &ES = J->getExecutionSession();
|
||||
if (TT->isOSBinFormatMachO()) {
|
||||
if (auto P = llvm::orc::MachOPlatform::Create(
|
||||
ES, *OLL, J->getMainJITDylib(), OrcRuntime.c_str()))
|
||||
ES.setPlatform(std::move(*P));
|
||||
else
|
||||
ExitOnErr(P.takeError());
|
||||
} else if (TT->isOSBinFormatELF()) {
|
||||
if (auto P = llvm::orc::ELFNixPlatform::Create(
|
||||
ES, *OLL, J->getMainJITDylib(), OrcRuntime.c_str()))
|
||||
ES.setPlatform(std::move(*P));
|
||||
else
|
||||
ExitOnErr(P.takeError());
|
||||
} else {
|
||||
errs() << "No ORC platform support\n";
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
errs() << "ORC platform requires JITLink\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Regular modules are greedy: They materialize as a whole and trigger
|
||||
|
||||
Reference in New Issue
Block a user