Index: llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h =================================================================== --- llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h +++ llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h @@ -42,8 +42,8 @@ static Expected> Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, - LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false, - const char *VCRuntimePath = nullptr, + LoadDynamicLibrary LoadDynLibrary = nullptr, + bool StaticVCRuntime = false, const char *VCRuntimePath = nullptr, Optional RuntimeAliases = None); ExecutionSession &getExecutionSession() const { return ES; } Index: llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h =================================================================== --- llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h +++ llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h @@ -145,6 +145,10 @@ /// Get the PlatformSupport instance. PlatformSupport *getPlatformSupport() { return PS.get(); } + /// Load orc runtime archive and set up a Platform instance for + /// current JIT instance. + Error loadOrcRuntime(StringRef OrcRuntimePath); + /// Run the initializers for the given JITDylib. Error initialize(JITDylib &JD) { DEBUG_WITH_TYPE("orc", { @@ -447,8 +451,12 @@ public LLLazyJITBuilderSetters {}; -/// Configure the LLJIT instance to use orc runtime support. -Error setUpOrcPlatform(LLJIT& J); +/// Loads orc runtime platform instance from orc runtime archive path +/// and configure LLJIT instance to use orc runtime for platform support +/// facilities. (i.e. running static initializers) It fails if JITLink is not +/// enabled or the target platform and architecture of LLJIT instance is not +/// supported by orc runtime. +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 Index: llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp +++ llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp @@ -159,6 +159,23 @@ namespace llvm { namespace orc { +/// Default load dynamic library function that loads dll as +/// bare jitdylib and add it to link order. +static Error LoadDynLibraryAsJD(ExecutionSession &ES, JITDylib &JD, + StringRef DLLName) { + if (!DLLName.endswith_insensitive(".dll")) + return make_error("DLLName not ending with .dll", + inconvertibleErrorCode()); + auto G = EPCDynamicLibrarySearchGenerator::Load(ES, DLLName.data()); + if (!G) + return G.takeError(); + auto DynJD = &ES.createBareJITDylib(DLLName.data()); + DynJD->addGenerator(std::move(*G)); + + JD.addToLinkOrder(*DynJD); + return llvm::Error::success(); +} + Expected> COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, @@ -195,6 +212,12 @@ PlatformJD.addToLinkOrder(HostFuncJD); + // If not custom LoadDynLibrary is given use default one. + if (!LoadDynLibrary) + LoadDynLibrary = [ES = &ES](JITDylib &JD, StringRef DLLName) -> Error { + return LoadDynLibraryAsJD(*ES, JD, DLLName); + }; + // Create the instance. Error Err = Error::success(); auto P = std::unique_ptr(new COFFPlatform( @@ -415,10 +438,10 @@ } 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)) { Index: llvm/lib/ExecutionEngine/Orc/LLJIT.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -9,6 +9,8 @@ #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/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" @@ -927,11 +929,42 @@ return Error::success(); } -Error setUpOrcPlatform(LLJIT& J) { - LLVM_DEBUG( - { dbgs() << "Setting up orc platform support for LLJIT\n"; }); - J.setPlatformSupport(std::make_unique(J)); - return Error::success(); +Error LLJIT::loadOrcRuntime(StringRef OrcRuntimePath) { + auto &ES = getExecutionSession(); + auto TT = ES.getExecutorProcessControl().getTargetTriple(); + if (auto *OLL = dyn_cast(&getObjLinkingLayer())) { + if (TT.isOSBinFormatMachO()) { + if (auto P = llvm::orc::MachOPlatform::Create(ES, *OLL, getMainJITDylib(), + OrcRuntimePath.data())) + ES.setPlatform(std::move(*P)); + else + return P.takeError(); + } else if (TT.isOSBinFormatELF()) { + if (auto P = llvm::orc::ELFNixPlatform::Create( + ES, *OLL, getMainJITDylib(), OrcRuntimePath.data())) + ES.setPlatform(std::move(*P)); + else + return P.takeError(); + } else if (TT.isOSBinFormatCOFF()) { + if (auto P = llvm::orc::COFFPlatform::Create(ES, *OLL, getMainJITDylib(), + OrcRuntimePath.data())) + ES.setPlatform(std::move(*P)); + else + return P.takeError(); + } else + return llvm::make_error( + "No orc runtime support available.", llvm::inconvertibleErrorCode()); + } else + return llvm::make_error( + "JITLink is required for orc runtime.", llvm::inconvertibleErrorCode()); + + return Error::success(); +} + +Error setUpOrcPlatform(LLJIT &J) { + LLVM_DEBUG({ dbgs() << "Setting up orc platform support for LLJIT\n"; }); + J.setPlatformSupport(std::make_unique(J)); + return Error::success(); } void setUpGenericLLVMIRPlatform(LLJIT &J) { Index: llvm/tools/lli/lli.cpp =================================================================== --- llvm/tools/lli/lli.cpp +++ llvm/tools/lli/lli.cpp @@ -915,7 +915,8 @@ LLJITPlatform P = Platform; if (P == LLJITPlatform::DetectHost) { if (JITLinker == JITLinkerKind::JITLink && !OrcRuntime.empty() && - (TT->isOSBinFormatMachO() || TT->isOSBinFormatELF())) + (TT->isOSBinFormatMachO() || TT->isOSBinFormatELF() || + TT->isOSBinFormatCOFF())) P = LLJITPlatform::ORC; else P = LLJITPlatform::GenericIR; @@ -993,31 +994,8 @@ J->getMainJITDylib().addGenerator( std::make_unique(GenerateBuiltinFunctions, Mangle)); - - if (P == LLJITPlatform::ORC) { - if (auto *OLL = llvm::dyn_cast(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); - } - } + if (P == LLJITPlatform::ORC) + ExitOnErr(J->loadOrcRuntime(OrcRuntime)); // Regular modules are greedy: They materialize as a whole and trigger // materialization for all required symbols recursively. Lazy modules go