1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
11 #include "llvm/ExecutionEngine/Orc/OrcError.h"
12 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
13 #include "llvm/IR/Mangler.h"
14
15 namespace llvm {
16 namespace orc {
17
18 Expected<std::unique_ptr<LLJIT>>
Create(std::unique_ptr<ExecutionSession> ES,std::unique_ptr<TargetMachine> TM,DataLayout DL)19 LLJIT::Create(std::unique_ptr<ExecutionSession> ES,
20 std::unique_ptr<TargetMachine> TM, DataLayout DL) {
21 return std::unique_ptr<LLJIT>(
22 new LLJIT(std::move(ES), std::move(TM), std::move(DL)));
23 }
24
defineAbsolute(StringRef Name,JITEvaluatedSymbol Sym)25 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
26 auto InternedName = ES->getSymbolStringPool().intern(Name);
27 SymbolMap Symbols({{InternedName, Sym}});
28 return Main.define(absoluteSymbols(std::move(Symbols)));
29 }
30
addIRModule(VSO & V,std::unique_ptr<Module> M)31 Error LLJIT::addIRModule(VSO &V, std::unique_ptr<Module> M) {
32 assert(M && "Can not add null module");
33
34 if (auto Err = applyDataLayout(*M))
35 return Err;
36
37 auto K = ES->allocateVModule();
38 return CompileLayer.add(V, K, std::move(M));
39 }
40
lookupLinkerMangled(VSO & V,StringRef Name)41 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V,
42 StringRef Name) {
43 return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name));
44 }
45
LLJIT(std::unique_ptr<ExecutionSession> ES,std::unique_ptr<TargetMachine> TM,DataLayout DL)46 LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
47 std::unique_ptr<TargetMachine> TM, DataLayout DL)
48 : ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)),
49 DL(std::move(DL)),
50 ObjLinkingLayer(*this->ES,
51 [this](VModuleKey K) { return getMemoryManager(K); }),
52 CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
53 CtorRunner(Main), DtorRunner(Main) {}
54
55 std::shared_ptr<RuntimeDyld::MemoryManager>
getMemoryManager(VModuleKey K)56 LLJIT::getMemoryManager(VModuleKey K) {
57 return llvm::make_unique<SectionMemoryManager>();
58 }
59
mangle(StringRef UnmangledName)60 std::string LLJIT::mangle(StringRef UnmangledName) {
61 std::string MangledName;
62 {
63 raw_string_ostream MangledNameStream(MangledName);
64 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
65 }
66 return MangledName;
67 }
68
applyDataLayout(Module & M)69 Error LLJIT::applyDataLayout(Module &M) {
70 if (M.getDataLayout().isDefault())
71 M.setDataLayout(DL);
72
73 if (M.getDataLayout() != DL)
74 return make_error<StringError>(
75 "Added modules have incompatible data layouts",
76 inconvertibleErrorCode());
77
78 return Error::success();
79 }
80
recordCtorDtors(Module & M)81 void LLJIT::recordCtorDtors(Module &M) {
82 CtorRunner.add(getConstructors(M));
83 DtorRunner.add(getDestructors(M));
84 }
85
86 Expected<std::unique_ptr<LLLazyJIT>>
Create(std::unique_ptr<ExecutionSession> ES,std::unique_ptr<TargetMachine> TM,DataLayout DL,LLVMContext & Ctx)87 LLLazyJIT::Create(std::unique_ptr<ExecutionSession> ES,
88 std::unique_ptr<TargetMachine> TM, DataLayout DL,
89 LLVMContext &Ctx) {
90 const Triple &TT = TM->getTargetTriple();
91
92 auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0);
93 if (!CCMgr)
94 return make_error<StringError>(
95 std::string("No callback manager available for ") + TT.str(),
96 inconvertibleErrorCode());
97
98 auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
99 if (!ISMBuilder)
100 return make_error<StringError>(
101 std::string("No indirect stubs manager builder for ") + TT.str(),
102 inconvertibleErrorCode());
103
104 return std::unique_ptr<LLLazyJIT>(
105 new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL), Ctx,
106 std::move(CCMgr), std::move(ISMBuilder)));
107 }
108
addLazyIRModule(VSO & V,std::unique_ptr<Module> M)109 Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) {
110 assert(M && "Can not add null module");
111
112 if (auto Err = applyDataLayout(*M))
113 return Err;
114
115 makeAllSymbolsExternallyAccessible(*M);
116
117 recordCtorDtors(*M);
118
119 auto K = ES->allocateVModule();
120 return CODLayer.add(V, K, std::move(M));
121 }
122
LLLazyJIT(std::unique_ptr<ExecutionSession> ES,std::unique_ptr<TargetMachine> TM,DataLayout DL,LLVMContext & Ctx,std::unique_ptr<JITCompileCallbackManager> CCMgr,std::function<std::unique_ptr<IndirectStubsManager> ()> ISMBuilder)123 LLLazyJIT::LLLazyJIT(
124 std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
125 DataLayout DL, LLVMContext &Ctx,
126 std::unique_ptr<JITCompileCallbackManager> CCMgr,
127 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
128 : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
129 CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),
130 CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder),
131 [&]() -> LLVMContext & { return Ctx; }) {}
132
133 } // End namespace orc.
134 } // End namespace llvm.
135