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:
Lang Hames
2023-04-07 05:32:21 +00:00
parent 624973806c
commit 0b2240eda0
6 changed files with 147 additions and 388 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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)) {

View File

@@ -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() {

View File

@@ -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.
;

View File

@@ -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