• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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