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(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   Resolvers[K] = createResolverFor(V);
39   return CompileLayer.add(V, K, std::move(M));
40 }
41 
42 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V,
43                                                         StringRef Name) {
44   return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name));
45 }
46 
47 LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
48              std::unique_ptr<TargetMachine> TM, DataLayout DL)
49     : ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)),
50       DL(std::move(DL)),
51       ObjLinkingLayer(*this->ES,
52                       [this](VModuleKey K) { return getRTDyldResources(K); }),
53       CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
54       CtorRunner(Main), DtorRunner(Main) {
55   VSOLookupOrder[&Main] = VSOList({&Main});
56 }
57 
58 std::shared_ptr<SymbolResolver> LLJIT::takeSymbolResolver(VModuleKey K) {
59   auto ResolverI = Resolvers.find(K);
60   assert(ResolverI != Resolvers.end() && "Missing resolver");
61   auto Resolver = std::move(ResolverI->second);
62   Resolvers.erase(ResolverI);
63   return Resolver;
64 }
65 
66 RTDyldObjectLinkingLayer2::Resources LLJIT::getRTDyldResources(VModuleKey K) {
67   return orc::RTDyldObjectLinkingLayer2::Resources(
68       {llvm::make_unique<SectionMemoryManager>(), takeSymbolResolver(K)});
69 }
70 
71 std::string LLJIT::mangle(StringRef UnmangledName) {
72   std::string MangledName;
73   {
74     raw_string_ostream MangledNameStream(MangledName);
75     Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
76   }
77   return MangledName;
78 }
79 
80 std::unique_ptr<SymbolResolver> LLJIT::createResolverFor(VSO &V) {
81   return createSymbolResolver(
82       [&](SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) {
83         return V.lookupFlags(Flags, Symbols);
84       },
85       [&, this](std::shared_ptr<AsynchronousSymbolQuery> Q,
86                 SymbolNameSet Symbols) {
87         assert(VSOLookupOrder.count(&V) && "No VSO lookup order for V");
88         SymbolNameSet Unresolved = std::move(Symbols);
89         for (auto *LV : VSOLookupOrder[&V])
90           Unresolved = LV->lookup(Q, std::move(Unresolved));
91         return Unresolved;
92       });
93 }
94 
95 Error LLJIT::applyDataLayout(Module &M) {
96   if (M.getDataLayout().isDefault())
97     M.setDataLayout(DL);
98 
99   if (M.getDataLayout() != DL)
100     return make_error<StringError>(
101         "Added modules have incompatible data layouts",
102         inconvertibleErrorCode());
103 
104   return Error::success();
105 }
106 
107 void LLJIT::recordCtorDtors(Module &M) {
108   CtorRunner.add(getConstructors(M));
109   DtorRunner.add(getDestructors(M));
110 }
111 
112 Expected<std::unique_ptr<LLLazyJIT>>
113 LLLazyJIT::Create(std::unique_ptr<ExecutionSession> ES,
114                   std::unique_ptr<TargetMachine> TM, DataLayout DL,
115                   LLVMContext &Ctx) {
116   const Triple &TT = TM->getTargetTriple();
117 
118   auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0);
119   if (!CCMgr)
120     return make_error<StringError>(
121         std::string("No callback manager available for ") + TT.str(),
122         inconvertibleErrorCode());
123 
124   auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
125   if (!ISMBuilder)
126     return make_error<StringError>(
127         std::string("No indirect stubs manager builder for ") + TT.str(),
128         inconvertibleErrorCode());
129 
130   return std::unique_ptr<LLLazyJIT>(
131       new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL), Ctx,
132                     std::move(CCMgr), std::move(ISMBuilder)));
133 }
134 
135 Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) {
136   assert(M && "Can not add null module");
137 
138   if (auto Err = applyDataLayout(*M))
139     return Err;
140 
141   makeAllSymbolsExternallyAccessible(*M);
142 
143   recordCtorDtors(*M);
144 
145   auto K = ES->allocateVModule();
146   setSymbolResolver(K, createResolverFor(V));
147   return CODLayer.add(V, K, std::move(M));
148 }
149 
150 LLLazyJIT::LLLazyJIT(
151     std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
152     DataLayout DL, LLVMContext &Ctx,
153     std::unique_ptr<JITCompileCallbackManager> CCMgr,
154     std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
155     : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
156       CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),
157       CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder),
158                [this](VModuleKey K) { return takeSymbolResolver(K); },
159                [this](VModuleKey K, std::shared_ptr<SymbolResolver> R) {
160                  setSymbolResolver(K, std::move(R));
161                },
162                [&]() -> LLVMContext & { return Ctx; }) {}
163 
164 void LLLazyJIT::setSymbolResolver(VModuleKey K,
165                                   std::shared_ptr<SymbolResolver> R) {
166   assert(!Resolvers.count(K) && "Resolver already present for VModule K");
167   Resolvers[K] = std::move(R);
168 }
169 
170 } // End namespace orc.
171 } // End namespace llvm.
172