blob: 9432363239157897a737a12e2b163cc7431a5226 [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
15namespace llvm {
16namespace orc {
17
Lang Hameseb14dc72019-04-29 22:37:27 +000018Error LLJITBuilderState::prepareForConstruction() {
19
20 if (!JTMB) {
21 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
22 JTMB = std::move(*JTMBOrErr);
23 else
24 return JTMBOrErr.takeError();
25 }
26
27 return Error::success();
28}
29
Lang Hamesf0a3fd882018-09-26 16:26:59 +000030LLJIT::~LLJIT() {
31 if (CompileThreads)
32 CompileThreads->wait();
33}
34
Lang Hames6a941342018-06-26 21:35:48 +000035Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
Lang Hames71d781c2018-09-30 23:18:24 +000036 auto InternedName = ES->intern(Name);
Lang Hames6a941342018-06-26 21:35:48 +000037 SymbolMap Symbols({{InternedName, Sym}});
38 return Main.define(absoluteSymbols(std::move(Symbols)));
39}
40
Lang Hames8d76c712018-09-26 01:24:12 +000041Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
42 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +000043
Lang Hames809e9d12019-08-02 15:21:37 +000044 if (auto Err =
45 TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); }))
Lang Hames6a941342018-06-26 21:35:48 +000046 return Err;
47
Lang Hameseb14dc72019-04-29 22:37:27 +000048 return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +000049}
50
Lang Hames37a66412018-08-28 20:20:31 +000051Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
52 assert(Obj && "Can not add null object");
53
Lang Hameseb14dc72019-04-29 22:37:27 +000054 return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
Lang Hames37a66412018-08-28 20:20:31 +000055}
56
Lang Hamesd5f56c52018-08-17 21:18:18 +000057Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
Lang Hames6a941342018-06-26 21:35:48 +000058 StringRef Name) {
Lang Hames23cb2e72018-10-23 23:01:39 +000059 return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
Lang Hames6a941342018-06-26 21:35:48 +000060}
61
Lang Hameseb14dc72019-04-29 22:37:27 +000062std::unique_ptr<ObjectLayer>
63LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
Lang Hames6a941342018-06-26 21:35:48 +000064
Lang Hameseb14dc72019-04-29 22:37:27 +000065 // If the config state provided an ObjectLinkingLayer factory then use it.
66 if (S.CreateObjectLinkingLayer)
67 return S.CreateObjectLinkingLayer(ES);
Lang Hamesf0a3fd882018-09-26 16:26:59 +000068
Lang Hameseb14dc72019-04-29 22:37:27 +000069 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
70 // a new SectionMemoryManager for each object.
71 auto GetMemMgr = []() { return llvm::make_unique<SectionMemoryManager>(); };
72 return llvm::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
73}
Lang Hames8b813952018-09-27 21:13:07 +000074
Lang Hames843f1982019-07-10 17:24:24 +000075Expected<IRCompileLayer::CompileFunction>
76LLJIT::createCompileFunction(LLJITBuilderState &S,
77 JITTargetMachineBuilder JTMB) {
78
79 /// If there is a custom compile function creator set then use it.
80 if (S.CreateCompileFunction)
81 return S.CreateCompileFunction(std::move(JTMB));
82
83 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
84 // depending on the number of threads requested.
85 if (S.NumCompileThreads > 0)
86 return ConcurrentIRCompiler(std::move(JTMB));
87
88 auto TM = JTMB.createTargetMachine();
89 if (!TM)
90 return TM.takeError();
91
92 return TMOwningSimpleCompiler(std::move(*TM));
93}
94
Lang Hameseb14dc72019-04-29 22:37:27 +000095LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
96 : ES(S.ES ? std::move(S.ES) : llvm::make_unique<ExecutionSession>()),
97 Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main),
98 DtorRunner(Main) {
99
100 ErrorAsOutParameter _(&Err);
101
102 ObjLinkingLayer = createObjectLinkingLayer(S, *ES);
103
Lang Hames843f1982019-07-10 17:24:24 +0000104 if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
105 DL = std::move(*DLOrErr);
106 else {
107 Err = DLOrErr.takeError();
108 return;
109 }
Lang Hameseb14dc72019-04-29 22:37:27 +0000110
Lang Hames843f1982019-07-10 17:24:24 +0000111 {
112 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB));
113 if (!CompileFunction) {
114 Err = CompileFunction.takeError();
Lang Hameseb14dc72019-04-29 22:37:27 +0000115 return;
116 }
Lang Hames843f1982019-07-10 17:24:24 +0000117 CompileLayer = llvm::make_unique<IRCompileLayer>(
118 *ES, *ObjLinkingLayer, std::move(*CompileFunction));
119 }
Lang Hameseb14dc72019-04-29 22:37:27 +0000120
Lang Hames843f1982019-07-10 17:24:24 +0000121 if (S.NumCompileThreads > 0) {
122 CompileLayer->setCloneToNewContextOnEmit(true);
Lang Hameseb14dc72019-04-29 22:37:27 +0000123 CompileThreads = llvm::make_unique<ThreadPool>(S.NumCompileThreads);
124 ES->setDispatchMaterialization(
125 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
126 // FIXME: Switch to move capture once we have c++14.
127 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
128 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
129 CompileThreads->async(std::move(Work));
130 });
Lang Hameseb14dc72019-04-29 22:37:27 +0000131 }
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000132}
133
Lang Hames6a941342018-06-26 21:35:48 +0000134std::string LLJIT::mangle(StringRef UnmangledName) {
135 std::string MangledName;
136 {
137 raw_string_ostream MangledNameStream(MangledName);
138 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
139 }
140 return MangledName;
141}
142
Lang Hames6a941342018-06-26 21:35:48 +0000143Error LLJIT::applyDataLayout(Module &M) {
144 if (M.getDataLayout().isDefault())
145 M.setDataLayout(DL);
146
147 if (M.getDataLayout() != DL)
148 return make_error<StringError>(
149 "Added modules have incompatible data layouts",
150 inconvertibleErrorCode());
151
152 return Error::success();
153}
154
155void LLJIT::recordCtorDtors(Module &M) {
156 CtorRunner.add(getConstructors(M));
157 DtorRunner.add(getDestructors(M));
158}
159
Lang Hameseb14dc72019-04-29 22:37:27 +0000160Error LLLazyJITBuilderState::prepareForConstruction() {
161 if (auto Err = LLJITBuilderState::prepareForConstruction())
162 return Err;
163 TT = JTMB->getTargetTriple();
164 return Error::success();
Lang Hames6a941342018-06-26 21:35:48 +0000165}
166
Lang Hames8d76c712018-09-26 01:24:12 +0000167Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
168 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +0000169
Lang Hames809e9d12019-08-02 15:21:37 +0000170 if (auto Err = TSM.withModuleDo([&](Module &M) -> Error {
171 if (auto Err = applyDataLayout(M))
172 return Err;
Lang Hames6a941342018-06-26 21:35:48 +0000173
Lang Hames809e9d12019-08-02 15:21:37 +0000174 recordCtorDtors(M);
175 return Error::success();
176 }))
177 return Err;
Lang Hames6a941342018-06-26 21:35:48 +0000178
Lang Hameseb14dc72019-04-29 22:37:27 +0000179 return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +0000180}
181
Lang Hameseb14dc72019-04-29 22:37:27 +0000182LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
Lang Hames6a941342018-06-26 21:35:48 +0000183
Lang Hameseb14dc72019-04-29 22:37:27 +0000184 // If LLJIT construction failed then bail out.
185 if (Err)
186 return;
187
188 ErrorAsOutParameter _(&Err);
189
190 /// Take/Create the lazy-compile callthrough manager.
191 if (S.LCTMgr)
192 LCTMgr = std::move(S.LCTMgr);
193 else {
194 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
195 S.TT, *ES, S.LazyCompileFailureAddr))
196 LCTMgr = std::move(*LCTMgrOrErr);
197 else {
198 Err = LCTMgrOrErr.takeError();
199 return;
200 }
201 }
202
203 // Take/Create the indirect stubs manager builder.
204 auto ISMBuilder = std::move(S.ISMBuilder);
205
206 // If none was provided, try to build one.
207 if (!ISMBuilder)
208 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);
209
210 // No luck. Bail out.
211 if (!ISMBuilder) {
212 Err = make_error<StringError>("Could not construct "
213 "IndirectStubsManagerBuilder for target " +
214 S.TT.str(),
215 inconvertibleErrorCode());
216 return;
217 }
218
219 // Create the transform layer.
220 TransformLayer = llvm::make_unique<IRTransformLayer>(*ES, *CompileLayer);
221
222 // Create the COD layer.
223 CODLayer = llvm::make_unique<CompileOnDemandLayer>(
224 *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
225
226 if (S.NumCompileThreads > 0)
227 CODLayer->setCloneToNewContextOnEmit(true);
Lang Hames8b813952018-09-27 21:13:07 +0000228}
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000229
Lang Hames6a941342018-06-26 21:35:48 +0000230} // End namespace orc.
231} // End namespace llvm.