blob: 059fba23d570c6ce235a24f0dc2285d426b7e74a [file] [log] [blame]
Lang Hames6a941342018-06-26 21:35:48 +00001//===--------- 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
15namespace llvm {
16namespace orc {
17
18Expected<std::unique_ptr<LLJIT>>
19LLJIT::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
25Error 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
31Error 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
42Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V,
43 StringRef Name) {
44 return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name));
45}
46
47LLJIT::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
58std::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
66RTDyldObjectLinkingLayer2::Resources LLJIT::getRTDyldResources(VModuleKey K) {
67 return orc::RTDyldObjectLinkingLayer2::Resources(
68 {llvm::make_unique<SectionMemoryManager>(), takeSymbolResolver(K)});
69}
70
71std::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
80std::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
95Error 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
107void LLJIT::recordCtorDtors(Module &M) {
108 CtorRunner.add(getConstructors(M));
109 DtorRunner.add(getDestructors(M));
110}
111
112Expected<std::unique_ptr<LLLazyJIT>>
113LLLazyJIT::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
135Error 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
150LLLazyJIT::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
164void 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.