Skip to content

Commit 23973e0

Browse files
[lli] Add --jit-linker command line argument
The argument value determines the dynamic linker to use (`default`, `rtdyld` or `jitlink`). The JITLink implementation only supports in-process JITing for now. This is the first commit for the reviewed patch. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D97339
1 parent 7f086d7 commit 23973e0

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

llvm/tools/lli/lli.cpp

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Config/llvm-config.h"
2323
#include "llvm/ExecutionEngine/GenericValue.h"
2424
#include "llvm/ExecutionEngine/Interpreter.h"
25+
#include "llvm/ExecutionEngine/JITSymbol.h"
2526
#include "llvm/ExecutionEngine/JITEventListener.h"
2627
#include "llvm/ExecutionEngine/MCJIT.h"
2728
#include "llvm/ExecutionEngine/ObjectCache.h"
@@ -32,6 +33,9 @@
3233
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
3334
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
3435
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
36+
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
37+
#include "llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h"
38+
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
3539
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
3640
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
3741
#include "llvm/IR/IRBuilder.h"
@@ -78,6 +82,7 @@ static codegen::RegisterCodeGenFlags CGF;
7882
namespace {
7983

8084
enum class JITKind { MCJIT, OrcLazy };
85+
enum class JITLinkerKind { Default, RuntimeDyld, JITLink };
8186

8287
cl::opt<std::string>
8388
InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-"));
@@ -96,6 +101,16 @@ namespace {
96101
clEnumValN(JITKind::OrcLazy, "orc-lazy",
97102
"Orc-based lazy JIT.")));
98103

104+
cl::opt<JITLinkerKind>
105+
JITLinker("jit-linker", cl::desc("Choose the dynamic linker/loader."),
106+
cl::init(JITLinkerKind::Default),
107+
cl::values(clEnumValN(JITLinkerKind::Default, "default",
108+
"Default for platform and JIT-kind"),
109+
clEnumValN(JITLinkerKind::RuntimeDyld, "rtdyld",
110+
"RuntimeDyld"),
111+
clEnumValN(JITLinkerKind::JITLink, "jitlink",
112+
"Orc-specific linker")));
113+
99114
cl::opt<unsigned>
100115
LazyJITCompileThreads("compile-threads",
101116
cl::desc("Choose the number of compile threads "
@@ -260,6 +275,11 @@ namespace {
260275
ExitOnError ExitOnErr;
261276
}
262277

278+
LLVM_ATTRIBUTE_USED void linkComponents() {
279+
errs() << (void *)&llvm_orc_registerEHFrameSectionWrapper
280+
<< (void *)&llvm_orc_deregisterEHFrameSectionWrapper;
281+
}
282+
263283
//===----------------------------------------------------------------------===//
264284
// Object cache
265285
//
@@ -893,6 +913,20 @@ int runOrcLazyJIT(const char *ProgName) {
893913
}
894914
}
895915

916+
std::unique_ptr<orc::TargetProcessControl> TPC = nullptr;
917+
if (JITLinker == JITLinkerKind::JITLink) {
918+
TPC = ExitOnErr(orc::SelfTargetProcessControl::Create(
919+
std::make_shared<orc::SymbolStringPool>()));
920+
921+
Builder.setObjectLinkingLayerCreator([&TPC](orc::ExecutionSession &ES,
922+
const Triple &) {
923+
auto L = std::make_unique<orc::ObjectLinkingLayer>(ES, TPC->getMemMgr());
924+
L->addPlugin(std::make_unique<orc::EHFrameRegistrationPlugin>(
925+
ES, ExitOnErr(orc::TPCEHFrameRegistrar::Create(*TPC))));
926+
return L;
927+
});
928+
}
929+
896930
auto J = ExitOnErr(Builder.create());
897931

898932
auto *ObjLayer = &J->getObjLinkingLayer();
@@ -997,13 +1031,19 @@ int runOrcLazyJIT(const char *ProgName) {
9971031
AltEntryThreads.push_back(std::thread([EntryPoint]() { EntryPoint(); }));
9981032
}
9991033

1000-
// Run main.
1001-
auto MainSym = ExitOnErr(J->lookup("main"));
1034+
// Resolve and run the main function.
1035+
JITEvaluatedSymbol MainSym = ExitOnErr(J->lookup("main"));
1036+
int Result;
10021037

1003-
typedef int (*MainFnPtr)(int, char *[]);
1004-
auto Result = orc::runAsMain(
1005-
jitTargetAddressToFunction<MainFnPtr>(MainSym.getAddress()), InputArgv,
1006-
StringRef(InputFile));
1038+
if (TPC) {
1039+
// TargetProcessControl-based execution with JITLink.
1040+
Result = ExitOnErr(TPC->runAsMain(MainSym.getAddress(), InputArgv));
1041+
} else {
1042+
// Manual in-process execution with RuntimeDyld.
1043+
using MainFnTy = int(int, char *[]);
1044+
auto MainFn = jitTargetAddressToFunction<MainFnTy *>(MainSym.getAddress());
1045+
Result = orc::runAsMain(MainFn, InputArgv, StringRef(InputFile));
1046+
}
10071047

10081048
// Wait for -entry-point threads.
10091049
for (auto &AltEntryThread : AltEntryThreads)

0 commit comments

Comments
 (0)