1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
10 #include "llvm/ExecutionEngine/Orc/OrcError.h"
11 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
12 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
13 #include "llvm/IR/Mangler.h"
14 
15 namespace llvm {
16 namespace orc {
17 
18 Error 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 
30 LLJIT::~LLJIT() {
31   if (CompileThreads)
32     CompileThreads->wait();
33 }
34 
35 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
36   auto InternedName = ES->intern(Name);
37   SymbolMap Symbols({{InternedName, Sym}});
38   return Main.define(absoluteSymbols(std::move(Symbols)));
39 }
40 
41 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
42   assert(TSM && "Can not add null module");
43 
44   if (auto Err =
45           TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); }))
46     return Err;
47 
48   return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
49 }
50 
51 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
52   assert(Obj && "Can not add null object");
53 
54   return ObjTransformLayer.add(JD, std::move(Obj), ES->allocateVModule());
55 }
56 
57 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
58                                                         StringRef Name) {
59   return ES->lookup(
60       makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols),
61       ES->intern(Name));
62 }
63 
64 std::unique_ptr<ObjectLayer>
65 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
66 
67   // If the config state provided an ObjectLinkingLayer factory then use it.
68   if (S.CreateObjectLinkingLayer)
69     return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple());
70 
71   // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
72   // a new SectionMemoryManager for each object.
73   auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); };
74   auto ObjLinkingLayer =
75       std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
76 
77   if (S.JTMB->getTargetTriple().isOSBinFormatCOFF())
78     ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags(true);
79 
80   // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence
81   //        errors from some GCC / libstdc++ bots. Remove this conversion (i.e.
82   //        just return ObjLinkingLayer) once those bots are upgraded.
83   return std::unique_ptr<ObjectLayer>(std::move(ObjLinkingLayer));
84 }
85 
86 Expected<IRCompileLayer::CompileFunction>
87 LLJIT::createCompileFunction(LLJITBuilderState &S,
88                              JITTargetMachineBuilder JTMB) {
89 
90   /// If there is a custom compile function creator set then use it.
91   if (S.CreateCompileFunction)
92     return S.CreateCompileFunction(std::move(JTMB));
93 
94   // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
95   // depending on the number of threads requested.
96   if (S.NumCompileThreads > 0)
97     return ConcurrentIRCompiler(std::move(JTMB));
98 
99   auto TM = JTMB.createTargetMachine();
100   if (!TM)
101     return TM.takeError();
102 
103   return TMOwningSimpleCompiler(std::move(*TM));
104 }
105 
106 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
107     : ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()),
108       Main(this->ES->getMainJITDylib()), DL(""),
109       ObjLinkingLayer(createObjectLinkingLayer(S, *ES)),
110       ObjTransformLayer(*this->ES, *ObjLinkingLayer), CtorRunner(Main),
111       DtorRunner(Main) {
112 
113   ErrorAsOutParameter _(&Err);
114 
115   if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
116     DL = std::move(*DLOrErr);
117   else {
118     Err = DLOrErr.takeError();
119     return;
120   }
121 
122   {
123     auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB));
124     if (!CompileFunction) {
125       Err = CompileFunction.takeError();
126       return;
127     }
128     CompileLayer = std::make_unique<IRCompileLayer>(
129         *ES, ObjTransformLayer, std::move(*CompileFunction));
130   }
131 
132   if (S.NumCompileThreads > 0) {
133     CompileLayer->setCloneToNewContextOnEmit(true);
134     CompileThreads = std::make_unique<ThreadPool>(S.NumCompileThreads);
135     ES->setDispatchMaterialization(
136         [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
137           // FIXME: Switch to move capture once we have c++14.
138           auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
139           auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
140           CompileThreads->async(std::move(Work));
141         });
142   }
143 }
144 
145 std::string LLJIT::mangle(StringRef UnmangledName) {
146   std::string MangledName;
147   {
148     raw_string_ostream MangledNameStream(MangledName);
149     Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
150   }
151   return MangledName;
152 }
153 
154 Error LLJIT::applyDataLayout(Module &M) {
155   if (M.getDataLayout().isDefault())
156     M.setDataLayout(DL);
157 
158   if (M.getDataLayout() != DL)
159     return make_error<StringError>(
160         "Added modules have incompatible data layouts",
161         inconvertibleErrorCode());
162 
163   return Error::success();
164 }
165 
166 void LLJIT::recordCtorDtors(Module &M) {
167   CtorRunner.add(getConstructors(M));
168   DtorRunner.add(getDestructors(M));
169 }
170 
171 Error LLLazyJITBuilderState::prepareForConstruction() {
172   if (auto Err = LLJITBuilderState::prepareForConstruction())
173     return Err;
174   TT = JTMB->getTargetTriple();
175   return Error::success();
176 }
177 
178 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
179   assert(TSM && "Can not add null module");
180 
181   if (auto Err = TSM.withModuleDo([&](Module &M) -> Error {
182         if (auto Err = applyDataLayout(M))
183           return Err;
184 
185         recordCtorDtors(M);
186         return Error::success();
187       }))
188     return Err;
189 
190   return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
191 }
192 
193 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
194 
195   // If LLJIT construction failed then bail out.
196   if (Err)
197     return;
198 
199   ErrorAsOutParameter _(&Err);
200 
201   /// Take/Create the lazy-compile callthrough manager.
202   if (S.LCTMgr)
203     LCTMgr = std::move(S.LCTMgr);
204   else {
205     if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
206             S.TT, *ES, S.LazyCompileFailureAddr))
207       LCTMgr = std::move(*LCTMgrOrErr);
208     else {
209       Err = LCTMgrOrErr.takeError();
210       return;
211     }
212   }
213 
214   // Take/Create the indirect stubs manager builder.
215   auto ISMBuilder = std::move(S.ISMBuilder);
216 
217   // If none was provided, try to build one.
218   if (!ISMBuilder)
219     ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);
220 
221   // No luck. Bail out.
222   if (!ISMBuilder) {
223     Err = make_error<StringError>("Could not construct "
224                                   "IndirectStubsManagerBuilder for target " +
225                                       S.TT.str(),
226                                   inconvertibleErrorCode());
227     return;
228   }
229 
230   // Create the transform layer.
231   TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer);
232 
233   // Create the COD layer.
234   CODLayer = std::make_unique<CompileOnDemandLayer>(
235       *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
236 
237   if (S.NumCompileThreads > 0)
238     CODLayer->setCloneToNewContextOnEmit(true);
239 }
240 
241 } // End namespace orc.
242 } // End namespace llvm.
243