[compiler-rt] 1aa71f8 - [ORC][ORC_RT] Integrate ORC platforms with LLJIT and lli
Peter S. Housel via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 9 22:48:51 PDT 2022
Author: Peter S. Housel
Date: 2022-06-09T22:47:58-07:00
New Revision: 1aa71f8679e439db651c06e8e68ef21e6deffa93
URL: https://github.com/llvm/llvm-project/commit/1aa71f8679e439db651c06e8e68ef21e6deffa93
DIFF: https://github.com/llvm/llvm-project/commit/1aa71f8679e439db651c06e8e68ef21e6deffa93.diff
LOG: [ORC][ORC_RT] Integrate ORC platforms with LLJIT and lli
This change enables integrating orc::LLJIT with the ORCv2
platforms (MachOPlatform and ELFNixPlatform) and the compiler-rt orc
runtime. Changes include:
- Adding SPS wrapper functions for the orc runtime's dlfcn emulation
functions, allowing initialization and deinitialization to be invoked
by LLJIT.
- Changing the LLJIT code generation default to add UseInitArray so
that .init_array constructors are generated for ELF platforms.
- Integrating the ORCv2 Platforms into lli, and adding a
PlatformSupport implementation to the LLJIT instance used by lli which
implements initialization and deinitialization by calling the new
wrapper functions in the runtime.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D126492
Added:
compiler-rt/lib/orc/dlfcn_wrapper.cpp
compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-ehframe.cpp
compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-initialize-deinitialize.ll
compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-ehframe.cpp
compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-initialize-deinitialize.ll
compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-ehframe.cpp
compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-initialize-deinitialize.ll
Modified:
compiler-rt/lib/orc/CMakeLists.txt
compiler-rt/test/orc/lit.cfg.py
llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
llvm/tools/lli/lli.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/orc/CMakeLists.txt b/compiler-rt/lib/orc/CMakeLists.txt
index 7375934c47ec..d2786acf3cfe 100644
--- a/compiler-rt/lib/orc/CMakeLists.txt
+++ b/compiler-rt/lib/orc/CMakeLists.txt
@@ -9,6 +9,7 @@ set(ORC_SOURCES
macho_platform.cpp
elfnix_platform.cpp
run_program_wrapper.cpp
+ dlfcn_wrapper.cpp
)
# Implementation files for all ORC architectures.
diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
new file mode 100644
index 000000000000..c513aae97bb3
--- /dev/null
+++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
@@ -0,0 +1,52 @@
+//===- dlfcn_wrapper.cpp --------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime support library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "adt.h"
+#include "common.h"
+#include "wrapper_function_utils.h"
+
+#include <vector>
+
+using namespace __orc_rt;
+
+extern "C" const char *__orc_rt_jit_dlerror();
+extern "C" void *__orc_rt_jit_dlopen(const char *path, int mode);
+extern "C" int __orc_rt_jit_dlclose(void *dso_handle);
+
+ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
+__orc_rt_jit_dlerror_wrapper(const char *ArgData, size_t ArgSize) {
+ return WrapperFunction<SPSString()>::handle(
+ ArgData, ArgSize,
+ []() { return std::string(__orc_rt_jit_dlerror()); })
+ .release();
+}
+
+ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
+__orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
+ return WrapperFunction<SPSExecutorAddr(SPSString, int32_t)>::handle(
+ ArgData, ArgSize,
+ [](const std::string &Path, int32_t mode) {
+ return ExecutorAddr::fromPtr(
+ __orc_rt_jit_dlopen(Path.c_str(), mode));
+ })
+ .release();
+}
+
+ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
+__orc_rt_jit_dlclose_wrapper(const char *ArgData, size_t ArgSize) {
+ return WrapperFunction<int32_t(SPSExecutorAddr)>::handle(
+ ArgData, ArgSize,
+ [](ExecutorAddr &DSOHandle) {
+ return __orc_rt_jit_dlclose(DSOHandle.toPtr<void *>());
+ })
+ .release();
+}
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-ehframe.cpp b/compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-ehframe.cpp
new file mode 100644
index 000000000000..b73ec2387028
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-ehframe.cpp
@@ -0,0 +1,15 @@
+// RUN: %clangxx -fPIC -emit-llvm -c -o %t %s
+// RUN: %lli_orc_jitlink -relocation-model=pic %t | FileCheck %s
+
+// CHECK: catch
+
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ try {
+ throw 0;
+ } catch (int X) {
+ puts("catch");
+ }
+ return 0;
+}
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-initialize-deinitialize.ll b/compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-initialize-deinitialize.ll
new file mode 100644
index 000000000000..e5b976423238
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/lljit-initialize-deinitialize.ll
@@ -0,0 +1,32 @@
+; RUN: %lli_orc_jitlink -relocation-model=pic %s | FileCheck %s
+
+; CHECK: constructor
+; CHECK-NEXT: main
+; CHECK-NEXT: destructor
+
+ at __dso_handle = external hidden global i8
+ at .str = private unnamed_addr constant [5 x i8] c"main\00", align 1
+ at .str.1 = private unnamed_addr constant [12 x i8] c"constructor\00", align 1
+ at .str.2 = private unnamed_addr constant [11 x i8] c"destructor\00", align 1
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @constructor, i8* null }]
+
+define dso_local void @destructor(i8* %0) {
+ %2 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0))
+ ret void
+}
+
+declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+
+; Function Attrs: nofree norecurse nounwind uwtable
+define dso_local i32 @main(i32 %0, i8** nocapture readnone %1) local_unnamed_addr #2 {
+ %3 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0))
+ ret i32 0
+}
+
+declare i32 @puts(i8* nocapture readonly)
+
+define internal void @constructor() {
+ %1 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #5
+ %2 = tail call i32 @__cxa_atexit(void (i8*)* @destructor, i8* null, i8* nonnull @__dso_handle) #5
+ ret void
+}
diff --git a/compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-ehframe.cpp b/compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-ehframe.cpp
new file mode 100644
index 000000000000..b73ec2387028
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-ehframe.cpp
@@ -0,0 +1,15 @@
+// RUN: %clangxx -fPIC -emit-llvm -c -o %t %s
+// RUN: %lli_orc_jitlink -relocation-model=pic %t | FileCheck %s
+
+// CHECK: catch
+
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ try {
+ throw 0;
+ } catch (int X) {
+ puts("catch");
+ }
+ return 0;
+}
diff --git a/compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-initialize-deinitialize.ll b/compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-initialize-deinitialize.ll
new file mode 100644
index 000000000000..34bfc10b9d89
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/FreeBSD/x86-64/lljit-initialize-deinitialize.ll
@@ -0,0 +1,32 @@
+; RUN: %lli_orc_jitlink %s | FileCheck %s
+
+; CHECK: constructor
+; CHECK-NEXT: main
+; CHECK-NEXT: destructor
+
+ at __dso_handle = external hidden global i8
+ at .str = private unnamed_addr constant [5 x i8] c"main\00", align 1
+ at .str.1 = private unnamed_addr constant [12 x i8] c"constructor\00", align 1
+ at .str.2 = private unnamed_addr constant [11 x i8] c"destructor\00", align 1
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @constructor, i8* null }]
+
+define dso_local void @destructor(i8* %0) {
+ %2 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0))
+ ret void
+}
+
+declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+
+; Function Attrs: nofree norecurse nounwind uwtable
+define dso_local i32 @main(i32 %0, i8** nocapture readnone %1) local_unnamed_addr #2 {
+ %3 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0))
+ ret i32 0
+}
+
+declare i32 @puts(i8* nocapture readonly)
+
+define internal void @constructor() {
+ %1 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #5
+ %2 = tail call i32 @__cxa_atexit(void (i8*)* @destructor, i8* null, i8* nonnull @__dso_handle) #5
+ ret void
+}
diff --git a/compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-ehframe.cpp b/compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-ehframe.cpp
new file mode 100644
index 000000000000..b73ec2387028
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-ehframe.cpp
@@ -0,0 +1,15 @@
+// RUN: %clangxx -fPIC -emit-llvm -c -o %t %s
+// RUN: %lli_orc_jitlink -relocation-model=pic %t | FileCheck %s
+
+// CHECK: catch
+
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ try {
+ throw 0;
+ } catch (int X) {
+ puts("catch");
+ }
+ return 0;
+}
diff --git a/compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-initialize-deinitialize.ll b/compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-initialize-deinitialize.ll
new file mode 100644
index 000000000000..34bfc10b9d89
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Linux/x86-64/lljit-initialize-deinitialize.ll
@@ -0,0 +1,32 @@
+; RUN: %lli_orc_jitlink %s | FileCheck %s
+
+; CHECK: constructor
+; CHECK-NEXT: main
+; CHECK-NEXT: destructor
+
+ at __dso_handle = external hidden global i8
+ at .str = private unnamed_addr constant [5 x i8] c"main\00", align 1
+ at .str.1 = private unnamed_addr constant [12 x i8] c"constructor\00", align 1
+ at .str.2 = private unnamed_addr constant [11 x i8] c"destructor\00", align 1
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @constructor, i8* null }]
+
+define dso_local void @destructor(i8* %0) {
+ %2 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0))
+ ret void
+}
+
+declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+
+; Function Attrs: nofree norecurse nounwind uwtable
+define dso_local i32 @main(i32 %0, i8** nocapture readnone %1) local_unnamed_addr #2 {
+ %3 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0))
+ ret i32 0
+}
+
+declare i32 @puts(i8* nocapture readonly)
+
+define internal void @constructor() {
+ %1 = tail call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #5
+ %2 = tail call i32 @__cxa_atexit(void (i8*)* @destructor, i8* null, i8* nonnull @__dso_handle) #5
+ ret void
+}
diff --git a/compiler-rt/test/orc/lit.cfg.py b/compiler-rt/test/orc/lit.cfg.py
index b2e97cefbf0e..78c653373be2 100644
--- a/compiler-rt/test/orc/lit.cfg.py
+++ b/compiler-rt/test/orc/lit.cfg.py
@@ -13,6 +13,7 @@ def build_invocation(compile_flags):
# Assume that llvm-jitlink is in the config.llvm_tools_dir.
llvm_jitlink = os.path.join(config.llvm_tools_dir, 'llvm-jitlink')
+lli = os.path.join(config.llvm_tools_dir, 'lli')
if config.host_os == 'Darwin':
orc_rt_path = '%s/libclang_rt.orc_osx.a' % config.compiler_rt_libdir
else:
@@ -30,9 +31,11 @@ def build_invocation(compile_flags):
build_invocation(config.cxx_mode_flags + [config.target_cflags])))
config.substitutions.append(
('%llvm_jitlink', (llvm_jitlink + ' -orc-runtime=' + orc_rt_path)))
+config.substitutions.append(
+ ('%lli_orc_jitlink', (lli + ' -jit-kind=orc -jit-linker=jitlink -orc-runtime=' + orc_rt_path)))
# Default test suffixes.
-config.suffixes = ['.c', '.cpp', '.S']
+config.suffixes = ['.c', '.cpp', '.S', '.ll']
# Exclude Inputs directories.
config.excludes = ['Inputs']
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h b/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
index 2cc8c29b2813..e6a63707653a 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
@@ -125,7 +125,7 @@ class JITTargetMachineBuilder {
/// Set TargetOptions.
///
/// Note: This operation will overwrite any previously configured options,
- /// including EmulatedTLS and ExplicitEmulatedTLS which
+ /// including EmulatedTLS, ExplicitEmulatedTLS, and UseInitArray which
/// the JITTargetMachineBuilder sets by default. Clients are responsible
/// for re-enabling these overwritten options.
JITTargetMachineBuilder &setOptions(TargetOptions Options) {
diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
index 0185a9d15de2..730e193ec41b 100644
--- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
@@ -263,6 +263,10 @@ ELFNixPlatform::standardRuntimeUtilityAliases() {
static const std::pair<const char *, const char *>
StandardRuntimeUtilityAliases[] = {
{"__orc_rt_run_program", "__orc_rt_elfnix_run_program"},
+ {"__orc_rt_jit_dlerror", "__orc_rt_elfnix_jit_dlerror"},
+ {"__orc_rt_jit_dlopen", "__orc_rt_elfnix_jit_dlopen"},
+ {"__orc_rt_jit_dlclose", "__orc_rt_elfnix_jit_dlclose"},
+ {"__orc_rt_jit_dlsym", "__orc_rt_elfnix_jit_dlsym"},
{"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}};
return ArrayRef<std::pair<const char *, const char *>>(
diff --git a/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp b/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
index 0fbf79b8a56d..c60f4b3b263c 100644
--- a/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
@@ -19,6 +19,7 @@ JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
: TT(std::move(TT)) {
Options.EmulatedTLS = true;
Options.ExplicitEmulatedTLS = true;
+ Options.UseInitArray = true;
}
Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index b2de83acc2e9..d5274b06a76f 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -302,6 +302,10 @@ MachOPlatform::standardRuntimeUtilityAliases() {
static const std::pair<const char *, const char *>
StandardRuntimeUtilityAliases[] = {
{"___orc_rt_run_program", "___orc_rt_macho_run_program"},
+ {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
+ {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
+ {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
+ {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
{"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
return ArrayRef<std::pair<const char *, const char *>>(
diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index e45088865bea..f2e3886bdf07 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -28,12 +28,15 @@
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
+#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
+#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
+#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
@@ -120,6 +123,9 @@ namespace {
"RuntimeDyld"),
clEnumValN(JITLinkerKind::JITLink, "jitlink",
"Orc-specific linker")));
+ cl::opt<std::string> OrcRuntime("orc-runtime",
+ cl::desc("Use ORC runtime from given path"),
+ cl::init(""));
cl::opt<unsigned>
LazyJITCompileThreads("compile-threads",
@@ -230,13 +236,15 @@ namespace {
cl::desc("Do not resolve lli process symbols in JIT'd code"),
cl::init(false));
- enum class LLJITPlatform { Inactive, DetectHost, GenericIR };
+ 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",
@@ -365,6 +373,53 @@ class LLIObjectCache : public ObjectCache {
}
};
+class ORCPlatformSupport : public orc::LLJIT::PlatformSupport {
+public:
+ ORCPlatformSupport(orc::LLJIT &J) : J(J) {}
+
+ Error initialize(orc::JITDylib &JD) override {
+ using llvm::orc::shared::SPSExecutorAddr;
+ using llvm::orc::shared::SPSString;
+ using SPSDLOpenSig = SPSExecutorAddr(SPSString, int32_t);
+ enum dlopen_mode : int32_t {
+ ORC_RT_RTLD_LAZY = 0x1,
+ ORC_RT_RTLD_NOW = 0x2,
+ ORC_RT_RTLD_LOCAL = 0x4,
+ 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));
+ } else
+ return WrapperAddr.takeError();
+ }
+
+ Error deinitialize(orc::JITDylib &JD) override {
+ using llvm::orc::shared::SPSExecutorAddr;
+ using SPSDLCloseSig = int32_t(SPSExecutorAddr);
+
+ if (auto WrapperAddr = J.lookup("__orc_rt_jit_dlclose_wrapper")) {
+ int32_t result;
+ auto E = J.getExecutionSession().callSPSWrapper<SPSDLCloseSig>(
+ *WrapperAddr, result, DSOHandles[&JD]);
+ if (E)
+ return E;
+ else if (result)
+ return make_error<StringError>("dlclose failed",
+ inconvertibleErrorCode());
+ DSOHandles.erase(&JD);
+ } else
+ return WrapperAddr.takeError();
+ return Error::success();
+ }
+
+private:
+ orc::LLJIT &J;
+ DenseMap<orc::JITDylib *, orc::ExecutorAddr> DSOHandles;
+};
+
// On Mingw and Cygwin, an external symbol named '__main' is called from the
// generated 'main' function to allow static initialization. To avoid linking
// problems with remote targets (because lli's remote target support does not
@@ -904,21 +959,29 @@ int runOrcJIT(const char *ProgName) {
}
// Set up LLJIT platform.
- {
- LLJITPlatform P = Platform;
- if (P == LLJITPlatform::DetectHost)
+ LLJITPlatform P = Platform;
+ if (P == LLJITPlatform::DetectHost) {
+ if (JITLinker == JITLinkerKind::JITLink && !OrcRuntime.empty() &&
+ (TT->isOSBinFormatMachO() || TT->isOSBinFormatELF()))
+ P = LLJITPlatform::ORC;
+ else
P = LLJITPlatform::GenericIR;
-
- switch (P) {
- case LLJITPlatform::GenericIR:
- // Nothing to do: LLJITBuilder will use this by default.
- break;
- case LLJITPlatform::Inactive:
- Builder.setPlatformSetUp(orc::setUpInactivePlatform);
- break;
- default:
- llvm_unreachable("Unrecognized platform value");
- }
+ }
+ switch (P) {
+ case LLJITPlatform::ORC:
+ Builder.setPlatformSetUp([](llvm::orc::LLJIT &J) -> llvm::Error {
+ J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));
+ return Error::success();
+ });
+ break;
+ case LLJITPlatform::GenericIR:
+ // Nothing to do: LLJITBuilder will use this by default.
+ break;
+ case LLJITPlatform::Inactive:
+ Builder.setPlatformSetUp(orc::setUpInactivePlatform);
+ break;
+ default:
+ llvm_unreachable("Unrecognized platform value");
}
std::unique_ptr<orc::ExecutorProcessControl> EPC = nullptr;
@@ -926,13 +989,15 @@ int runOrcJIT(const char *ProgName) {
EPC = ExitOnErr(orc::SelfExecutorProcessControl::Create(
std::make_shared<orc::SymbolStringPool>()));
- Builder.setObjectLinkingLayerCreator([&EPC](orc::ExecutionSession &ES,
- const Triple &) {
+ Builder.setObjectLinkingLayerCreator([&EPC, &P](orc::ExecutionSession &ES,
+ const Triple &TT) {
auto L = std::make_unique<orc::ObjectLinkingLayer>(ES, EPC->getMemMgr());
- L->addPlugin(std::make_unique<orc::EHFrameRegistrationPlugin>(
- ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES))));
- L->addPlugin(std::make_unique<orc::DebugObjectManagerPlugin>(
- ES, ExitOnErr(orc::createJITLoaderGDBRegistrar(ES))));
+ if (P != LLJITPlatform::ORC) {
+ L->addPlugin(std::make_unique<orc::EHFrameRegistrationPlugin>(
+ ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES))));
+ L->addPlugin(std::make_unique<orc::DebugObjectManagerPlugin>(
+ ES, ExitOnErr(orc::createJITLoaderGDBRegistrar(ES))));
+ }
return L;
});
}
@@ -979,6 +1044,31 @@ int runOrcJIT(const char *ProgName) {
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
// materialization for all required symbols recursively. Lazy modules go
// through partitioning and they replace outgoing calls with reexport stubs
More information about the llvm-commits
mailing list