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/JITLink/EHFrameSupport.h"
11 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
12 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
13 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
14 #include "llvm/ExecutionEngine/Orc/OrcError.h"
15 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
16 #include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
17 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
18 #include "llvm/IR/GlobalVariable.h"
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/Support/DynamicLibrary.h"
23
24 #include <map>
25
26 #define DEBUG_TYPE "orc"
27
28 using namespace llvm;
29 using namespace llvm::orc;
30
31 namespace {
32
33 /// Adds helper function decls and wrapper functions that call the helper with
34 /// some additional prefix arguments.
35 ///
36 /// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix
37 /// args i32 4 and i16 12345, this function will add:
38 ///
39 /// declare i8 @bar(i32, i16, i8, i64)
40 ///
41 /// define i8 @foo(i8, i64) {
42 /// entry:
43 /// %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1)
44 /// ret i8 %2
45 /// }
46 ///
addHelperAndWrapper(Module & M,StringRef WrapperName,FunctionType * WrapperFnType,GlobalValue::VisibilityTypes WrapperVisibility,StringRef HelperName,ArrayRef<Value * > HelperPrefixArgs)47 Function *addHelperAndWrapper(Module &M, StringRef WrapperName,
48 FunctionType *WrapperFnType,
49 GlobalValue::VisibilityTypes WrapperVisibility,
50 StringRef HelperName,
51 ArrayRef<Value *> HelperPrefixArgs) {
52 std::vector<Type *> HelperArgTypes;
53 for (auto *Arg : HelperPrefixArgs)
54 HelperArgTypes.push_back(Arg->getType());
55 for (auto *T : WrapperFnType->params())
56 HelperArgTypes.push_back(T);
57 auto *HelperFnType =
58 FunctionType::get(WrapperFnType->getReturnType(), HelperArgTypes, false);
59 auto *HelperFn = Function::Create(HelperFnType, GlobalValue::ExternalLinkage,
60 HelperName, M);
61
62 auto *WrapperFn = Function::Create(
63 WrapperFnType, GlobalValue::ExternalLinkage, WrapperName, M);
64 WrapperFn->setVisibility(WrapperVisibility);
65
66 auto *EntryBlock = BasicBlock::Create(M.getContext(), "entry", WrapperFn);
67 IRBuilder<> IB(EntryBlock);
68
69 std::vector<Value *> HelperArgs;
70 for (auto *Arg : HelperPrefixArgs)
71 HelperArgs.push_back(Arg);
72 for (auto &Arg : WrapperFn->args())
73 HelperArgs.push_back(&Arg);
74 auto *HelperResult = IB.CreateCall(HelperFn, HelperArgs);
75 if (HelperFn->getReturnType()->isVoidTy())
76 IB.CreateRetVoid();
77 else
78 IB.CreateRet(HelperResult);
79
80 return WrapperFn;
81 }
82
83 class GenericLLVMIRPlatformSupport;
84
85 /// orc::Platform component of Generic LLVM IR Platform support.
86 /// Just forwards calls to the GenericLLVMIRPlatformSupport class below.
87 class GenericLLVMIRPlatform : public Platform {
88 public:
GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport & S)89 GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport &S) : S(S) {}
90 Error setupJITDylib(JITDylib &JD) override;
91 Error notifyAdding(ResourceTracker &RT,
92 const MaterializationUnit &MU) override;
notifyRemoving(ResourceTracker & RT)93 Error notifyRemoving(ResourceTracker &RT) override {
94 // Noop -- Nothing to do (yet).
95 return Error::success();
96 }
97
98 private:
99 GenericLLVMIRPlatformSupport &S;
100 };
101
102 /// This transform parses llvm.global_ctors to produce a single initialization
103 /// function for the module, records the function, then deletes
104 /// llvm.global_ctors.
105 class GlobalCtorDtorScraper {
106 public:
107
GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport & PS,StringRef InitFunctionPrefix)108 GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport &PS,
109 StringRef InitFunctionPrefix)
110 : PS(PS), InitFunctionPrefix(InitFunctionPrefix) {}
111 Expected<ThreadSafeModule> operator()(ThreadSafeModule TSM,
112 MaterializationResponsibility &R);
113
114 private:
115 GenericLLVMIRPlatformSupport &PS;
116 StringRef InitFunctionPrefix;
117 };
118
119 /// Generic IR Platform Support
120 ///
121 /// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with
122 /// specially named 'init' and 'deinit'. Injects definitions / interposes for
123 /// some runtime API, including __cxa_atexit, dlopen, and dlclose.
124 class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport {
125 public:
126 // GenericLLVMIRPlatform &P) : P(P) {
GenericLLVMIRPlatformSupport(LLJIT & J)127 GenericLLVMIRPlatformSupport(LLJIT &J)
128 : J(J), InitFunctionPrefix(J.mangle("__orc_init_func.")) {
129
130 getExecutionSession().setPlatform(
131 std::make_unique<GenericLLVMIRPlatform>(*this));
132
133 setInitTransform(J, GlobalCtorDtorScraper(*this, InitFunctionPrefix));
134
135 SymbolMap StdInterposes;
136
137 StdInterposes[J.mangleAndIntern("__lljit.platform_support_instance")] =
138 JITEvaluatedSymbol(pointerToJITTargetAddress(this),
139 JITSymbolFlags::Exported);
140 StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] =
141 JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper),
142 JITSymbolFlags());
143
144 cantFail(
145 J.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes))));
146 cantFail(setupJITDylib(J.getMainJITDylib()));
147 cantFail(J.addIRModule(J.getMainJITDylib(), createPlatformRuntimeModule()));
148 }
149
getExecutionSession()150 ExecutionSession &getExecutionSession() { return J.getExecutionSession(); }
151
152 /// Adds a module that defines the __dso_handle global.
setupJITDylib(JITDylib & JD)153 Error setupJITDylib(JITDylib &JD) {
154
155 // Add per-jitdylib standard interposes.
156 SymbolMap PerJDInterposes;
157 PerJDInterposes[J.mangleAndIntern("__lljit.run_atexits_helper")] =
158 JITEvaluatedSymbol(pointerToJITTargetAddress(runAtExitsHelper),
159 JITSymbolFlags());
160 cantFail(JD.define(absoluteSymbols(std::move(PerJDInterposes))));
161
162 auto Ctx = std::make_unique<LLVMContext>();
163 auto M = std::make_unique<Module>("__standard_lib", *Ctx);
164 M->setDataLayout(J.getDataLayout());
165
166 auto *Int64Ty = Type::getInt64Ty(*Ctx);
167 auto *DSOHandle = new GlobalVariable(
168 *M, Int64Ty, true, GlobalValue::ExternalLinkage,
169 ConstantInt::get(Int64Ty, reinterpret_cast<uintptr_t>(&JD)),
170 "__dso_handle");
171 DSOHandle->setVisibility(GlobalValue::DefaultVisibility);
172 DSOHandle->setInitializer(
173 ConstantInt::get(Int64Ty, pointerToJITTargetAddress(&JD)));
174
175 auto *GenericIRPlatformSupportTy =
176 StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport");
177
178 auto *PlatformInstanceDecl = new GlobalVariable(
179 *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage,
180 nullptr, "__lljit.platform_support_instance");
181
182 auto *VoidTy = Type::getVoidTy(*Ctx);
183 addHelperAndWrapper(
184 *M, "__lljit_run_atexits", FunctionType::get(VoidTy, {}, false),
185 GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper",
186 {PlatformInstanceDecl, DSOHandle});
187
188 return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx)));
189 }
190
notifyAdding(ResourceTracker & RT,const MaterializationUnit & MU)191 Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) {
192 auto &JD = RT.getJITDylib();
193 if (auto &InitSym = MU.getInitializerSymbol())
194 InitSymbols[&JD].add(InitSym, SymbolLookupFlags::WeaklyReferencedSymbol);
195 else {
196 // If there's no identified init symbol attached, but there is a symbol
197 // with the GenericIRPlatform::InitFunctionPrefix, then treat that as
198 // an init function. Add the symbol to both the InitSymbols map (which
199 // will trigger a lookup to materialize the module) and the InitFunctions
200 // map (which holds the names of the symbols to execute).
201 for (auto &KV : MU.getSymbols())
202 if ((*KV.first).startswith(InitFunctionPrefix)) {
203 InitSymbols[&JD].add(KV.first,
204 SymbolLookupFlags::WeaklyReferencedSymbol);
205 InitFunctions[&JD].add(KV.first);
206 }
207 }
208 return Error::success();
209 }
210
initialize(JITDylib & JD)211 Error initialize(JITDylib &JD) override {
212 LLVM_DEBUG({
213 dbgs() << "GenericLLVMIRPlatformSupport getting initializers to run\n";
214 });
215 if (auto Initializers = getInitializers(JD)) {
216 LLVM_DEBUG(
217 { dbgs() << "GenericLLVMIRPlatformSupport running initializers\n"; });
218 for (auto InitFnAddr : *Initializers) {
219 LLVM_DEBUG({
220 dbgs() << " Running init " << formatv("{0:x16}", InitFnAddr)
221 << "...\n";
222 });
223 auto *InitFn = jitTargetAddressToFunction<void (*)()>(InitFnAddr);
224 InitFn();
225 }
226 } else
227 return Initializers.takeError();
228 return Error::success();
229 }
230
deinitialize(JITDylib & JD)231 Error deinitialize(JITDylib &JD) override {
232 LLVM_DEBUG({
233 dbgs() << "GenericLLVMIRPlatformSupport getting deinitializers to run\n";
234 });
235 if (auto Deinitializers = getDeinitializers(JD)) {
236 LLVM_DEBUG({
237 dbgs() << "GenericLLVMIRPlatformSupport running deinitializers\n";
238 });
239 for (auto DeinitFnAddr : *Deinitializers) {
240 LLVM_DEBUG({
241 dbgs() << " Running init " << formatv("{0:x16}", DeinitFnAddr)
242 << "...\n";
243 });
244 auto *DeinitFn = jitTargetAddressToFunction<void (*)()>(DeinitFnAddr);
245 DeinitFn();
246 }
247 } else
248 return Deinitializers.takeError();
249
250 return Error::success();
251 }
252
registerInitFunc(JITDylib & JD,SymbolStringPtr InitName)253 void registerInitFunc(JITDylib &JD, SymbolStringPtr InitName) {
254 getExecutionSession().runSessionLocked([&]() {
255 InitFunctions[&JD].add(InitName);
256 });
257 }
258
259 private:
260
getInitializers(JITDylib & JD)261 Expected<std::vector<JITTargetAddress>> getInitializers(JITDylib &JD) {
262 if (auto Err = issueInitLookups(JD))
263 return std::move(Err);
264
265 DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols;
266 std::vector<JITDylibSP> DFSLinkOrder;
267
268 getExecutionSession().runSessionLocked([&]() {
269 DFSLinkOrder = JD.getDFSLinkOrder();
270
271 for (auto &NextJD : DFSLinkOrder) {
272 auto IFItr = InitFunctions.find(NextJD.get());
273 if (IFItr != InitFunctions.end()) {
274 LookupSymbols[NextJD.get()] = std::move(IFItr->second);
275 InitFunctions.erase(IFItr);
276 }
277 }
278 });
279
280 LLVM_DEBUG({
281 dbgs() << "JITDylib init order is [ ";
282 for (auto &JD : llvm::reverse(DFSLinkOrder))
283 dbgs() << "\"" << JD->getName() << "\" ";
284 dbgs() << "]\n";
285 dbgs() << "Looking up init functions:\n";
286 for (auto &KV : LookupSymbols)
287 dbgs() << " \"" << KV.first->getName() << "\": " << KV.second << "\n";
288 });
289
290 auto &ES = getExecutionSession();
291 auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols);
292
293 if (!LookupResult)
294 return LookupResult.takeError();
295
296 std::vector<JITTargetAddress> Initializers;
297 while (!DFSLinkOrder.empty()) {
298 auto &NextJD = *DFSLinkOrder.back();
299 DFSLinkOrder.pop_back();
300 auto InitsItr = LookupResult->find(&NextJD);
301 if (InitsItr == LookupResult->end())
302 continue;
303 for (auto &KV : InitsItr->second)
304 Initializers.push_back(KV.second.getAddress());
305 }
306
307 return Initializers;
308 }
309
getDeinitializers(JITDylib & JD)310 Expected<std::vector<JITTargetAddress>> getDeinitializers(JITDylib &JD) {
311 auto &ES = getExecutionSession();
312
313 auto LLJITRunAtExits = J.mangleAndIntern("__lljit_run_atexits");
314
315 DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols;
316 std::vector<JITDylibSP> DFSLinkOrder;
317
318 ES.runSessionLocked([&]() {
319 DFSLinkOrder = JD.getDFSLinkOrder();
320
321 for (auto &NextJD : DFSLinkOrder) {
322 auto &JDLookupSymbols = LookupSymbols[NextJD.get()];
323 auto DIFItr = DeInitFunctions.find(NextJD.get());
324 if (DIFItr != DeInitFunctions.end()) {
325 LookupSymbols[NextJD.get()] = std::move(DIFItr->second);
326 DeInitFunctions.erase(DIFItr);
327 }
328 JDLookupSymbols.add(LLJITRunAtExits,
329 SymbolLookupFlags::WeaklyReferencedSymbol);
330 }
331 });
332
333 LLVM_DEBUG({
334 dbgs() << "JITDylib deinit order is [ ";
335 for (auto &JD : DFSLinkOrder)
336 dbgs() << "\"" << JD->getName() << "\" ";
337 dbgs() << "]\n";
338 dbgs() << "Looking up deinit functions:\n";
339 for (auto &KV : LookupSymbols)
340 dbgs() << " \"" << KV.first->getName() << "\": " << KV.second << "\n";
341 });
342
343 auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols);
344
345 if (!LookupResult)
346 return LookupResult.takeError();
347
348 std::vector<JITTargetAddress> DeInitializers;
349 for (auto &NextJD : DFSLinkOrder) {
350 auto DeInitsItr = LookupResult->find(NextJD.get());
351 assert(DeInitsItr != LookupResult->end() &&
352 "Every JD should have at least __lljit_run_atexits");
353
354 auto RunAtExitsItr = DeInitsItr->second.find(LLJITRunAtExits);
355 if (RunAtExitsItr != DeInitsItr->second.end())
356 DeInitializers.push_back(RunAtExitsItr->second.getAddress());
357
358 for (auto &KV : DeInitsItr->second)
359 if (KV.first != LLJITRunAtExits)
360 DeInitializers.push_back(KV.second.getAddress());
361 }
362
363 return DeInitializers;
364 }
365
366 /// Issue lookups for all init symbols required to initialize JD (and any
367 /// JITDylibs that it depends on).
issueInitLookups(JITDylib & JD)368 Error issueInitLookups(JITDylib &JD) {
369 DenseMap<JITDylib *, SymbolLookupSet> RequiredInitSymbols;
370 std::vector<JITDylibSP> DFSLinkOrder;
371
372 getExecutionSession().runSessionLocked([&]() {
373 DFSLinkOrder = JD.getDFSLinkOrder();
374
375 for (auto &NextJD : DFSLinkOrder) {
376 auto ISItr = InitSymbols.find(NextJD.get());
377 if (ISItr != InitSymbols.end()) {
378 RequiredInitSymbols[NextJD.get()] = std::move(ISItr->second);
379 InitSymbols.erase(ISItr);
380 }
381 }
382 });
383
384 return Platform::lookupInitSymbols(getExecutionSession(),
385 RequiredInitSymbols)
386 .takeError();
387 }
388
registerAtExitHelper(void * Self,void (* F)(void *),void * Ctx,void * DSOHandle)389 static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx,
390 void *DSOHandle) {
391 LLVM_DEBUG({
392 dbgs() << "Registering atexit function " << (void *)F << " for JD "
393 << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
394 });
395 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit(
396 F, Ctx, DSOHandle);
397 }
398
runAtExitsHelper(void * Self,void * DSOHandle)399 static void runAtExitsHelper(void *Self, void *DSOHandle) {
400 LLVM_DEBUG({
401 dbgs() << "Running atexit functions for JD "
402 << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
403 });
404 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.runAtExits(
405 DSOHandle);
406 }
407
408 // Constructs an LLVM IR module containing platform runtime globals,
409 // functions, and interposes.
createPlatformRuntimeModule()410 ThreadSafeModule createPlatformRuntimeModule() {
411 auto Ctx = std::make_unique<LLVMContext>();
412 auto M = std::make_unique<Module>("__standard_lib", *Ctx);
413 M->setDataLayout(J.getDataLayout());
414
415 auto *GenericIRPlatformSupportTy =
416 StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport");
417
418 auto *PlatformInstanceDecl = new GlobalVariable(
419 *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage,
420 nullptr, "__lljit.platform_support_instance");
421
422 auto *Int8Ty = Type::getInt8Ty(*Ctx);
423 auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);
424 auto *VoidTy = Type::getVoidTy(*Ctx);
425 auto *BytePtrTy = PointerType::getUnqual(Int8Ty);
426 auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false);
427 auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy);
428
429 addHelperAndWrapper(
430 *M, "__cxa_atexit",
431 FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy},
432 false),
433 GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper",
434 {PlatformInstanceDecl});
435
436 return ThreadSafeModule(std::move(M), std::move(Ctx));
437 }
438
439 LLJIT &J;
440 std::string InitFunctionPrefix;
441 DenseMap<JITDylib *, SymbolLookupSet> InitSymbols;
442 DenseMap<JITDylib *, SymbolLookupSet> InitFunctions;
443 DenseMap<JITDylib *, SymbolLookupSet> DeInitFunctions;
444 ItaniumCXAAtExitSupport AtExitMgr;
445 };
446
setupJITDylib(JITDylib & JD)447 Error GenericLLVMIRPlatform::setupJITDylib(JITDylib &JD) {
448 return S.setupJITDylib(JD);
449 }
450
notifyAdding(ResourceTracker & RT,const MaterializationUnit & MU)451 Error GenericLLVMIRPlatform::notifyAdding(ResourceTracker &RT,
452 const MaterializationUnit &MU) {
453 return S.notifyAdding(RT, MU);
454 }
455
456 Expected<ThreadSafeModule>
operator ()(ThreadSafeModule TSM,MaterializationResponsibility & R)457 GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM,
458 MaterializationResponsibility &R) {
459 auto Err = TSM.withModuleDo([&](Module &M) -> Error {
460 auto &Ctx = M.getContext();
461 auto *GlobalCtors = M.getNamedGlobal("llvm.global_ctors");
462
463 // If there's no llvm.global_ctors or it's just a decl then skip.
464 if (!GlobalCtors || GlobalCtors->isDeclaration())
465 return Error::success();
466
467 std::string InitFunctionName;
468 raw_string_ostream(InitFunctionName)
469 << InitFunctionPrefix << M.getModuleIdentifier();
470
471 MangleAndInterner Mangle(PS.getExecutionSession(), M.getDataLayout());
472 auto InternedName = Mangle(InitFunctionName);
473 if (auto Err =
474 R.defineMaterializing({{InternedName, JITSymbolFlags::Callable}}))
475 return Err;
476
477 auto *InitFunc =
478 Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {}, false),
479 GlobalValue::ExternalLinkage, InitFunctionName, &M);
480 InitFunc->setVisibility(GlobalValue::HiddenVisibility);
481 std::vector<std::pair<Function *, unsigned>> Inits;
482 for (auto E : getConstructors(M))
483 Inits.push_back(std::make_pair(E.Func, E.Priority));
484 llvm::sort(Inits, [](const std::pair<Function *, unsigned> &LHS,
485 const std::pair<Function *, unsigned> &RHS) {
486 return LHS.first < RHS.first;
487 });
488 auto *EntryBlock = BasicBlock::Create(Ctx, "entry", InitFunc);
489 IRBuilder<> IB(EntryBlock);
490 for (auto &KV : Inits)
491 IB.CreateCall(KV.first);
492 IB.CreateRetVoid();
493
494 PS.registerInitFunc(R.getTargetJITDylib(), InternedName);
495 GlobalCtors->eraseFromParent();
496 return Error::success();
497 });
498
499 if (Err)
500 return std::move(Err);
501
502 return std::move(TSM);
503 }
504
505 class MachOPlatformSupport : public LLJIT::PlatformSupport {
506 public:
507 using DLOpenType = void *(*)(const char *Name, int Mode);
508 using DLCloseType = int (*)(void *Handle);
509 using DLSymType = void *(*)(void *Handle, const char *Name);
510 using DLErrorType = const char *(*)();
511
512 struct DlFcnValues {
513 Optional<void *> RTLDDefault;
514 DLOpenType dlopen = nullptr;
515 DLCloseType dlclose = nullptr;
516 DLSymType dlsym = nullptr;
517 DLErrorType dlerror = nullptr;
518 };
519
520 static Expected<std::unique_ptr<MachOPlatformSupport>>
Create(LLJIT & J,JITDylib & PlatformJITDylib)521 Create(LLJIT &J, JITDylib &PlatformJITDylib) {
522
523 // Make process symbols visible.
524 {
525 std::string ErrMsg;
526 auto Lib = sys::DynamicLibrary::getPermanentLibrary(nullptr, &ErrMsg);
527 if (!Lib.isValid())
528 return make_error<StringError>(std::move(ErrMsg),
529 inconvertibleErrorCode());
530 }
531
532 DlFcnValues DlFcn;
533
534 // Add support for RTLDDefault on known platforms.
535 #ifdef __APPLE__
536 DlFcn.RTLDDefault = reinterpret_cast<void *>(-2);
537 #endif // __APPLE__
538
539 if (auto Err = hookUpFunction(DlFcn.dlopen, "dlopen"))
540 return std::move(Err);
541 if (auto Err = hookUpFunction(DlFcn.dlclose, "dlclose"))
542 return std::move(Err);
543 if (auto Err = hookUpFunction(DlFcn.dlsym, "dlsym"))
544 return std::move(Err);
545 if (auto Err = hookUpFunction(DlFcn.dlerror, "dlerror"))
546 return std::move(Err);
547
548 std::unique_ptr<MachOPlatformSupport> MP(
549 new MachOPlatformSupport(J, PlatformJITDylib, DlFcn));
550 return std::move(MP);
551 }
552
initialize(JITDylib & JD)553 Error initialize(JITDylib &JD) override {
554 LLVM_DEBUG({
555 dbgs() << "MachOPlatformSupport initializing \"" << JD.getName()
556 << "\"\n";
557 });
558
559 auto InitSeq = MP.getInitializerSequence(JD);
560 if (!InitSeq)
561 return InitSeq.takeError();
562
563 // If ObjC is not enabled but there are JIT'd ObjC inits then return
564 // an error.
565 if (!objCRegistrationEnabled())
566 for (auto &KV : *InitSeq) {
567 if (!KV.second.getObjCSelRefsSections().empty() ||
568 !KV.second.getObjCClassListSections().empty())
569 return make_error<StringError>("JITDylib " + KV.first->getName() +
570 " contains objc metadata but objc"
571 " is not enabled",
572 inconvertibleErrorCode());
573 }
574
575 // Run the initializers.
576 for (auto &KV : *InitSeq) {
577 if (objCRegistrationEnabled()) {
578 KV.second.registerObjCSelectors();
579 if (auto Err = KV.second.registerObjCClasses()) {
580 // FIXME: Roll back registrations on error?
581 return Err;
582 }
583 }
584 KV.second.runModInits();
585 }
586
587 return Error::success();
588 }
589
deinitialize(JITDylib & JD)590 Error deinitialize(JITDylib &JD) override {
591 auto &ES = J.getExecutionSession();
592 if (auto DeinitSeq = MP.getDeinitializerSequence(JD)) {
593 for (auto &KV : *DeinitSeq) {
594 auto DSOHandleName = ES.intern("___dso_handle");
595
596 // FIXME: Run DeInits here.
597 auto Result = ES.lookup(
598 {{KV.first, JITDylibLookupFlags::MatchAllSymbols}},
599 SymbolLookupSet(DSOHandleName,
600 SymbolLookupFlags::WeaklyReferencedSymbol));
601 if (!Result)
602 return Result.takeError();
603 if (Result->empty())
604 continue;
605 assert(Result->count(DSOHandleName) &&
606 "Result does not contain __dso_handle");
607 auto *DSOHandle = jitTargetAddressToPointer<void *>(
608 Result->begin()->second.getAddress());
609 AtExitMgr.runAtExits(DSOHandle);
610 }
611 } else
612 return DeinitSeq.takeError();
613 return Error::success();
614 }
615
616 private:
617 template <typename FunctionPtrTy>
hookUpFunction(FunctionPtrTy & Fn,const char * Name)618 static Error hookUpFunction(FunctionPtrTy &Fn, const char *Name) {
619 if (auto *FnAddr = sys::DynamicLibrary::SearchForAddressOfSymbol(Name)) {
620 Fn = reinterpret_cast<FunctionPtrTy>(Fn);
621 return Error::success();
622 }
623
624 return make_error<StringError>((Twine("Can not enable MachO JIT Platform: "
625 "missing function: ") +
626 Name)
627 .str(),
628 inconvertibleErrorCode());
629 }
630
MachOPlatformSupport(LLJIT & J,JITDylib & PlatformJITDylib,DlFcnValues DlFcn)631 MachOPlatformSupport(LLJIT &J, JITDylib &PlatformJITDylib, DlFcnValues DlFcn)
632 : J(J), MP(setupPlatform(J)), DlFcn(std::move(DlFcn)) {
633
634 SymbolMap HelperSymbols;
635
636 // platform and atexit helpers.
637 HelperSymbols[J.mangleAndIntern("__lljit.platform_support_instance")] =
638 JITEvaluatedSymbol(pointerToJITTargetAddress(this), JITSymbolFlags());
639 HelperSymbols[J.mangleAndIntern("__lljit.cxa_atexit_helper")] =
640 JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper),
641 JITSymbolFlags());
642 HelperSymbols[J.mangleAndIntern("__lljit.run_atexits_helper")] =
643 JITEvaluatedSymbol(pointerToJITTargetAddress(runAtExitsHelper),
644 JITSymbolFlags());
645
646 // dlfcn helpers.
647 HelperSymbols[J.mangleAndIntern("__lljit.dlopen_helper")] =
648 JITEvaluatedSymbol(pointerToJITTargetAddress(dlopenHelper),
649 JITSymbolFlags());
650 HelperSymbols[J.mangleAndIntern("__lljit.dlclose_helper")] =
651 JITEvaluatedSymbol(pointerToJITTargetAddress(dlcloseHelper),
652 JITSymbolFlags());
653 HelperSymbols[J.mangleAndIntern("__lljit.dlsym_helper")] =
654 JITEvaluatedSymbol(pointerToJITTargetAddress(dlsymHelper),
655 JITSymbolFlags());
656 HelperSymbols[J.mangleAndIntern("__lljit.dlerror_helper")] =
657 JITEvaluatedSymbol(pointerToJITTargetAddress(dlerrorHelper),
658 JITSymbolFlags());
659
660 cantFail(
661 PlatformJITDylib.define(absoluteSymbols(std::move(HelperSymbols))));
662 cantFail(MP.setupJITDylib(J.getMainJITDylib()));
663 cantFail(J.addIRModule(PlatformJITDylib, createPlatformRuntimeModule()));
664 }
665
setupPlatform(LLJIT & J)666 static MachOPlatform &setupPlatform(LLJIT &J) {
667 auto Tmp = std::make_unique<MachOPlatform>(
668 J.getExecutionSession(),
669 static_cast<ObjectLinkingLayer &>(J.getObjLinkingLayer()),
670 createStandardSymbolsObject(J));
671 auto &MP = *Tmp;
672 J.getExecutionSession().setPlatform(std::move(Tmp));
673 return MP;
674 }
675
createStandardSymbolsObject(LLJIT & J)676 static std::unique_ptr<MemoryBuffer> createStandardSymbolsObject(LLJIT &J) {
677 LLVMContext Ctx;
678 Module M("__standard_symbols", Ctx);
679 M.setDataLayout(J.getDataLayout());
680
681 auto *Int64Ty = Type::getInt64Ty(Ctx);
682
683 auto *DSOHandle =
684 new GlobalVariable(M, Int64Ty, true, GlobalValue::ExternalLinkage,
685 ConstantInt::get(Int64Ty, 0), "__dso_handle");
686 DSOHandle->setVisibility(GlobalValue::DefaultVisibility);
687
688 return cantFail(J.getIRCompileLayer().getCompiler()(M));
689 }
690
createPlatformRuntimeModule()691 ThreadSafeModule createPlatformRuntimeModule() {
692 auto Ctx = std::make_unique<LLVMContext>();
693 auto M = std::make_unique<Module>("__standard_lib", *Ctx);
694 M->setDataLayout(J.getDataLayout());
695
696 auto *MachOPlatformSupportTy =
697 StructType::create(*Ctx, "lljit.MachOPlatformSupport");
698
699 auto *PlatformInstanceDecl = new GlobalVariable(
700 *M, MachOPlatformSupportTy, true, GlobalValue::ExternalLinkage, nullptr,
701 "__lljit.platform_support_instance");
702
703 auto *Int8Ty = Type::getInt8Ty(*Ctx);
704 auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);
705 auto *VoidTy = Type::getVoidTy(*Ctx);
706 auto *BytePtrTy = PointerType::getUnqual(Int8Ty);
707 auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false);
708 auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy);
709
710 addHelperAndWrapper(
711 *M, "__cxa_atexit",
712 FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy},
713 false),
714 GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper",
715 {PlatformInstanceDecl});
716
717 addHelperAndWrapper(*M, "dlopen",
718 FunctionType::get(BytePtrTy, {BytePtrTy, IntTy}, false),
719 GlobalValue::DefaultVisibility, "__lljit.dlopen_helper",
720 {PlatformInstanceDecl});
721
722 addHelperAndWrapper(*M, "dlclose",
723 FunctionType::get(IntTy, {BytePtrTy}, false),
724 GlobalValue::DefaultVisibility,
725 "__lljit.dlclose_helper", {PlatformInstanceDecl});
726
727 addHelperAndWrapper(
728 *M, "dlsym",
729 FunctionType::get(BytePtrTy, {BytePtrTy, BytePtrTy}, false),
730 GlobalValue::DefaultVisibility, "__lljit.dlsym_helper",
731 {PlatformInstanceDecl});
732
733 addHelperAndWrapper(*M, "dlerror", FunctionType::get(BytePtrTy, {}, false),
734 GlobalValue::DefaultVisibility,
735 "__lljit.dlerror_helper", {PlatformInstanceDecl});
736
737 return ThreadSafeModule(std::move(M), std::move(Ctx));
738 }
739
registerAtExitHelper(void * Self,void (* F)(void *),void * Ctx,void * DSOHandle)740 static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx,
741 void *DSOHandle) {
742 static_cast<MachOPlatformSupport *>(Self)->AtExitMgr.registerAtExit(
743 F, Ctx, DSOHandle);
744 }
745
runAtExitsHelper(void * Self,void * DSOHandle)746 static void runAtExitsHelper(void *Self, void *DSOHandle) {
747 static_cast<MachOPlatformSupport *>(Self)->AtExitMgr.runAtExits(DSOHandle);
748 }
749
jit_dlopen(const char * Path,int Mode)750 void *jit_dlopen(const char *Path, int Mode) {
751 JITDylib *JDToOpen = nullptr;
752 // FIXME: Do the right thing with Mode flags.
753 {
754 std::lock_guard<std::mutex> Lock(PlatformSupportMutex);
755
756 // Clear any existing error messages.
757 dlErrorMsgs.erase(std::this_thread::get_id());
758
759 if (auto *JD = J.getExecutionSession().getJITDylibByName(Path)) {
760 auto I = JDRefCounts.find(JD);
761 if (I != JDRefCounts.end()) {
762 ++I->second;
763 return JD;
764 }
765
766 JDRefCounts[JD] = 1;
767 JDToOpen = JD;
768 }
769 }
770
771 if (JDToOpen) {
772 if (auto Err = initialize(*JDToOpen)) {
773 recordError(std::move(Err));
774 return 0;
775 }
776 }
777
778 // Fall through to dlopen if no JITDylib found for Path.
779 return DlFcn.dlopen(Path, Mode);
780 }
781
dlopenHelper(void * Self,const char * Path,int Mode)782 static void *dlopenHelper(void *Self, const char *Path, int Mode) {
783 return static_cast<MachOPlatformSupport *>(Self)->jit_dlopen(Path, Mode);
784 }
785
jit_dlclose(void * Handle)786 int jit_dlclose(void *Handle) {
787 JITDylib *JDToClose = nullptr;
788
789 {
790 std::lock_guard<std::mutex> Lock(PlatformSupportMutex);
791
792 // Clear any existing error messages.
793 dlErrorMsgs.erase(std::this_thread::get_id());
794
795 auto I = JDRefCounts.find(Handle);
796 if (I != JDRefCounts.end()) {
797 --I->second;
798 if (I->second == 0) {
799 JDRefCounts.erase(I);
800 JDToClose = static_cast<JITDylib *>(Handle);
801 } else
802 return 0;
803 }
804 }
805
806 if (JDToClose) {
807 if (auto Err = deinitialize(*JDToClose)) {
808 recordError(std::move(Err));
809 return -1;
810 }
811 return 0;
812 }
813
814 // Fall through to dlclose if no JITDylib found for Path.
815 return DlFcn.dlclose(Handle);
816 }
817
dlcloseHelper(void * Self,void * Handle)818 static int dlcloseHelper(void *Self, void *Handle) {
819 return static_cast<MachOPlatformSupport *>(Self)->jit_dlclose(Handle);
820 }
821
jit_dlsym(void * Handle,const char * Name)822 void *jit_dlsym(void *Handle, const char *Name) {
823 JITDylibSearchOrder JITSymSearchOrder;
824
825 // FIXME: RTLD_NEXT, RTLD_SELF not supported.
826 {
827 std::lock_guard<std::mutex> Lock(PlatformSupportMutex);
828
829 // Clear any existing error messages.
830 dlErrorMsgs.erase(std::this_thread::get_id());
831
832 if (JDRefCounts.count(Handle)) {
833 JITSymSearchOrder.push_back(
834 {static_cast<JITDylib *>(Handle),
835 JITDylibLookupFlags::MatchExportedSymbolsOnly});
836 } else if (Handle == DlFcn.RTLDDefault) {
837 for (auto &KV : JDRefCounts)
838 JITSymSearchOrder.push_back(
839 {static_cast<JITDylib *>(KV.first),
840 JITDylibLookupFlags::MatchExportedSymbolsOnly});
841 }
842 }
843
844 if (!JITSymSearchOrder.empty()) {
845 auto MangledName = J.mangleAndIntern(Name);
846 SymbolLookupSet Syms(MangledName,
847 SymbolLookupFlags::WeaklyReferencedSymbol);
848 if (auto Result = J.getExecutionSession().lookup(JITSymSearchOrder, Syms,
849 LookupKind::DLSym)) {
850 auto I = Result->find(MangledName);
851 if (I != Result->end())
852 return jitTargetAddressToPointer<void *>(I->second.getAddress());
853 } else {
854 recordError(Result.takeError());
855 return 0;
856 }
857 }
858
859 // Fall through to dlsym.
860 return DlFcn.dlsym(Handle, Name);
861 }
862
dlsymHelper(void * Self,void * Handle,const char * Name)863 static void *dlsymHelper(void *Self, void *Handle, const char *Name) {
864 return static_cast<MachOPlatformSupport *>(Self)->jit_dlsym(Handle, Name);
865 }
866
jit_dlerror()867 const char *jit_dlerror() {
868 {
869 std::lock_guard<std::mutex> Lock(PlatformSupportMutex);
870 auto I = dlErrorMsgs.find(std::this_thread::get_id());
871 if (I != dlErrorMsgs.end())
872 return I->second->c_str();
873 }
874 return DlFcn.dlerror();
875 }
876
dlerrorHelper(void * Self)877 static const char *dlerrorHelper(void *Self) {
878 return static_cast<MachOPlatformSupport *>(Self)->jit_dlerror();
879 }
880
recordError(Error Err)881 void recordError(Error Err) {
882 std::lock_guard<std::mutex> Lock(PlatformSupportMutex);
883 dlErrorMsgs[std::this_thread::get_id()] =
884 std::make_unique<std::string>(toString(std::move(Err)));
885 }
886
887 std::mutex PlatformSupportMutex;
888 LLJIT &J;
889 MachOPlatform &MP;
890 DlFcnValues DlFcn;
891 ItaniumCXAAtExitSupport AtExitMgr;
892 DenseMap<void *, unsigned> JDRefCounts;
893 std::map<std::thread::id, std::unique_ptr<std::string>> dlErrorMsgs;
894 };
895
896 } // end anonymous namespace
897
898 namespace llvm {
899 namespace orc {
900
setInitTransform(LLJIT & J,IRTransformLayer::TransformFunction T)901 void LLJIT::PlatformSupport::setInitTransform(
902 LLJIT &J, IRTransformLayer::TransformFunction T) {
903 J.InitHelperTransformLayer->setTransform(std::move(T));
904 }
905
~PlatformSupport()906 LLJIT::PlatformSupport::~PlatformSupport() {}
907
prepareForConstruction()908 Error LLJITBuilderState::prepareForConstruction() {
909
910 LLVM_DEBUG(dbgs() << "Preparing to create LLJIT instance...\n");
911
912 if (!JTMB) {
913 LLVM_DEBUG({
914 dbgs() << " No explicitly set JITTargetMachineBuilder. "
915 "Detecting host...\n";
916 });
917 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
918 JTMB = std::move(*JTMBOrErr);
919 else
920 return JTMBOrErr.takeError();
921 }
922
923 LLVM_DEBUG({
924 dbgs() << " JITTargetMachineBuilder is " << JTMB << "\n"
925 << " Pre-constructed ExecutionSession: " << (ES ? "Yes" : "No")
926 << "\n"
927 << " DataLayout: ";
928 if (DL)
929 dbgs() << DL->getStringRepresentation() << "\n";
930 else
931 dbgs() << "None (will be created by JITTargetMachineBuilder)\n";
932
933 dbgs() << " Custom object-linking-layer creator: "
934 << (CreateObjectLinkingLayer ? "Yes" : "No") << "\n"
935 << " Custom compile-function creator: "
936 << (CreateCompileFunction ? "Yes" : "No") << "\n"
937 << " Custom platform-setup function: "
938 << (SetUpPlatform ? "Yes" : "No") << "\n"
939 << " Number of compile threads: " << NumCompileThreads;
940 if (!NumCompileThreads)
941 dbgs() << " (code will be compiled on the execution thread)\n";
942 else
943 dbgs() << "\n";
944 });
945
946 // If the client didn't configure any linker options then auto-configure the
947 // JIT linker.
948 if (!CreateObjectLinkingLayer) {
949 auto &TT = JTMB->getTargetTriple();
950 if (TT.isOSBinFormatMachO() &&
951 (TT.getArch() == Triple::aarch64 || TT.getArch() == Triple::x86_64)) {
952
953 JTMB->setRelocationModel(Reloc::PIC_);
954 JTMB->setCodeModel(CodeModel::Small);
955 CreateObjectLinkingLayer =
956 [TPC = this->TPC](ExecutionSession &ES,
957 const Triple &) -> std::unique_ptr<ObjectLayer> {
958 std::unique_ptr<ObjectLinkingLayer> ObjLinkingLayer;
959 if (TPC)
960 ObjLinkingLayer =
961 std::make_unique<ObjectLinkingLayer>(ES, TPC->getMemMgr());
962 else
963 ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>(
964 ES, std::make_unique<jitlink::InProcessMemoryManager>());
965 ObjLinkingLayer->addPlugin(std::make_unique<EHFrameRegistrationPlugin>(
966 ES, std::make_unique<jitlink::InProcessEHFrameRegistrar>()));
967 return std::move(ObjLinkingLayer);
968 };
969 }
970 }
971
972 return Error::success();
973 }
974
~LLJIT()975 LLJIT::~LLJIT() {
976 if (CompileThreads)
977 CompileThreads->wait();
978 if (auto Err = ES->endSession())
979 ES->reportError(std::move(Err));
980 }
981
addIRModule(ResourceTrackerSP RT,ThreadSafeModule TSM)982 Error LLJIT::addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) {
983 assert(TSM && "Can not add null module");
984
985 if (auto Err =
986 TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); }))
987 return Err;
988
989 return InitHelperTransformLayer->add(std::move(RT), std::move(TSM));
990 }
991
addIRModule(JITDylib & JD,ThreadSafeModule TSM)992 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
993 return addIRModule(JD.getDefaultResourceTracker(), std::move(TSM));
994 }
995
addObjectFile(ResourceTrackerSP RT,std::unique_ptr<MemoryBuffer> Obj)996 Error LLJIT::addObjectFile(ResourceTrackerSP RT,
997 std::unique_ptr<MemoryBuffer> Obj) {
998 assert(Obj && "Can not add null object");
999
1000 return ObjTransformLayer.add(std::move(RT), std::move(Obj));
1001 }
1002
addObjectFile(JITDylib & JD,std::unique_ptr<MemoryBuffer> Obj)1003 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
1004 return addObjectFile(JD.getDefaultResourceTracker(), std::move(Obj));
1005 }
1006
lookupLinkerMangled(JITDylib & JD,SymbolStringPtr Name)1007 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
1008 SymbolStringPtr Name) {
1009 return ES->lookup(
1010 makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), Name);
1011 }
1012
1013 std::unique_ptr<ObjectLayer>
createObjectLinkingLayer(LLJITBuilderState & S,ExecutionSession & ES)1014 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
1015
1016 // If the config state provided an ObjectLinkingLayer factory then use it.
1017 if (S.CreateObjectLinkingLayer)
1018 return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple());
1019
1020 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
1021 // a new SectionMemoryManager for each object.
1022 auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); };
1023 auto ObjLinkingLayer =
1024 std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
1025
1026 if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) {
1027 ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags(true);
1028 ObjLinkingLayer->setAutoClaimResponsibilityForObjectSymbols(true);
1029 }
1030
1031 // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence
1032 // errors from some GCC / libstdc++ bots. Remove this conversion (i.e.
1033 // just return ObjLinkingLayer) once those bots are upgraded.
1034 return std::unique_ptr<ObjectLayer>(std::move(ObjLinkingLayer));
1035 }
1036
1037 Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
createCompileFunction(LLJITBuilderState & S,JITTargetMachineBuilder JTMB)1038 LLJIT::createCompileFunction(LLJITBuilderState &S,
1039 JITTargetMachineBuilder JTMB) {
1040
1041 /// If there is a custom compile function creator set then use it.
1042 if (S.CreateCompileFunction)
1043 return S.CreateCompileFunction(std::move(JTMB));
1044
1045 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
1046 // depending on the number of threads requested.
1047 if (S.NumCompileThreads > 0)
1048 return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB));
1049
1050 auto TM = JTMB.createTargetMachine();
1051 if (!TM)
1052 return TM.takeError();
1053
1054 return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM));
1055 }
1056
LLJIT(LLJITBuilderState & S,Error & Err)1057 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
1058 : ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()), Main(),
1059 DL(""), TT(S.JTMB->getTargetTriple()),
1060 ObjLinkingLayer(createObjectLinkingLayer(S, *ES)),
1061 ObjTransformLayer(*this->ES, *ObjLinkingLayer) {
1062
1063 ErrorAsOutParameter _(&Err);
1064
1065 if (auto MainOrErr = this->ES->createJITDylib("main"))
1066 Main = &*MainOrErr;
1067 else {
1068 Err = MainOrErr.takeError();
1069 return;
1070 }
1071
1072 if (S.DL)
1073 DL = std::move(*S.DL);
1074 else if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
1075 DL = std::move(*DLOrErr);
1076 else {
1077 Err = DLOrErr.takeError();
1078 return;
1079 }
1080
1081 {
1082 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB));
1083 if (!CompileFunction) {
1084 Err = CompileFunction.takeError();
1085 return;
1086 }
1087 CompileLayer = std::make_unique<IRCompileLayer>(
1088 *ES, ObjTransformLayer, std::move(*CompileFunction));
1089 TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer);
1090 InitHelperTransformLayer =
1091 std::make_unique<IRTransformLayer>(*ES, *TransformLayer);
1092 }
1093
1094 if (S.NumCompileThreads > 0) {
1095 InitHelperTransformLayer->setCloneToNewContextOnEmit(true);
1096 CompileThreads =
1097 std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads));
1098 ES->setDispatchMaterialization(
1099 [this](std::unique_ptr<MaterializationUnit> MU,
1100 std::unique_ptr<MaterializationResponsibility> MR) {
1101 // FIXME: We should be able to use move-capture here, but ThreadPool's
1102 // AsyncTaskTys are std::functions rather than unique_functions
1103 // (because MSVC's std::packaged_tasks don't support move-only types).
1104 // Fix this when all the above gets sorted out.
1105 CompileThreads->async(
1106 [UnownedMU = MU.release(), UnownedMR = MR.release()]() mutable {
1107 std::unique_ptr<MaterializationUnit> MU(UnownedMU);
1108 std::unique_ptr<MaterializationResponsibility> MR(UnownedMR);
1109 MU->materialize(std::move(MR));
1110 });
1111 });
1112 }
1113
1114 if (S.SetUpPlatform)
1115 Err = S.SetUpPlatform(*this);
1116 else
1117 setUpGenericLLVMIRPlatform(*this);
1118 }
1119
mangle(StringRef UnmangledName) const1120 std::string LLJIT::mangle(StringRef UnmangledName) const {
1121 std::string MangledName;
1122 {
1123 raw_string_ostream MangledNameStream(MangledName);
1124 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
1125 }
1126 return MangledName;
1127 }
1128
applyDataLayout(Module & M)1129 Error LLJIT::applyDataLayout(Module &M) {
1130 if (M.getDataLayout().isDefault())
1131 M.setDataLayout(DL);
1132
1133 if (M.getDataLayout() != DL)
1134 return make_error<StringError>(
1135 "Added modules have incompatible data layouts: " +
1136 M.getDataLayout().getStringRepresentation() + " (module) vs " +
1137 DL.getStringRepresentation() + " (jit)",
1138 inconvertibleErrorCode());
1139
1140 return Error::success();
1141 }
1142
setUpGenericLLVMIRPlatform(LLJIT & J)1143 void setUpGenericLLVMIRPlatform(LLJIT &J) {
1144 LLVM_DEBUG(
1145 { dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; });
1146 J.setPlatformSupport(std::make_unique<GenericLLVMIRPlatformSupport>(J));
1147 }
1148
setUpMachOPlatform(LLJIT & J)1149 Error setUpMachOPlatform(LLJIT &J) {
1150 LLVM_DEBUG({ dbgs() << "Setting up MachOPlatform support for LLJIT\n"; });
1151 auto MP = MachOPlatformSupport::Create(J, J.getMainJITDylib());
1152 if (!MP)
1153 return MP.takeError();
1154 J.setPlatformSupport(std::move(*MP));
1155 return Error::success();
1156 }
1157
prepareForConstruction()1158 Error LLLazyJITBuilderState::prepareForConstruction() {
1159 if (auto Err = LLJITBuilderState::prepareForConstruction())
1160 return Err;
1161 TT = JTMB->getTargetTriple();
1162 return Error::success();
1163 }
1164
addLazyIRModule(JITDylib & JD,ThreadSafeModule TSM)1165 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
1166 assert(TSM && "Can not add null module");
1167
1168 if (auto Err = TSM.withModuleDo(
1169 [&](Module &M) -> Error { return applyDataLayout(M); }))
1170 return Err;
1171
1172 return CODLayer->add(JD, std::move(TSM));
1173 }
1174
LLLazyJIT(LLLazyJITBuilderState & S,Error & Err)1175 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
1176
1177 // If LLJIT construction failed then bail out.
1178 if (Err)
1179 return;
1180
1181 ErrorAsOutParameter _(&Err);
1182
1183 /// Take/Create the lazy-compile callthrough manager.
1184 if (S.LCTMgr)
1185 LCTMgr = std::move(S.LCTMgr);
1186 else {
1187 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
1188 S.TT, *ES, S.LazyCompileFailureAddr))
1189 LCTMgr = std::move(*LCTMgrOrErr);
1190 else {
1191 Err = LCTMgrOrErr.takeError();
1192 return;
1193 }
1194 }
1195
1196 // Take/Create the indirect stubs manager builder.
1197 auto ISMBuilder = std::move(S.ISMBuilder);
1198
1199 // If none was provided, try to build one.
1200 if (!ISMBuilder)
1201 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);
1202
1203 // No luck. Bail out.
1204 if (!ISMBuilder) {
1205 Err = make_error<StringError>("Could not construct "
1206 "IndirectStubsManagerBuilder for target " +
1207 S.TT.str(),
1208 inconvertibleErrorCode());
1209 return;
1210 }
1211
1212 // Create the COD layer.
1213 CODLayer = std::make_unique<CompileOnDemandLayer>(
1214 *ES, *InitHelperTransformLayer, *LCTMgr, std::move(ISMBuilder));
1215
1216 if (S.NumCompileThreads > 0)
1217 CODLayer->setCloneToNewContextOnEmit(true);
1218 }
1219
1220 } // End namespace orc.
1221 } // End namespace llvm.
1222