diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp index 37d230b61f766..d744270d486a1 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.cpp +++ b/clang/lib/Interpreter/IncrementalExecutor.cpp @@ -43,15 +43,6 @@ IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, Err = JitOrErr.takeError(); return; } - - const char Pref = Jit->getDataLayout().getGlobalPrefix(); - // Discover symbols from the process as a fallback. - if (auto PSGOrErr = DynamicLibrarySearchGenerator::GetForCurrentProcess(Pref)) - Jit->getMainJITDylib().addGenerator(std::move(*PSGOrErr)); - else { - Err = PSGOrErr.takeError(); - return; - } } IncrementalExecutor::~IncrementalExecutor() {} diff --git a/llvm/examples/OrcV2Examples/CMakeLists.txt b/llvm/examples/OrcV2Examples/CMakeLists.txt index af738e7bcb309..f1189e4ef96ca 100644 --- a/llvm/examples/OrcV2Examples/CMakeLists.txt +++ b/llvm/examples/OrcV2Examples/CMakeLists.txt @@ -14,7 +14,6 @@ add_subdirectory(OrcV2CBindingsBasicUsage) add_subdirectory(OrcV2CBindingsDumpObjects) add_subdirectory(OrcV2CBindingsIRTransforms) add_subdirectory(OrcV2CBindingsMCJITLikeMemoryManager) -add_subdirectory(OrcV2CBindingsReflectProcessSymbols) add_subdirectory(OrcV2CBindingsRemovableCode) add_subdirectory(OrcV2CBindingsLazy) add_subdirectory(OrcV2CBindingsVeryLazy) diff --git a/llvm/examples/OrcV2Examples/LLJITWithExecutorProcessControl/LLJITWithExecutorProcessControl.cpp b/llvm/examples/OrcV2Examples/LLJITWithExecutorProcessControl/LLJITWithExecutorProcessControl.cpp index d3ca7bfc1ee30..8d2ac3261e399 100644 --- a/llvm/examples/OrcV2Examples/LLJITWithExecutorProcessControl/LLJITWithExecutorProcessControl.cpp +++ b/llvm/examples/OrcV2Examples/LLJITWithExecutorProcessControl/LLJITWithExecutorProcessControl.cpp @@ -22,7 +22,6 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" -#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" #include "llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h" #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" @@ -152,9 +151,6 @@ int main(int argc, char *argv[]) { EPCIU->createLazyCallThroughManager( J->getExecutionSession(), ExecutorAddr::fromPtr(&reportErrorAndExit)); auto ISM = EPCIU->createIndirectStubsManager(); - J->getMainJITDylib().addGenerator( - ExitOnErr(EPCDynamicLibrarySearchGenerator::GetForTargetProcess( - J->getExecutionSession()))); // (4) Add modules. ExitOnErr(J->addIRModule(ExitOnErr(parseExampleModule(FooMod, "foo-mod")))); diff --git a/llvm/examples/OrcV2Examples/LLJITWithGDBRegistrationListener/LLJITWithGDBRegistrationListener.cpp b/llvm/examples/OrcV2Examples/LLJITWithGDBRegistrationListener/LLJITWithGDBRegistrationListener.cpp index 16e7ba3cc080b..5ee52244b3fb4 100644 --- a/llvm/examples/OrcV2Examples/LLJITWithGDBRegistrationListener/LLJITWithGDBRegistrationListener.cpp +++ b/llvm/examples/OrcV2Examples/LLJITWithGDBRegistrationListener/LLJITWithGDBRegistrationListener.cpp @@ -82,17 +82,6 @@ int main(int argc, char *argv[]) { }) .create()); - // Make sure that our process symbols are visible to JIT'd code. - { - MangleAndInterner Mangle(J->getExecutionSession(), J->getDataLayout()); - J->getMainJITDylib().addGenerator( - ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess( - J->getDataLayout().getGlobalPrefix(), - [MainName = Mangle("main")](const orc::SymbolStringPtr &Name) { - return Name != MainName; - }))); - } - // Load the input modules. for (auto &InputFile : InputFiles) { auto Ctx = std::make_unique(); diff --git a/llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin/LLJITWithObjectLinkingLayerPlugin.cpp b/llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin/LLJITWithObjectLinkingLayerPlugin.cpp index dd097a15b15e6..10b1633646349 100644 --- a/llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin/LLJITWithObjectLinkingLayerPlugin.cpp +++ b/llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin/LLJITWithObjectLinkingLayerPlugin.cpp @@ -218,13 +218,6 @@ int main(int argc, char *argv[]) { .create()); if (!InputObjects.empty()) { - - // If we have input objects then reflect process symbols so the input - // objects can do interesting things, like call printf. - J->getMainJITDylib().addGenerator( - ExitOnErr(DynamicLibrarySearchGenerator::GetForCurrentProcess( - J->getDataLayout().getGlobalPrefix()))); - // Load the input objects. for (auto InputObject : InputObjects) { auto ObjBuffer = diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/CMakeLists.txt b/llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/CMakeLists.txt deleted file mode 100644 index beb44692786c4..0000000000000 --- a/llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Core - ExecutionEngine - IRReader - JITLink - MC - OrcJIT - Support - Target - nativecodegen - ) - -add_llvm_example(OrcV2CBindingsReflectProcessSymbols - OrcV2CBindingsReflectProcessSymbols.c - ) - -export_executable_symbols(OrcV2CBindingsReflectProcessSymbols) diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/OrcV2CBindingsReflectProcessSymbols.c b/llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/OrcV2CBindingsReflectProcessSymbols.c deleted file mode 100644 index 1966d65b159e3..0000000000000 --- a/llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/OrcV2CBindingsReflectProcessSymbols.c +++ /dev/null @@ -1,221 +0,0 @@ -//===-------- BasicOrcV2CBindings.c - Basic OrcV2 C Bindings Demo ---------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm-c/Core.h" -#include "llvm-c/Error.h" -#include "llvm-c/LLJIT.h" -#include "llvm-c/Support.h" -#include "llvm-c/Target.h" - -#include -#include - -int handleError(LLVMErrorRef Err) { - char *ErrMsg = LLVMGetErrorMessage(Err); - fprintf(stderr, "Error: %s\n", ErrMsg); - LLVMDisposeErrorMessage(ErrMsg); - return 1; -} - -int32_t add(int32_t X, int32_t Y) { return X + Y; } - -int32_t mul(int32_t X, int32_t Y) { return X * Y; } - -int allowedSymbols(void *Ctx, LLVMOrcSymbolStringPoolEntryRef Sym) { - assert(Ctx && "Cannot call allowedSymbols with a null context"); - - LLVMOrcSymbolStringPoolEntryRef *AllowList = - (LLVMOrcSymbolStringPoolEntryRef *)Ctx; - - // If Sym appears in the allowed list then return true. - LLVMOrcSymbolStringPoolEntryRef *P = AllowList; - while (*P) { - if (Sym == *P) - return 1; - ++P; - } - - // otherwise return false. - return 0; -} - -LLVMOrcThreadSafeModuleRef createDemoModule(void) { - // Create a new ThreadSafeContext and underlying LLVMContext. - LLVMOrcThreadSafeContextRef TSCtx = LLVMOrcCreateNewThreadSafeContext(); - - // Get a reference to the underlying LLVMContext. - LLVMContextRef Ctx = LLVMOrcThreadSafeContextGetContext(TSCtx); - - // Create a new LLVM module. - LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx); - - // Add a "sum" function": - // - Create the function type and function instance. - LLVMTypeRef I32BinOpParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()}; - LLVMTypeRef I32BinOpFunctionType = - LLVMFunctionType(LLVMInt32Type(), I32BinOpParamTypes, 2, 0); - LLVMValueRef AddI32Function = LLVMAddFunction(M, "add", I32BinOpFunctionType); - LLVMValueRef MulI32Function = LLVMAddFunction(M, "mul", I32BinOpFunctionType); - - LLVMTypeRef MulAddParamTypes[] = {LLVMInt32Type(), LLVMInt32Type(), - LLVMInt32Type()}; - LLVMTypeRef MulAddFunctionType = - LLVMFunctionType(LLVMInt32Type(), MulAddParamTypes, 3, 0); - LLVMValueRef MulAddFunction = - LLVMAddFunction(M, "mul_add", MulAddFunctionType); - - // - Add a basic block to the function. - LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(MulAddFunction, "entry"); - - // - Add an IR builder and point it at the end of the basic block. - LLVMBuilderRef Builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(Builder, EntryBB); - - // - Get the three function arguments and use them co construct calls to - // 'mul' and 'add': - // - // i32 mul_add(i32 %0, i32 %1, i32 %2) { - // %t = call i32 @mul(i32 %0, i32 %1) - // %r = call i32 @add(i32 %t, i32 %2) - // ret i32 %r - // } - LLVMValueRef SumArg0 = LLVMGetParam(MulAddFunction, 0); - LLVMValueRef SumArg1 = LLVMGetParam(MulAddFunction, 1); - LLVMValueRef SumArg2 = LLVMGetParam(MulAddFunction, 2); - - LLVMValueRef MulArgs[] = {SumArg0, SumArg1}; - LLVMValueRef MulResult = LLVMBuildCall2(Builder, I32BinOpFunctionType, - MulI32Function, MulArgs, 2, "t"); - - LLVMValueRef AddArgs[] = {MulResult, SumArg2}; - LLVMValueRef AddResult = LLVMBuildCall2(Builder, I32BinOpFunctionType, - AddI32Function, AddArgs, 2, "r"); - - // - Build the return instruction. - LLVMBuildRet(Builder, AddResult); - - // - Free the builder. - LLVMDisposeBuilder(Builder); - - // Our demo module is now complete. Wrap it and our ThreadSafeContext in a - // ThreadSafeModule. - LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule(M, TSCtx); - - // Dispose of our local ThreadSafeContext value. The underlying LLVMContext - // will be kept alive by our ThreadSafeModule, TSM. - LLVMOrcDisposeThreadSafeContext(TSCtx); - - // Return the result. - return TSM; -} - -int main(int argc, char *argv[]) { - - int MainResult = 0; - - // Parse command line arguments and initialize LLVM Core. - LLVMParseCommandLineOptions(argc, (const char **)argv, ""); - - // Initialize native target codegen and asm printer. - LLVMInitializeNativeTarget(); - LLVMInitializeNativeAsmPrinter(); - - // Create the JIT instance. - LLVMOrcLLJITRef J; - { - LLVMErrorRef Err; - if ((Err = LLVMOrcCreateLLJIT(&J, 0))) { - MainResult = handleError(Err); - goto llvm_shutdown; - } - } - - // Build a filter to allow JIT'd code to only access allowed symbols. - // This filter is optional: If a null value is suppled for the Filter - // argument to LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess then - // all process symbols will be reflected. - LLVMOrcSymbolStringPoolEntryRef AllowList[] = { - LLVMOrcLLJITMangleAndIntern(J, "mul"), - LLVMOrcLLJITMangleAndIntern(J, "add"), 0}; - - { - LLVMOrcDefinitionGeneratorRef ProcessSymbolsGenerator = 0; - LLVMErrorRef Err; - if ((Err = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( - &ProcessSymbolsGenerator, LLVMOrcLLJITGetGlobalPrefix(J), - allowedSymbols, AllowList))) { - MainResult = handleError(Err); - goto jit_cleanup; - } - - LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(J), - ProcessSymbolsGenerator); - } - - // Create our demo module. - LLVMOrcThreadSafeModuleRef TSM = createDemoModule(); - - // Add our demo module to the JIT. - { - LLVMOrcJITDylibRef MainJD = LLVMOrcLLJITGetMainJITDylib(J); - LLVMErrorRef Err; - if ((Err = LLVMOrcLLJITAddLLVMIRModule(J, MainJD, TSM))) { - // If adding the ThreadSafeModule fails then we need to clean it up - // ourselves. If adding it succeeds the JIT will manage the memory. - LLVMOrcDisposeThreadSafeModule(TSM); - MainResult = handleError(Err); - goto jit_cleanup; - } - } - - // Look up the address of our demo entry point. - LLVMOrcJITTargetAddress MulAddAddr; - { - LLVMErrorRef Err; - if ((Err = LLVMOrcLLJITLookup(J, &MulAddAddr, "mul_add"))) { - MainResult = handleError(Err); - goto jit_cleanup; - } - } - - // If we made it here then everything succeeded. Execute our JIT'd code. - int32_t (*MulAdd)(int32_t, int32_t, int32_t) = - (int32_t(*)(int32_t, int32_t, int32_t))MulAddAddr; - int32_t Result = MulAdd(3, 4, 5); - - // Print the result. - printf("3 * 4 + 5 = %i\n", Result); - -jit_cleanup: - // Release all symbol string pool entries that we have allocated. In this - // example that's just our allowed entries. - { - LLVMOrcSymbolStringPoolEntryRef *P = AllowList; - while (*P) - LLVMOrcReleaseSymbolStringPoolEntry(*P++); - } - - // Destroy our JIT instance. This will clean up any memory that the JIT has - // taken ownership of. This operation is non-trivial (e.g. it may need to - // JIT static destructors) and may also fail. In that case we want to render - // the error to stderr, but not overwrite any existing return value. - { - LLVMErrorRef Err; - if ((Err = LLVMOrcDisposeLLJIT(J))) { - int NewFailureResult = handleError(Err); - if (MainResult == 0) - MainResult = NewFailureResult; - } - } - -llvm_shutdown: - // Shut down LLVM. - LLVMShutdown(); - - return MainResult; -} diff --git a/llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h index 969c6f0b15afc..4ef208dbbca22 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h @@ -39,6 +39,14 @@ class COFFPlatform : public Platform { /// Try to create a COFFPlatform instance, adding the ORC runtime to the /// given JITDylib. + static Expected> + Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, + JITDylib &PlatformJD, + std::unique_ptr OrcRuntimeArchiveBuffer, + LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false, + const char *VCRuntimePath = nullptr, + std::optional RuntimeAliases = std::nullopt); + static Expected> Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, @@ -136,10 +144,14 @@ class COFFPlatform : public Platform { 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 OrcRuntimeGenerator, + std::unique_ptr OrcRuntimeArchiveBuffer, + std::unique_ptr OrcRuntimeArchive, + LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime, + const char *VCRuntimePath, Error &Err); // Associate COFFPlatform JIT-side runtime support functions with handlers. Error associateRuntimeSupportFunctions(JITDylib &PlatformJD); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h index b61947efcc1dc..5984d2d3f8a96 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h @@ -37,7 +37,7 @@ class ExecutorProcessControl; class LLJIT { template friend class LLJITBuilderSetters; - friend void setUpGenericLLVMIRPlatform(LLJIT &J); + friend Expected setUpGenericLLVMIRPlatform(LLJIT &J); public: /// Initializer support for LLJIT. @@ -70,6 +70,20 @@ class 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) { @@ -108,9 +122,12 @@ class LLJIT { /// 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 createJITDylib(std::string Name) { - return ES->createJITDylib(std::move(Name)); - } + Expected 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); @@ -228,8 +245,12 @@ class LLJIT { std::unique_ptr ES; std::unique_ptr PS; + JITDylib *ProcessSymbols = nullptr; + JITDylib *Platform = nullptr; JITDylib *Main = nullptr; + JITDylibSearchOrder DefaultLinks; + DataLayout DL; Triple TT; std::unique_ptr CompileThreads; @@ -284,12 +305,17 @@ class LLJITBuilderState { std::function>( JITTargetMachineBuilder JTMB)>; - using PlatformSetupFunction = std::function; + using ProcessSymbolsJITDylibSetupFunction = + std::function; + + using PlatformSetupFunction = unique_function(LLJIT &J)>; std::unique_ptr EPC; std::unique_ptr ES; std::optional JTMB; std::optional DL; + bool LinkProcessSymbolsByDefault = true; + ProcessSymbolsJITDylibSetupFunction SetupProcessSymbolsJITDylib; ObjectLinkingLayerCreator CreateObjectLinkingLayer; CompileFunctionCreator CreateCompileFunction; PlatformSetupFunction SetUpPlatform; @@ -342,6 +368,28 @@ class LLJITBuilderSetters { 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 @@ -473,20 +521,49 @@ class LLLazyJITBuilder public LLLazyJITBuilderSetters {}; -/// 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 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 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 operator()(LLJIT &J); + +private: + std::variant> OrcRuntime; + std::optional> 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 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 setUpInactivePlatform(LLJIT &J); } // End namespace orc } // End namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp index 06144bd5b1826..7c869bead0b00 100644 --- a/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp @@ -159,12 +159,11 @@ class COFFHeaderMaterializationUnit : public MaterializationUnit { namespace llvm { namespace orc { -Expected> -COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, - JITDylib &PlatformJD, const char *OrcRuntimePath, - LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime, - const char *VCRuntimePath, - std::optional RuntimeAliases) { +Expected> COFFPlatform::Create( + ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, + JITDylib &PlatformJD, std::unique_ptr OrcRuntimeArchiveBuffer, + LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime, + const char *VCRuntimePath, std::optional RuntimeAliases) { // If the target is not supported then bail out immediately. if (!supportedTarget(ES.getTargetTriple())) @@ -174,6 +173,22 @@ COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, 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); @@ -199,13 +214,30 @@ COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, // Create the instance. Error Err = Error::success(); auto P = std::unique_ptr(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> +COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, + JITDylib &PlatformJD, const char *OrcRuntimePath, + LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime, + const char *VCRuntimePath, + std::optional 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 COFFPlatform::getPerJDObjectFile() { auto PerJDObj = OrcRuntimeArchive->findSym("__orc_rt_coff_per_jd_marker"); if (!PerJDObj) @@ -349,37 +381,22 @@ bool COFFPlatform::supportedTarget(const Triple &TT) { } } -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 OrcRuntimeGenerator, + std::unique_ptr OrcRuntimeArchiveBuffer, + std::unique_ptr 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(*OrcRuntimeArchiveBuffer, Err); - if (Err) - return; - Bootstrapping.store(true); ObjLinkingLayer.addPlugin(std::make_unique(*this)); @@ -392,7 +409,7 @@ COFFPlatform::COFFPlatform(ExecutionSession &ES, } VCRuntimeBootstrap = std::move(*VCRT); - for (auto &Lib : (*OrcRuntimeArchiveGenerator)->getImportedDynamicLibraries()) + for (auto &Lib : OrcRuntimeGenerator->getImportedDynamicLibraries()) DylibsToPreload.insert(Lib); auto ImportedLibs = @@ -406,7 +423,7 @@ COFFPlatform::COFFPlatform(ExecutionSession &ES, 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. @@ -416,10 +433,10 @@ COFFPlatform::COFFPlatform(ExecutionSession &ES, } 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)) { diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 65e63eb2d932b..fd106f9dc3ef8 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/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/EPCDynamicLibrarySearchGenerator.h" #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h" #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" @@ -99,10 +101,16 @@ class ORCPlatformSupport : public LLJIT::PlatformSupport { ORC_RT_RTLD_GLOBAL = 0x8 }; - if (auto WrapperAddr = J.lookup("__orc_rt_jit_dlopen_wrapper")) { - return J.getExecutionSession().callSPSWrapper( - *WrapperAddr, DSOHandles[&JD], JD.getName(), - int32_t(ORC_RT_RTLD_LAZY)); + 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(WrapperAddr->getAddress(), + DSOHandles[&JD], JD.getName(), + int32_t(ORC_RT_RTLD_LAZY)); } else return WrapperAddr.takeError(); } @@ -111,10 +119,16 @@ class ORCPlatformSupport : public LLJIT::PlatformSupport { using llvm::orc::shared::SPSExecutorAddr; using SPSDLCloseSig = int32_t(SPSExecutorAddr); - if (auto WrapperAddr = J.lookup("__orc_rt_jit_dlclose_wrapper")) { + 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"))) { int32_t result; auto E = J.getExecutionSession().callSPSWrapper( - *WrapperAddr, result, DSOHandles[&JD]); + WrapperAddr->getAddress(), result, DSOHandles[&JD]); if (E) return E; else if (result) @@ -177,7 +191,7 @@ class GlobalCtorDtorScraper { /// 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.")) { @@ -194,10 +208,9 @@ class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] = { ExecutorAddr::fromPtr(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(); } @@ -754,6 +767,19 @@ LLJIT::~LLJIT() { ES->reportError(std::move(Err)); } +JITDylibSP LLJIT::getProcessSymbolsJITDylib() { return ProcessSymbols; } + +JITDylibSP LLJIT::getPlatformJITDylib() { return Platform; } + +Expected LLJIT::createJITDylib(std::string Name) { + auto JD = ES->createJITDylib(std::move(Name)); + if (!JD) + return JD.takeError(); + + JD->addToLinkOrder(DefaultLinks); + return JD; +} + Expected LLJIT::loadPlatformDynamicLibrary(const char *Path) { auto G = EPCDynamicLibrarySearchGenerator::Load(*ES, Path); if (!G) @@ -893,13 +919,6 @@ 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()) @@ -947,10 +966,47 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) }); } - if (S.SetUpPlatform) - Err = S.SetUpPlatform(*this); - else - setUpGenericLLVMIRPlatform(*this); + 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(""); + 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; + } } std::string LLJIT::mangle(StringRef UnmangledName) const { @@ -976,24 +1032,136 @@ Error LLJIT::applyDataLayout(Module &M) { return Error::success(); } -Error setUpOrcPlatform(LLJIT& J) { - LLVM_DEBUG( - { dbgs() << "Setting up orc platform support for LLJIT\n"; }); - J.setPlatformSupport(std::make_unique(J)); +Error setUpOrcPlatformManually(LLJIT &J) { + LLVM_DEBUG({ dbgs() << "Setting up orc platform support for LLJIT\n"; }); + J.setPlatformSupport(std::make_unique(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("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); return Error::success(); + } + +private: + LLJIT &J; +}; + +Expected ExecutorNativePlatform::operator()(LLJIT &J) { + auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib(); + if (!ProcessSymbolsJD) + return make_error( + "Native platforms require a process symbols JITDylib", + inconvertibleErrorCode()); + + const Triple &TT = J.getTargetTriple(); + ObjectLinkingLayer *ObjLinkingLayer = + dyn_cast(&J.getObjLinkingLayer()); + + if (!ObjLinkingLayer) + return make_error( + "SetUpTargetPlatform requires ObjectLinkingLayer", + inconvertibleErrorCode()); + + std::unique_ptr 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(""); + PlatformJD.addToLinkOrder(*ProcessSymbolsJD); + + J.setPlatformSupport(std::make_unique(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("Unsupported object format in triple " + + TT.str(), + inconvertibleErrorCode()); + } + + return &PlatformJD; } -void setUpGenericLLVMIRPlatform(LLJIT &J) { +Expected setUpGenericLLVMIRPlatform(LLJIT &J) { LLVM_DEBUG( { dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; }); - J.setPlatformSupport(std::make_unique(J)); + auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib(); + if (!ProcessSymbolsJD) + return make_error( + "Native platforms require a process symbols JITDylib", + inconvertibleErrorCode()); + + auto &PlatformJD = J.getExecutionSession().createBareJITDylib(""); + PlatformJD.addToLinkOrder(*ProcessSymbolsJD); + + J.setPlatformSupport( + std::make_unique(J, PlatformJD)); + + return &PlatformJD; } -Error setUpInactivePlatform(LLJIT &J) { +Expected setUpInactivePlatform(LLJIT &J) { LLVM_DEBUG( { dbgs() << "Explicitly deactivated platform support for LLJIT\n"; }); J.setPlatformSupport(std::make_unique()); - return Error::success(); + return nullptr; } Error LLLazyJITBuilderState::prepareForConstruction() { diff --git a/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll b/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll index 51a5905feefa9..a70bc5f4ceb42 100644 --- a/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll +++ b/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll @@ -1,8 +1,8 @@ ; 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: | FileCheck %s +; RUN: not lli -no-process-syms -lljit-platform=Inactive -emulated-tls \ +; RUN: -jit-kind=orc-lazy %s 2>&1 | FileCheck %s ; ; Test that emulated-tls does not generate any unexpected errors. ; diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp index 464db8f99457a..368a8baca07da 100644 --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -27,7 +27,6 @@ #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" @@ -35,7 +34,6 @@ #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" @@ -236,20 +234,22 @@ namespace { cl::desc("Do not resolve lli process symbols in JIT'd code"), cl::init(false)); - enum class LLJITPlatform { Inactive, DetectHost, ORC, GenericIR }; - - cl::opt - 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 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, @@ -864,6 +864,9 @@ 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). @@ -905,17 +908,15 @@ int runOrcJIT(const char *ProgName) { // 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::ExecutorNativePlatform(OrcRuntime)); break; + } case LLJITPlatform::GenericIR: // Nothing to do: LLJITBuilder will use this by default. break; @@ -934,7 +935,7 @@ int runOrcJIT(const char *ProgName) { Builder.setObjectLinkingLayerCreator([&EPC, &P](orc::ExecutionSession &ES, const Triple &TT) { auto L = std::make_unique(ES, EPC->getMemMgr()); - if (P != LLJITPlatform::ORC) { + if (P != LLJITPlatform::ExecutorNative) { L->addPlugin(std::make_unique( ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES)))); L->addPlugin(std::make_unique( @@ -982,46 +983,12 @@ int runOrcJIT(const char *ProgName) { 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(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); - } } // Regular modules are greedy: They materialize as a whole and trigger