/// 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,
static bool supportedTarget(const Triple &TT);
- COFFPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
- JITDylib &PlatformJD, const char *OrcRuntimePath,
- LoadDynamicLibrary LoadDynamicLibrary, bool StaticVCRuntime,
- const char *VCRuntimePath, Error &Err);
+ 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);
// Associate COFFPlatform JIT-side runtime support functions with handlers.
Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
void setLinkOrder(JITDylibSearchOrder NewSearchOrder,
bool LinkAgainstThisJITDylibFirst = true);
+ /// Append the given JITDylibSearchOrder to the link order for this
+ /// JITDylib.
+ void addToLinkOrder(const JITDylibSearchOrder &NewLinks);
+
/// Add the given JITDylib to the link order for definitions in this
/// JITDylib.
///
class LLJIT {
template <typename, typename, typename> friend class LLJITBuilderSetters;
- friend void setUpGenericLLVMIRPlatform(LLJIT &J);
+ friend Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
public:
/// Initializer support for LLJIT.
/// 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) {
/// 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) {
- return ES->createJITDylib(std::move(Name));
- }
+ 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; }
/// Adds an IR module with the given ResourceTracker.
Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
std::unique_ptr<PlatformSupport> PS;
JITDylib *Main = nullptr;
+ JITDylib *ProcessSymbols = nullptr;
+ JITDylib *Platform = nullptr;
+
+ JITDylibSearchOrder DefaultLinks;
DataLayout DL;
Triple TT;
std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
JITTargetMachineBuilder JTMB)>;
- using PlatformSetupFunction = std::function<Error(LLJIT &J)>;
+ using ProcessSymbolsJITDylibSetupFunction =
+ std::function<Error(JITDylib &JD)>;
+
+ using PlatformSetupFunction = unique_function<Expected<JITDylibSP>(LLJIT &J)>;
std::unique_ptr<ExecutorProcessControl> EPC;
std::unique_ptr<ExecutionSession> ES;
std::optional<JITTargetMachineBuilder> JTMB;
std::optional<DataLayout> DL;
+ bool LinkProcessSymbolsJITDylibByDefault = true;
+ ProcessSymbolsJITDylibSetupFunction SetupProcessSymbolsJITDylib;
ObjectLinkingLayerCreator CreateObjectLinkingLayer;
CompileFunctionCreator CreateCompileFunction;
PlatformSetupFunction SetUpPlatform;
return impl();
}
+ /// The LinkProcessSymbolsJITDylibDyDefault 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 &
+ setLinkProcessSymbolsJITDylibByDefault(bool LinkProcessSymsByDefault) {
+ impl().LinkProcessSymbolsJITDylibByDefault = LinkProcessSymsByDefault;
+ 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
public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
LLLazyJITBuilderState> {};
-/// Configure the LLJIT instance to use orc runtime support.
-Error setUpOrcPlatform(LLJIT& J);
+/// 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 SetUpExecutorNativePlatform {
+public:
+ /// Set up using path to Orc runtime. CreatePlatformJD will be run before
+ /// attempting to construct the platform instance. It should be used (if
+ /// needed) to provide the offers an opportunity
+ /// to load process symbols.
+ SetUpExecutorNativePlatform(std::string OrcRuntimePath)
+ : OrcRuntime(std::move(OrcRuntimePath)) {}
+
+ /// Set up using the given memory buffer.
+ SetUpExecutorNativePlatform(std::unique_ptr<MemoryBuffer> OrcRuntimeMB)
+ : OrcRuntime(std::move(OrcRuntimeMB)) {}
+
+ // TODO: add compiler-rt.
+
+ /// Add a path to the VC runtime.
+ SetUpExecutorNativePlatform &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 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.
-void setUpGenericLLVMIRPlatform(LLJIT &J);
+Expected<JITDylibSP> 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.
-Error setUpInactivePlatform(LLJIT &J);
+Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J);
} // End namespace orc
} // End namespace llvm
namespace llvm {
namespace orc {
-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) {
+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) {
// If the target is not supported then bail out immediately.
if (!supportedTarget(ES.getTargetTriple()))
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);
// Create the instance.
Error Err = Error::success();
auto P = std::unique_ptr<COFFPlatform>(new COFFPlatform(
- ES, ObjLinkingLayer, PlatformJD, OrcRuntimePath,
+ ES, ObjLinkingLayer, PlatformJD, std::move(*OrcRuntimeArchiveGenerator),
+ std::move(OrcRuntimeArchiveBuffer), std::move(RuntimeArchive),
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)
}
}
-COFFPlatform::COFFPlatform(ExecutionSession &ES,
- ObjectLinkingLayer &ObjLinkingLayer,
- JITDylib &PlatformJD, const char *OrcRuntimePath,
- LoadDynamicLibrary LoadDynamicLibrary,
- bool StaticVCRuntime, const char *VCRuntimePath,
- Error &Err)
+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)
: ES(ES), ObjLinkingLayer(ObjLinkingLayer),
- LoadDynLibrary(std::move(LoadDynamicLibrary)),
+ LoadDynLibrary(std::move(LoadDynLibrary)),
+ OrcRuntimeArchiveBuffer(std::move(OrcRuntimeArchiveBuffer)),
+ OrcRuntimeArchive(std::move(OrcRuntimeArchive)),
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));
}
VCRuntimeBootstrap = std::move(*VCRT);
- for (auto &Lib : (*OrcRuntimeArchiveGenerator)->getImportedDynamicLibraries())
+ for (auto &Lib : OrcRuntimeGenerator->getImportedDynamicLibraries())
DylibsToPreload.insert(Lib);
auto ImportedLibs =
for (auto &Lib : *ImportedLibs)
DylibsToPreload.insert(Lib);
- PlatformJD.addGenerator(std::move(*OrcRuntimeArchiveGenerator));
+ PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
// PlatformJD hasn't been set up by the platform yet (since we're creating
// the platform now), so set it up.
}
for (auto& Lib : DylibsToPreload)
- if (auto E2 = LoadDynLibrary(PlatformJD, Lib)) {
- Err = std::move(E2);
- return;
- }
+ if (auto E2 = this->LoadDynLibrary(PlatformJD, Lib)) {
+ Err = std::move(E2);
+ return;
+ }
if (StaticVCRuntime)
if (auto E2 = VCRuntimeBootstrap->initializeStaticVCRuntime(PlatformJD)) {
});
}
+void JITDylib::addToLinkOrder(const JITDylibSearchOrder &NewLinks) {
+ ES.runSessionLocked([&]() {
+ LinkOrder.reserve(LinkOrder.size() + NewLinks.size());
+ llvm::append_range(LinkOrder, NewLinks);
+ });
+}
+
void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) {
ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });
}
#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/EPCEHFrameRegistrar.h"
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
/// some runtime API, including __cxa_atexit, dlopen, and dlclose.
class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport {
public:
- GenericLLVMIRPlatformSupport(LLJIT &J)
+ GenericLLVMIRPlatformSupport(LLJIT &J, JITDylib &PlatformJD)
: J(J), InitFunctionPrefix(J.mangle("__orc_init_func.")),
DeInitFunctionPrefix(J.mangle("__orc_deinit_func.")) {
JITEvaluatedSymbol(pointerToJITTargetAddress(registerCxaAtExitHelper),
JITSymbolFlags());
- cantFail(
- J.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes))));
- cantFail(setupJITDylib(J.getMainJITDylib()));
- cantFail(J.addIRModule(J.getMainJITDylib(), createPlatformRuntimeModule()));
+ cantFail(PlatformJD.define(absoluteSymbols(std::move(StdInterposes))));
+ cantFail(setupJITDylib(PlatformJD));
+ cantFail(J.addIRModule(PlatformJD, createPlatformRuntimeModule()));
}
ExecutionSession &getExecutionSession() { return J.getExecutionSession(); }
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;
+}
+
Error LLJIT::addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) {
assert(TSM && "Can not add null module");
}
}
- 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())
});
}
- if (S.SetUpPlatform)
- Err = S.SetUpPlatform(*this);
- else
- setUpGenericLLVMIRPlatform(*this);
+ if (S.LinkProcessSymbolsJITDylibByDefault && !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.LinkProcessSymbolsJITDylibByDefault)
+ DefaultLinks.push_back(
+ {ProcessSymbols, JITDylibLookupFlags::MatchExportedSymbolsOnly});
+
+ if (auto MainOrErr = createJITDylib("main"))
+ Main = &*MainOrErr;
+ else {
+ Err = MainOrErr.takeError();
+ return;
+ }
}
std::string LLJIT::mangle(StringRef UnmangledName) const {
return Error::success();
}
-Error setUpOrcPlatform(LLJIT& J) {
- LLVM_DEBUG(
- { dbgs() << "Setting up orc platform support for LLJIT\n"; });
- J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));
+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());
+ // TODO: Actually load library.
+ (void)J;
return Error::success();
+ }
+
+private:
+ LLJIT &J;
+};
+
+Expected<JITDylibSP> SetUpExecutorNativePlatform::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;
}
-void setUpGenericLLVMIRPlatform(LLJIT &J) {
+Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) {
LLVM_DEBUG(
{ dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; });
- J.setPlatformSupport(std::make_unique<GenericLLVMIRPlatformSupport>(J));
+ 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;
}
-Error setUpInactivePlatform(LLJIT &J) {
+Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J) {
LLVM_DEBUG(
{ dbgs() << "Explicitly deactivated platform support for LLJIT\n"; });
J.setPlatformSupport(std::make_unique<InactivePlatformSupport>());
- return Error::success();
+ return nullptr;
}
Error LLLazyJITBuilderState::prepareForConstruction() {
; LoongArch does not support emulated tls.
; UNSUPPORTED: target=loongarch{{.*}}
-; RUN: not lli -no-process-syms -emulated-tls -jit-kind=orc-lazy %s 2>&1 \
+; RUN: not lli -emulated-tls -jit-kind=orc-lazy %s 2>&1 \
; RUN: | FileCheck %s
;
; Test that emulated-tls does not generate any unexpected errors.
#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"
#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"
cl::desc("Do not resolve lli process symbols in JIT'd code"),
cl::init(false));
- enum class LLJITPlatform { Inactive, DetectHost, ORC, GenericIR };
-
- 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 LLJITPlatform { Inactive, Auto, ExecutorNative, 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);
enum class DumpKind {
NoDump,
.setRelocationModel(codegen::getExplicitRelocModel())
.setCodeModel(codegen::getExplicitCodeModel());
+ // Link process symbols unless NoProcessSymbols is set.
+ Builder.setLinkProcessSymbolsJITDylibByDefault(!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).
// Set up LLJIT platform.
LLJITPlatform P = Platform;
- if (P == LLJITPlatform::DetectHost) {
- if (JITLinker == JITLinkerKind::JITLink && !OrcRuntime.empty() &&
- (TT->isOSBinFormatMachO() || TT->isOSBinFormatELF()))
- P = LLJITPlatform::ORC;
- else
- P = LLJITPlatform::GenericIR;
- }
+ if (P == LLJITPlatform::Auto)
+ P = OrcRuntime.empty() ? LLJITPlatform::GenericIR
+ : LLJITPlatform::ExecutorNative;
+
switch (P) {
- case LLJITPlatform::ORC:
- Builder.setPlatformSetUp(orc::setUpOrcPlatform);
+ case LLJITPlatform::ExecutorNative: {
+ Builder.setPlatformSetUp(orc::SetUpExecutorNativePlatform(OrcRuntime));
break;
+ }
case LLJITPlatform::GenericIR:
// Nothing to do: LLJITBuilder will use this by default.
break;
Builder.setObjectLinkingLayerCreator([&EPC, &P](orc::ExecutionSession &ES,
const Triple &TT) {
auto L = std::make_unique<orc::ObjectLinkingLayer>(ES, EPC->getMemMgr());
- if (P != LLJITPlatform::ORC) {
+ if (P != LLJITPlatform::ExecutorNative) {
L->addPlugin(std::make_unique<orc::EHFrameRegistrationPlugin>(
ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES))));
L->addPlugin(std::make_unique<orc::DebugObjectManagerPlugin>(
return TSM;
});
- 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)
+ if (GenerateBuiltinFunctions.size() > 0) {
+ // Add LLI builtins.
+ orc::MangleAndInterner Mangle(J->getExecutionSession(), J->getDataLayout());
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