Author: Lang Hames
Date: 2023-04-08T02:40:58Z
New Revision: 231107a8b5be77d1c76975b0363976ba3211fa37

URL: 
https://github.com/llvm/llvm-project/commit/231107a8b5be77d1c76975b0363976ba3211fa37
DIFF: 
https://github.com/llvm/llvm-project/commit/231107a8b5be77d1c76975b0363976ba3211fa37.diff

LOG: Re-apply "[ORC] LLJIT updates: ExecutorNativePlatform, default ..." with 
fixes.

This reapplies 371cb1af61d, which was reverted in 0b2240eda01 due to bot
failures.

The clang-repl test failure is fixed by dropping the process symbols definition
generator that was manually attached to the main JITDylib, since LLJIT now
exposes process symbols by default. (The bug was triggered when JIT'd code used
the process atexit provided by the generator, rather than the JIT atexit which
has been moved into the platform JITDylib).

Any LLJIT clients that see crashes in static destructors should likewise remove
any process symbol generators attached to their main JITDylib.

Added: 
    

Modified: 
    clang/lib/Interpreter/IncrementalExecutor.cpp
    llvm/examples/OrcV2Examples/CMakeLists.txt
    
llvm/examples/OrcV2Examples/LLJITWithExecutorProcessControl/LLJITWithExecutorProcessControl.cpp
    
llvm/examples/OrcV2Examples/LLJITWithGDBRegistrationListener/LLJITWithGDBRegistrationListener.cpp
    
llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin/LLJITWithObjectLinkingLayerPlugin.cpp
    llvm/include/llvm/ExecutionEngine/Orc/COFFPlatform.h
    llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
    llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp
    llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
    llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll
    llvm/tools/lli/lli.cpp

Removed: 
    
llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/CMakeLists.txt
    
llvm/examples/OrcV2Examples/OrcV2CBindingsReflectProcessSymbols/OrcV2CBindingsReflectProcessSymbols.c


################################################################################
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<LLVMContext>();

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 <assert.h>
-#include <stdio.h>
-
-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<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,
@@ -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<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);

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 <typename, typename, typename> friend class LLJITBuilderSetters;
 
-  friend void setUpGenericLLVMIRPlatform(LLJIT &J);
+  friend Expected<JITDylibSP> 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<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);
@@ -228,8 +245,12 @@ class LLJIT {
   std::unique_ptr<ExecutionSession> ES;
   std::unique_ptr<PlatformSupport> PS;
 
+  JITDylib *ProcessSymbols = nullptr;
+  JITDylib *Platform = nullptr;
   JITDylib *Main = nullptr;
 
+  JITDylibSearchOrder DefaultLinks;
+
   DataLayout DL;
   Triple TT;
   std::unique_ptr<ThreadPool> CompileThreads;
@@ -284,12 +305,17 @@ class LLJITBuilderState {
       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 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<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 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 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

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<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()))
@@ -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<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)
@@ -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<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));
 
@@ -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<SPSDLOpenSig>(
-          *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<SPSDLOpenSig>(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<SPSDLCloseSig>(
-          *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<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)
@@ -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("<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;
+  }
 }
 
 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<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());
+    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<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;
 }
 
-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() {

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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to