blob: ae8a66f614448e20b29eabe0d942f2182f94e693 [file] [log] [blame]
Lang Hames6a941342018-06-26 21:35:48 +00001//===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Lang Hames6a941342018-06-26 21:35:48 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ExecutionEngine/Orc/LLJIT.h"
10#include "llvm/ExecutionEngine/Orc/OrcError.h"
Lang Hameseb14dc72019-04-29 22:37:27 +000011#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
Lang Hames6a941342018-06-26 21:35:48 +000012#include "llvm/ExecutionEngine/SectionMemoryManager.h"
13#include "llvm/IR/Mangler.h"
14
Lang Hamesf0a3fd882018-09-26 16:26:59 +000015namespace {
16
17 // A SimpleCompiler that owns its TargetMachine.
18 class TMOwningSimpleCompiler : public llvm::orc::SimpleCompiler {
19 public:
20 TMOwningSimpleCompiler(std::unique_ptr<llvm::TargetMachine> TM)
21 : llvm::orc::SimpleCompiler(*TM), TM(std::move(TM)) {}
22 private:
23 // FIXME: shared because std::functions (and thus
Lang Hames079df9a2018-10-15 22:56:10 +000024 // IRCompileLayer::CompileFunction) are not moveable.
Lang Hamesf0a3fd882018-09-26 16:26:59 +000025 std::shared_ptr<llvm::TargetMachine> TM;
26 };
27
28} // end anonymous namespace
29
Lang Hames6a941342018-06-26 21:35:48 +000030namespace llvm {
31namespace orc {
32
Lang Hameseb14dc72019-04-29 22:37:27 +000033Error LLJITBuilderState::prepareForConstruction() {
34
35 if (!JTMB) {
36 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
37 JTMB = std::move(*JTMBOrErr);
38 else
39 return JTMBOrErr.takeError();
40 }
41
42 return Error::success();
43}
44
Lang Hamesf0a3fd882018-09-26 16:26:59 +000045LLJIT::~LLJIT() {
46 if (CompileThreads)
47 CompileThreads->wait();
48}
49
Lang Hames6a941342018-06-26 21:35:48 +000050Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
Lang Hames71d781c2018-09-30 23:18:24 +000051 auto InternedName = ES->intern(Name);
Lang Hames6a941342018-06-26 21:35:48 +000052 SymbolMap Symbols({{InternedName, Sym}});
53 return Main.define(absoluteSymbols(std::move(Symbols)));
54}
55
Lang Hames8d76c712018-09-26 01:24:12 +000056Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
57 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +000058
Lang Hames8d76c712018-09-26 01:24:12 +000059 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +000060 return Err;
61
Lang Hameseb14dc72019-04-29 22:37:27 +000062 return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +000063}
64
Lang Hames37a66412018-08-28 20:20:31 +000065Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
66 assert(Obj && "Can not add null object");
67
Lang Hameseb14dc72019-04-29 22:37:27 +000068 return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
Lang Hames37a66412018-08-28 20:20:31 +000069}
70
Lang Hamesd5f56c52018-08-17 21:18:18 +000071Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
Lang Hames6a941342018-06-26 21:35:48 +000072 StringRef Name) {
Lang Hames23cb2e72018-10-23 23:01:39 +000073 return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
Lang Hames6a941342018-06-26 21:35:48 +000074}
75
Lang Hameseb14dc72019-04-29 22:37:27 +000076std::unique_ptr<ObjectLayer>
77LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
Lang Hames6a941342018-06-26 21:35:48 +000078
Lang Hameseb14dc72019-04-29 22:37:27 +000079 // If the config state provided an ObjectLinkingLayer factory then use it.
80 if (S.CreateObjectLinkingLayer)
81 return S.CreateObjectLinkingLayer(ES);
Lang Hamesf0a3fd882018-09-26 16:26:59 +000082
Lang Hameseb14dc72019-04-29 22:37:27 +000083 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
84 // a new SectionMemoryManager for each object.
85 auto GetMemMgr = []() { return llvm::make_unique<SectionMemoryManager>(); };
86 return llvm::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
87}
Lang Hames8b813952018-09-27 21:13:07 +000088
Lang Hameseb14dc72019-04-29 22:37:27 +000089LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
90 : ES(S.ES ? std::move(S.ES) : llvm::make_unique<ExecutionSession>()),
91 Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main),
92 DtorRunner(Main) {
93
94 ErrorAsOutParameter _(&Err);
95
96 ObjLinkingLayer = createObjectLinkingLayer(S, *ES);
97
98 if (S.NumCompileThreads > 0) {
99
100 // Configure multi-threaded.
101
102 if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
103 DL = std::move(*DLOrErr);
104 else {
105 Err = DLOrErr.takeError();
106 return;
107 }
108
109 {
110 auto TmpCompileLayer = llvm::make_unique<IRCompileLayer>(
111 *ES, *ObjLinkingLayer, ConcurrentIRCompiler(std::move(*S.JTMB)));
112
113 TmpCompileLayer->setCloneToNewContextOnEmit(true);
114 CompileLayer = std::move(TmpCompileLayer);
115 }
116
117 CompileThreads = llvm::make_unique<ThreadPool>(S.NumCompileThreads);
118 ES->setDispatchMaterialization(
119 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
120 // FIXME: Switch to move capture once we have c++14.
121 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
122 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
123 CompileThreads->async(std::move(Work));
124 });
125 } else {
126
127 // Configure single-threaded.
128
129 auto TM = S.JTMB->createTargetMachine();
130 if (!TM) {
131 Err = TM.takeError();
132 return;
133 }
134
135 DL = (*TM)->createDataLayout();
136
137 CompileLayer = llvm::make_unique<IRCompileLayer>(
138 *ES, *ObjLinkingLayer, TMOwningSimpleCompiler(std::move(*TM)));
139 }
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000140}
141
Lang Hames6a941342018-06-26 21:35:48 +0000142std::string LLJIT::mangle(StringRef UnmangledName) {
143 std::string MangledName;
144 {
145 raw_string_ostream MangledNameStream(MangledName);
146 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
147 }
148 return MangledName;
149}
150
Lang Hames6a941342018-06-26 21:35:48 +0000151Error LLJIT::applyDataLayout(Module &M) {
152 if (M.getDataLayout().isDefault())
153 M.setDataLayout(DL);
154
155 if (M.getDataLayout() != DL)
156 return make_error<StringError>(
157 "Added modules have incompatible data layouts",
158 inconvertibleErrorCode());
159
160 return Error::success();
161}
162
163void LLJIT::recordCtorDtors(Module &M) {
164 CtorRunner.add(getConstructors(M));
165 DtorRunner.add(getDestructors(M));
166}
167
Lang Hameseb14dc72019-04-29 22:37:27 +0000168Error LLLazyJITBuilderState::prepareForConstruction() {
169 if (auto Err = LLJITBuilderState::prepareForConstruction())
170 return Err;
171 TT = JTMB->getTargetTriple();
172 return Error::success();
Lang Hames6a941342018-06-26 21:35:48 +0000173}
174
Lang Hames8d76c712018-09-26 01:24:12 +0000175Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
176 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +0000177
Lang Hames8d76c712018-09-26 01:24:12 +0000178 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +0000179 return Err;
180
Lang Hames8d76c712018-09-26 01:24:12 +0000181 recordCtorDtors(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000182
Lang Hameseb14dc72019-04-29 22:37:27 +0000183 return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +0000184}
185
Lang Hameseb14dc72019-04-29 22:37:27 +0000186LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
Lang Hames6a941342018-06-26 21:35:48 +0000187
Lang Hameseb14dc72019-04-29 22:37:27 +0000188 // If LLJIT construction failed then bail out.
189 if (Err)
190 return;
191
192 ErrorAsOutParameter _(&Err);
193
194 /// Take/Create the lazy-compile callthrough manager.
195 if (S.LCTMgr)
196 LCTMgr = std::move(S.LCTMgr);
197 else {
198 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
199 S.TT, *ES, S.LazyCompileFailureAddr))
200 LCTMgr = std::move(*LCTMgrOrErr);
201 else {
202 Err = LCTMgrOrErr.takeError();
203 return;
204 }
205 }
206
207 // Take/Create the indirect stubs manager builder.
208 auto ISMBuilder = std::move(S.ISMBuilder);
209
210 // If none was provided, try to build one.
211 if (!ISMBuilder)
212 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);
213
214 // No luck. Bail out.
215 if (!ISMBuilder) {
216 Err = make_error<StringError>("Could not construct "
217 "IndirectStubsManagerBuilder for target " +
218 S.TT.str(),
219 inconvertibleErrorCode());
220 return;
221 }
222
223 // Create the transform layer.
224 TransformLayer = llvm::make_unique<IRTransformLayer>(*ES, *CompileLayer);
225
226 // Create the COD layer.
227 CODLayer = llvm::make_unique<CompileOnDemandLayer>(
228 *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
229
230 if (S.NumCompileThreads > 0)
231 CODLayer->setCloneToNewContextOnEmit(true);
Lang Hames8b813952018-09-27 21:13:07 +0000232}
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000233
Lang Hames6a941342018-06-26 21:35:48 +0000234} // End namespace orc.
235} // End namespace llvm.