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>>
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 
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 
31 Error LLJIT::addIRModule(JITDylib &JD, 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(JD, K, std::move(M));
39 }
40 
41 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
42   assert(Obj && "Can not add null object");
43 
44   auto K = ES->allocateVModule();
45   return ObjLinkingLayer.add(JD, K, std::move(Obj));
46 }
47 
48 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
49                                                         StringRef Name) {
50   return llvm::orc::lookup({&JD}, ES->getSymbolStringPool().intern(Name));
51 }
52 
53 LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
54              std::unique_ptr<TargetMachine> TM, DataLayout DL)
55     : ES(std::move(ES)), Main(this->ES->createJITDylib("main")),
56       TM(std::move(TM)), DL(std::move(DL)),
57       ObjLinkingLayer(*this->ES,
58                       [this](VModuleKey K) { return getMemoryManager(K); }),
59       CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
60       CtorRunner(Main), DtorRunner(Main) {}
61 
62 std::shared_ptr<RuntimeDyld::MemoryManager>
63 LLJIT::getMemoryManager(VModuleKey K) {
64   return llvm::make_unique<SectionMemoryManager>();
65 }
66 
67 std::string LLJIT::mangle(StringRef UnmangledName) {
68   std::string MangledName;
69   {
70     raw_string_ostream MangledNameStream(MangledName);
71     Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
72   }
73   return MangledName;
74 }
75 
76 Error LLJIT::applyDataLayout(Module &M) {
77   if (M.getDataLayout().isDefault())
78     M.setDataLayout(DL);
79 
80   if (M.getDataLayout() != DL)
81     return make_error<StringError>(
82         "Added modules have incompatible data layouts",
83         inconvertibleErrorCode());
84 
85   return Error::success();
86 }
87 
88 void LLJIT::recordCtorDtors(Module &M) {
89   CtorRunner.add(getConstructors(M));
90   DtorRunner.add(getDestructors(M));
91 }
92 
93 Expected<std::unique_ptr<LLLazyJIT>>
94 LLLazyJIT::Create(std::unique_ptr<ExecutionSession> ES,
95                   std::unique_ptr<TargetMachine> TM, DataLayout DL,
96                   LLVMContext &Ctx) {
97   const Triple &TT = TM->getTargetTriple();
98 
99   auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0);
100   if (!CCMgr)
101     return make_error<StringError>(
102         std::string("No callback manager available for ") + TT.str(),
103         inconvertibleErrorCode());
104 
105   auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
106   if (!ISMBuilder)
107     return make_error<StringError>(
108         std::string("No indirect stubs manager builder for ") + TT.str(),
109         inconvertibleErrorCode());
110 
111   return std::unique_ptr<LLLazyJIT>(
112       new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL), Ctx,
113                     std::move(CCMgr), std::move(ISMBuilder)));
114 }
115 
116 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, std::unique_ptr<Module> M) {
117   assert(M && "Can not add null module");
118 
119   if (auto Err = applyDataLayout(*M))
120     return Err;
121 
122   makeAllSymbolsExternallyAccessible(*M);
123 
124   recordCtorDtors(*M);
125 
126   auto K = ES->allocateVModule();
127   return CODLayer.add(JD, K, std::move(M));
128 }
129 
130 LLLazyJIT::LLLazyJIT(
131     std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
132     DataLayout DL, LLVMContext &Ctx,
133     std::unique_ptr<JITCompileCallbackManager> CCMgr,
134     std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
135     : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
136       CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),
137       CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder),
138                [&]() -> LLVMContext & { return Ctx; }) {}
139 
140 } // End namespace orc.
141 } // End namespace llvm.
142