1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#ifndef JIT_H
#define JIT_H
#include <llvm/ExecutionEngine/JITSymbol.h>
#include <llvm/ExecutionEngine/Orc/CompileUtils.h>
#include <llvm/ExecutionEngine/Orc/Core.h>
#include <llvm/ExecutionEngine/Orc/ExecutionUtils.h>
#include <llvm/ExecutionEngine/Orc/ExecutorProcessControl.h>
#include <llvm/ExecutionEngine/Orc/IRCompileLayer.h>
#include <llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h>
#include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
#include <llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/LLVMContext.h>
namespace jit {
using llvm::cantFail;
using llvm::DataLayout;
using llvm::Expected;
using llvm::JITEvaluatedSymbol;
using llvm::JITSymbolFlags;
using llvm::SectionMemoryManager;
using llvm::StringRef;
using llvm::orc::ConcurrentIRCompiler;
// using llvm::orc::DynamicLibrarySearchGenerator;
using llvm::orc::ExecutionSession;
using llvm::orc::ExecutorAddr;
using llvm::orc::ExecutorSymbolDef;
using llvm::orc::IRCompileLayer;
using llvm::orc::JITDylib;
using llvm::orc::JITTargetMachineBuilder;
using llvm::orc::MangleAndInterner;
using llvm::orc::ResourceTrackerSP;
using llvm::orc::RTDyldObjectLinkingLayer;
using llvm::orc::SelfExecutorProcessControl;
using llvm::orc::ThreadSafeModule;
// Simple JIT engine based on the KaleidoscopeJIT.
// https://www.llvm.org/docs/tutorial/BuildingAJIT1.html
class Jit {
private:
std::unique_ptr<ExecutionSession> ES;
DataLayout DL;
MangleAndInterner Mangle;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer CompileLayer;
JITDylib& JD;
public:
Jit(std::unique_ptr<ExecutionSession> ES,
JITTargetMachineBuilder JTMB,
DataLayout DL)
: ES(std::move(ES)),
DL(std::move(DL)),
Mangle(*this->ES, this->DL),
ObjectLayer(*this->ES,
[]() { return std::make_unique<SectionMemoryManager>(); }),
CompileLayer(*this->ES,
ObjectLayer,
std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),
JD(this->ES->createBareJITDylib("main")) {
// https://www.llvm.org/docs/ORCv2.html#how-to-add-process-and-library-symbols-to-jitdylibs
// JD.addGenerator(
// cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
// DL.getGlobalPrefix())));
cantFail(JD.define(llvm::orc::absoluteSymbols(
{{Mangle("libc_puts"),
{ExecutorAddr::fromPtr(&puts), JITSymbolFlags::Exported}}})));
}
~Jit() {
if (auto Err = ES->endSession())
ES->reportError(std::move(Err));
}
static std::unique_ptr<Jit> Create() {
auto EPC = cantFail(SelfExecutorProcessControl::Create());
auto ES = std::make_unique<ExecutionSession>(std::move(EPC));
JITTargetMachineBuilder JTMB(
ES->getExecutorProcessControl().getTargetTriple());
auto DL = cantFail(JTMB.getDefaultDataLayoutForTarget());
return std::make_unique<Jit>(std::move(ES), std::move(JTMB), std::move(DL));
}
Expected<ResourceTrackerSP> addModule(ThreadSafeModule TSM) {
auto RT = JD.createResourceTracker();
if (auto E = CompileLayer.add(RT, std::move(TSM))) {
return E;
}
return RT;
}
Expected<ExecutorSymbolDef> lookup(StringRef Name) {
return ES->lookup({&JD}, Mangle(Name.str()));
}
};
} // namespace jit
#endif
|