1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
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
7 //===----------------------------------------------------------------------===//
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/ExecutorProcessControl.h"
13 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
14 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
15 #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
16 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
17 #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
18 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
19 #include "llvm/IR/GlobalVariable.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/Support/DynamicLibrary.h"
27 #define DEBUG_TYPE "orc"
30 using namespace llvm::orc
;
34 /// Adds helper function decls and wrapper functions that call the helper with
35 /// some additional prefix arguments.
37 /// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix
38 /// args i32 4 and i16 12345, this function will add:
40 /// declare i8 @bar(i32, i16, i8, i64)
42 /// define i8 @foo(i8, i64) {
44 /// %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1)
48 Function
*addHelperAndWrapper(Module
&M
, StringRef WrapperName
,
49 FunctionType
*WrapperFnType
,
50 GlobalValue::VisibilityTypes WrapperVisibility
,
52 ArrayRef
<Value
*> HelperPrefixArgs
) {
53 std::vector
<Type
*> HelperArgTypes
;
54 for (auto *Arg
: HelperPrefixArgs
)
55 HelperArgTypes
.push_back(Arg
->getType());
56 for (auto *T
: WrapperFnType
->params())
57 HelperArgTypes
.push_back(T
);
59 FunctionType::get(WrapperFnType
->getReturnType(), HelperArgTypes
, false);
60 auto *HelperFn
= Function::Create(HelperFnType
, GlobalValue::ExternalLinkage
,
63 auto *WrapperFn
= Function::Create(
64 WrapperFnType
, GlobalValue::ExternalLinkage
, WrapperName
, M
);
65 WrapperFn
->setVisibility(WrapperVisibility
);
67 auto *EntryBlock
= BasicBlock::Create(M
.getContext(), "entry", WrapperFn
);
68 IRBuilder
<> IB(EntryBlock
);
70 std::vector
<Value
*> HelperArgs
;
71 for (auto *Arg
: HelperPrefixArgs
)
72 HelperArgs
.push_back(Arg
);
73 for (auto &Arg
: WrapperFn
->args())
74 HelperArgs
.push_back(&Arg
);
75 auto *HelperResult
= IB
.CreateCall(HelperFn
, HelperArgs
);
76 if (HelperFn
->getReturnType()->isVoidTy())
79 IB
.CreateRet(HelperResult
);
84 class GenericLLVMIRPlatformSupport
;
86 /// orc::Platform component of Generic LLVM IR Platform support.
87 /// Just forwards calls to the GenericLLVMIRPlatformSupport class below.
88 class GenericLLVMIRPlatform
: public Platform
{
90 GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport
&S
) : S(S
) {}
91 Error
setupJITDylib(JITDylib
&JD
) override
;
92 Error
teardownJITDylib(JITDylib
&JD
) override
;
93 Error
notifyAdding(ResourceTracker
&RT
,
94 const MaterializationUnit
&MU
) override
;
95 Error
notifyRemoving(ResourceTracker
&RT
) override
{
96 // Noop -- Nothing to do (yet).
97 return Error::success();
101 GenericLLVMIRPlatformSupport
&S
;
104 /// This transform parses llvm.global_ctors to produce a single initialization
105 /// function for the module, records the function, then deletes
106 /// llvm.global_ctors.
107 class GlobalCtorDtorScraper
{
109 GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport
&PS
,
110 StringRef InitFunctionPrefix
,
111 StringRef DeInitFunctionPrefix
)
112 : PS(PS
), InitFunctionPrefix(InitFunctionPrefix
),
113 DeInitFunctionPrefix(DeInitFunctionPrefix
) {}
114 Expected
<ThreadSafeModule
> operator()(ThreadSafeModule TSM
,
115 MaterializationResponsibility
&R
);
118 GenericLLVMIRPlatformSupport
&PS
;
119 StringRef InitFunctionPrefix
;
120 StringRef DeInitFunctionPrefix
;
123 /// Generic IR Platform Support
125 /// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with
126 /// specially named 'init' and 'deinit'. Injects definitions / interposes for
127 /// some runtime API, including __cxa_atexit, dlopen, and dlclose.
128 class GenericLLVMIRPlatformSupport
: public LLJIT::PlatformSupport
{
130 GenericLLVMIRPlatformSupport(LLJIT
&J
)
131 : J(J
), InitFunctionPrefix(J
.mangle("__orc_init_func.")),
132 DeInitFunctionPrefix(J
.mangle("__orc_deinit_func.")) {
134 getExecutionSession().setPlatform(
135 std::make_unique
<GenericLLVMIRPlatform
>(*this));
137 setInitTransform(J
, GlobalCtorDtorScraper(*this, InitFunctionPrefix
,
138 DeInitFunctionPrefix
));
140 SymbolMap StdInterposes
;
142 StdInterposes
[J
.mangleAndIntern("__lljit.platform_support_instance")] =
143 JITEvaluatedSymbol(pointerToJITTargetAddress(this),
144 JITSymbolFlags::Exported
);
145 StdInterposes
[J
.mangleAndIntern("__lljit.cxa_atexit_helper")] =
146 JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper
),
150 J
.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes
))));
151 cantFail(setupJITDylib(J
.getMainJITDylib()));
152 cantFail(J
.addIRModule(J
.getMainJITDylib(), createPlatformRuntimeModule()));
155 ExecutionSession
&getExecutionSession() { return J
.getExecutionSession(); }
157 /// Adds a module that defines the __dso_handle global.
158 Error
setupJITDylib(JITDylib
&JD
) {
160 // Add per-jitdylib standard interposes.
161 SymbolMap PerJDInterposes
;
162 PerJDInterposes
[J
.mangleAndIntern("__lljit.run_atexits_helper")] =
163 JITEvaluatedSymbol(pointerToJITTargetAddress(runAtExitsHelper
),
165 cantFail(JD
.define(absoluteSymbols(std::move(PerJDInterposes
))));
167 auto Ctx
= std::make_unique
<LLVMContext
>();
168 auto M
= std::make_unique
<Module
>("__standard_lib", *Ctx
);
169 M
->setDataLayout(J
.getDataLayout());
171 auto *Int64Ty
= Type::getInt64Ty(*Ctx
);
172 auto *DSOHandle
= new GlobalVariable(
173 *M
, Int64Ty
, true, GlobalValue::ExternalLinkage
,
174 ConstantInt::get(Int64Ty
, reinterpret_cast<uintptr_t>(&JD
)),
176 DSOHandle
->setVisibility(GlobalValue::DefaultVisibility
);
177 DSOHandle
->setInitializer(
178 ConstantInt::get(Int64Ty
, pointerToJITTargetAddress(&JD
)));
180 auto *GenericIRPlatformSupportTy
=
181 StructType::create(*Ctx
, "lljit.GenericLLJITIRPlatformSupport");
183 auto *PlatformInstanceDecl
= new GlobalVariable(
184 *M
, GenericIRPlatformSupportTy
, true, GlobalValue::ExternalLinkage
,
185 nullptr, "__lljit.platform_support_instance");
187 auto *VoidTy
= Type::getVoidTy(*Ctx
);
189 *M
, "__lljit_run_atexits", FunctionType::get(VoidTy
, {}, false),
190 GlobalValue::HiddenVisibility
, "__lljit.run_atexits_helper",
191 {PlatformInstanceDecl
, DSOHandle
});
193 return J
.addIRModule(JD
, ThreadSafeModule(std::move(M
), std::move(Ctx
)));
196 Error
notifyAdding(ResourceTracker
&RT
, const MaterializationUnit
&MU
) {
197 auto &JD
= RT
.getJITDylib();
198 if (auto &InitSym
= MU
.getInitializerSymbol())
199 InitSymbols
[&JD
].add(InitSym
, SymbolLookupFlags::WeaklyReferencedSymbol
);
201 // If there's no identified init symbol attached, but there is a symbol
202 // with the GenericIRPlatform::InitFunctionPrefix, then treat that as
203 // an init function. Add the symbol to both the InitSymbols map (which
204 // will trigger a lookup to materialize the module) and the InitFunctions
205 // map (which holds the names of the symbols to execute).
206 for (auto &KV
: MU
.getSymbols())
207 if ((*KV
.first
).startswith(InitFunctionPrefix
)) {
208 InitSymbols
[&JD
].add(KV
.first
,
209 SymbolLookupFlags::WeaklyReferencedSymbol
);
210 InitFunctions
[&JD
].add(KV
.first
);
211 } else if ((*KV
.first
).startswith(DeInitFunctionPrefix
)) {
212 DeInitFunctions
[&JD
].add(KV
.first
);
215 return Error::success();
218 Error
initialize(JITDylib
&JD
) override
{
220 dbgs() << "GenericLLVMIRPlatformSupport getting initializers to run\n";
222 if (auto Initializers
= getInitializers(JD
)) {
224 { dbgs() << "GenericLLVMIRPlatformSupport running initializers\n"; });
225 for (auto InitFnAddr
: *Initializers
) {
227 dbgs() << " Running init " << formatv("{0:x16}", InitFnAddr
)
230 auto *InitFn
= jitTargetAddressToFunction
<void (*)()>(InitFnAddr
);
234 return Initializers
.takeError();
235 return Error::success();
238 Error
deinitialize(JITDylib
&JD
) override
{
240 dbgs() << "GenericLLVMIRPlatformSupport getting deinitializers to run\n";
242 if (auto Deinitializers
= getDeinitializers(JD
)) {
244 dbgs() << "GenericLLVMIRPlatformSupport running deinitializers\n";
246 for (auto DeinitFnAddr
: *Deinitializers
) {
248 dbgs() << " Running deinit " << formatv("{0:x16}", DeinitFnAddr
)
251 auto *DeinitFn
= jitTargetAddressToFunction
<void (*)()>(DeinitFnAddr
);
255 return Deinitializers
.takeError();
257 return Error::success();
260 void registerInitFunc(JITDylib
&JD
, SymbolStringPtr InitName
) {
261 getExecutionSession().runSessionLocked([&]() {
262 InitFunctions
[&JD
].add(InitName
);
266 void registerDeInitFunc(JITDylib
&JD
, SymbolStringPtr DeInitName
) {
267 getExecutionSession().runSessionLocked(
268 [&]() { DeInitFunctions
[&JD
].add(DeInitName
); });
273 Expected
<std::vector
<JITTargetAddress
>> getInitializers(JITDylib
&JD
) {
274 if (auto Err
= issueInitLookups(JD
))
275 return std::move(Err
);
277 DenseMap
<JITDylib
*, SymbolLookupSet
> LookupSymbols
;
278 std::vector
<JITDylibSP
> DFSLinkOrder
;
280 getExecutionSession().runSessionLocked([&]() {
281 DFSLinkOrder
= JD
.getDFSLinkOrder();
283 for (auto &NextJD
: DFSLinkOrder
) {
284 auto IFItr
= InitFunctions
.find(NextJD
.get());
285 if (IFItr
!= InitFunctions
.end()) {
286 LookupSymbols
[NextJD
.get()] = std::move(IFItr
->second
);
287 InitFunctions
.erase(IFItr
);
293 dbgs() << "JITDylib init order is [ ";
294 for (auto &JD
: llvm::reverse(DFSLinkOrder
))
295 dbgs() << "\"" << JD
->getName() << "\" ";
297 dbgs() << "Looking up init functions:\n";
298 for (auto &KV
: LookupSymbols
)
299 dbgs() << " \"" << KV
.first
->getName() << "\": " << KV
.second
<< "\n";
302 auto &ES
= getExecutionSession();
303 auto LookupResult
= Platform::lookupInitSymbols(ES
, LookupSymbols
);
306 return LookupResult
.takeError();
308 std::vector
<JITTargetAddress
> Initializers
;
309 while (!DFSLinkOrder
.empty()) {
310 auto &NextJD
= *DFSLinkOrder
.back();
311 DFSLinkOrder
.pop_back();
312 auto InitsItr
= LookupResult
->find(&NextJD
);
313 if (InitsItr
== LookupResult
->end())
315 for (auto &KV
: InitsItr
->second
)
316 Initializers
.push_back(KV
.second
.getAddress());
322 Expected
<std::vector
<JITTargetAddress
>> getDeinitializers(JITDylib
&JD
) {
323 auto &ES
= getExecutionSession();
325 auto LLJITRunAtExits
= J
.mangleAndIntern("__lljit_run_atexits");
327 DenseMap
<JITDylib
*, SymbolLookupSet
> LookupSymbols
;
328 std::vector
<JITDylibSP
> DFSLinkOrder
;
330 ES
.runSessionLocked([&]() {
331 DFSLinkOrder
= JD
.getDFSLinkOrder();
333 for (auto &NextJD
: DFSLinkOrder
) {
334 auto &JDLookupSymbols
= LookupSymbols
[NextJD
.get()];
335 auto DIFItr
= DeInitFunctions
.find(NextJD
.get());
336 if (DIFItr
!= DeInitFunctions
.end()) {
337 LookupSymbols
[NextJD
.get()] = std::move(DIFItr
->second
);
338 DeInitFunctions
.erase(DIFItr
);
340 JDLookupSymbols
.add(LLJITRunAtExits
,
341 SymbolLookupFlags::WeaklyReferencedSymbol
);
346 dbgs() << "JITDylib deinit order is [ ";
347 for (auto &JD
: DFSLinkOrder
)
348 dbgs() << "\"" << JD
->getName() << "\" ";
350 dbgs() << "Looking up deinit functions:\n";
351 for (auto &KV
: LookupSymbols
)
352 dbgs() << " \"" << KV
.first
->getName() << "\": " << KV
.second
<< "\n";
355 auto LookupResult
= Platform::lookupInitSymbols(ES
, LookupSymbols
);
358 return LookupResult
.takeError();
360 std::vector
<JITTargetAddress
> DeInitializers
;
361 for (auto &NextJD
: DFSLinkOrder
) {
362 auto DeInitsItr
= LookupResult
->find(NextJD
.get());
363 assert(DeInitsItr
!= LookupResult
->end() &&
364 "Every JD should have at least __lljit_run_atexits");
366 auto RunAtExitsItr
= DeInitsItr
->second
.find(LLJITRunAtExits
);
367 if (RunAtExitsItr
!= DeInitsItr
->second
.end())
368 DeInitializers
.push_back(RunAtExitsItr
->second
.getAddress());
370 for (auto &KV
: DeInitsItr
->second
)
371 if (KV
.first
!= LLJITRunAtExits
)
372 DeInitializers
.push_back(KV
.second
.getAddress());
375 return DeInitializers
;
378 /// Issue lookups for all init symbols required to initialize JD (and any
379 /// JITDylibs that it depends on).
380 Error
issueInitLookups(JITDylib
&JD
) {
381 DenseMap
<JITDylib
*, SymbolLookupSet
> RequiredInitSymbols
;
382 std::vector
<JITDylibSP
> DFSLinkOrder
;
384 getExecutionSession().runSessionLocked([&]() {
385 DFSLinkOrder
= JD
.getDFSLinkOrder();
387 for (auto &NextJD
: DFSLinkOrder
) {
388 auto ISItr
= InitSymbols
.find(NextJD
.get());
389 if (ISItr
!= InitSymbols
.end()) {
390 RequiredInitSymbols
[NextJD
.get()] = std::move(ISItr
->second
);
391 InitSymbols
.erase(ISItr
);
396 return Platform::lookupInitSymbols(getExecutionSession(),
401 static void registerAtExitHelper(void *Self
, void (*F
)(void *), void *Ctx
,
404 dbgs() << "Registering atexit function " << (void *)F
<< " for JD "
405 << (*static_cast<JITDylib
**>(DSOHandle
))->getName() << "\n";
407 static_cast<GenericLLVMIRPlatformSupport
*>(Self
)->AtExitMgr
.registerAtExit(
411 static void runAtExitsHelper(void *Self
, void *DSOHandle
) {
413 dbgs() << "Running atexit functions for JD "
414 << (*static_cast<JITDylib
**>(DSOHandle
))->getName() << "\n";
416 static_cast<GenericLLVMIRPlatformSupport
*>(Self
)->AtExitMgr
.runAtExits(
420 // Constructs an LLVM IR module containing platform runtime globals,
421 // functions, and interposes.
422 ThreadSafeModule
createPlatformRuntimeModule() {
423 auto Ctx
= std::make_unique
<LLVMContext
>();
424 auto M
= std::make_unique
<Module
>("__standard_lib", *Ctx
);
425 M
->setDataLayout(J
.getDataLayout());
427 auto *GenericIRPlatformSupportTy
=
428 StructType::create(*Ctx
, "lljit.GenericLLJITIRPlatformSupport");
430 auto *PlatformInstanceDecl
= new GlobalVariable(
431 *M
, GenericIRPlatformSupportTy
, true, GlobalValue::ExternalLinkage
,
432 nullptr, "__lljit.platform_support_instance");
434 auto *Int8Ty
= Type::getInt8Ty(*Ctx
);
435 auto *IntTy
= Type::getIntNTy(*Ctx
, sizeof(int) * CHAR_BIT
);
436 auto *VoidTy
= Type::getVoidTy(*Ctx
);
437 auto *BytePtrTy
= PointerType::getUnqual(Int8Ty
);
438 auto *AtExitCallbackTy
= FunctionType::get(VoidTy
, {BytePtrTy
}, false);
439 auto *AtExitCallbackPtrTy
= PointerType::getUnqual(AtExitCallbackTy
);
443 FunctionType::get(IntTy
, {AtExitCallbackPtrTy
, BytePtrTy
, BytePtrTy
},
445 GlobalValue::DefaultVisibility
, "__lljit.cxa_atexit_helper",
446 {PlatformInstanceDecl
});
448 return ThreadSafeModule(std::move(M
), std::move(Ctx
));
452 std::string InitFunctionPrefix
;
453 std::string DeInitFunctionPrefix
;
454 DenseMap
<JITDylib
*, SymbolLookupSet
> InitSymbols
;
455 DenseMap
<JITDylib
*, SymbolLookupSet
> InitFunctions
;
456 DenseMap
<JITDylib
*, SymbolLookupSet
> DeInitFunctions
;
457 ItaniumCXAAtExitSupport AtExitMgr
;
460 Error
GenericLLVMIRPlatform::setupJITDylib(JITDylib
&JD
) {
461 return S
.setupJITDylib(JD
);
464 Error
GenericLLVMIRPlatform::teardownJITDylib(JITDylib
&JD
) {
465 return Error::success();
468 Error
GenericLLVMIRPlatform::notifyAdding(ResourceTracker
&RT
,
469 const MaterializationUnit
&MU
) {
470 return S
.notifyAdding(RT
, MU
);
473 Expected
<ThreadSafeModule
>
474 GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM
,
475 MaterializationResponsibility
&R
) {
476 auto Err
= TSM
.withModuleDo([&](Module
&M
) -> Error
{
477 auto &Ctx
= M
.getContext();
478 auto *GlobalCtors
= M
.getNamedGlobal("llvm.global_ctors");
479 auto *GlobalDtors
= M
.getNamedGlobal("llvm.global_dtors");
481 auto RegisterCOrDtors
= [&](GlobalVariable
*GlobalCOrDtors
,
482 bool isCtor
) -> Error
{
483 // If there's no llvm.global_c/dtor or it's just a decl then skip.
484 if (!GlobalCOrDtors
|| GlobalCOrDtors
->isDeclaration())
485 return Error::success();
486 std::string InitOrDeInitFunctionName
;
488 raw_string_ostream(InitOrDeInitFunctionName
)
489 << InitFunctionPrefix
<< M
.getModuleIdentifier();
491 raw_string_ostream(InitOrDeInitFunctionName
)
492 << DeInitFunctionPrefix
<< M
.getModuleIdentifier();
494 MangleAndInterner
Mangle(PS
.getExecutionSession(), M
.getDataLayout());
495 auto InternedInitOrDeInitName
= Mangle(InitOrDeInitFunctionName
);
496 if (auto Err
= R
.defineMaterializing(
497 {{InternedInitOrDeInitName
, JITSymbolFlags::Callable
}}))
500 auto *InitOrDeInitFunc
= Function::Create(
501 FunctionType::get(Type::getVoidTy(Ctx
), {}, false),
502 GlobalValue::ExternalLinkage
, InitOrDeInitFunctionName
, &M
);
503 InitOrDeInitFunc
->setVisibility(GlobalValue::HiddenVisibility
);
504 std::vector
<std::pair
<Function
*, unsigned>> InitsOrDeInits
;
505 auto COrDtors
= isCtor
? getConstructors(M
) : getDestructors(M
);
507 for (auto E
: COrDtors
)
508 InitsOrDeInits
.push_back(std::make_pair(E
.Func
, E
.Priority
));
509 llvm::sort(InitsOrDeInits
,
510 [](const std::pair
<Function
*, unsigned> &LHS
,
511 const std::pair
<Function
*, unsigned> &RHS
) {
512 return LHS
.first
< RHS
.first
;
515 auto *InitOrDeInitFuncEntryBlock
=
516 BasicBlock::Create(Ctx
, "entry", InitOrDeInitFunc
);
517 IRBuilder
<> IB(InitOrDeInitFuncEntryBlock
);
518 for (auto &KV
: InitsOrDeInits
)
519 IB
.CreateCall(KV
.first
);
523 PS
.registerInitFunc(R
.getTargetJITDylib(), InternedInitOrDeInitName
);
525 PS
.registerDeInitFunc(R
.getTargetJITDylib(), InternedInitOrDeInitName
);
527 GlobalCOrDtors
->eraseFromParent();
528 return Error::success();
531 if (auto Err
= RegisterCOrDtors(GlobalCtors
, true))
533 if (auto Err
= RegisterCOrDtors(GlobalDtors
, false))
536 return Error::success();
540 return std::move(Err
);
542 return std::move(TSM
);
545 /// Inactive Platform Support
547 /// Explicitly disables platform support. JITDylibs are not scanned for special
548 /// init/deinit symbols. No runtime API interposes are injected.
549 class InactivePlatformSupport
: public LLJIT::PlatformSupport
{
551 InactivePlatformSupport() = default;
553 Error
initialize(JITDylib
&JD
) override
{
554 LLVM_DEBUG(dbgs() << "InactivePlatformSupport: no initializers running for "
555 << JD
.getName() << "\n");
556 return Error::success();
559 Error
deinitialize(JITDylib
&JD
) override
{
561 dbgs() << "InactivePlatformSupport: no deinitializers running for "
562 << JD
.getName() << "\n");
563 return Error::success();
567 } // end anonymous namespace
572 void LLJIT::PlatformSupport::setInitTransform(
573 LLJIT
&J
, IRTransformLayer::TransformFunction T
) {
574 J
.InitHelperTransformLayer
->setTransform(std::move(T
));
577 LLJIT::PlatformSupport::~PlatformSupport() {}
579 Error
LLJITBuilderState::prepareForConstruction() {
581 LLVM_DEBUG(dbgs() << "Preparing to create LLJIT instance...\n");
585 dbgs() << " No explicitly set JITTargetMachineBuilder. "
586 "Detecting host...\n";
588 if (auto JTMBOrErr
= JITTargetMachineBuilder::detectHost())
589 JTMB
= std::move(*JTMBOrErr
);
591 return JTMBOrErr
.takeError();
595 dbgs() << " JITTargetMachineBuilder is "
596 << JITTargetMachineBuilderPrinter(*JTMB
, " ")
597 << " Pre-constructed ExecutionSession: " << (ES
? "Yes" : "No")
601 dbgs() << DL
->getStringRepresentation() << "\n";
603 dbgs() << "None (will be created by JITTargetMachineBuilder)\n";
605 dbgs() << " Custom object-linking-layer creator: "
606 << (CreateObjectLinkingLayer
? "Yes" : "No") << "\n"
607 << " Custom compile-function creator: "
608 << (CreateCompileFunction
? "Yes" : "No") << "\n"
609 << " Custom platform-setup function: "
610 << (SetUpPlatform
? "Yes" : "No") << "\n"
611 << " Number of compile threads: " << NumCompileThreads
;
612 if (!NumCompileThreads
)
613 dbgs() << " (code will be compiled on the execution thread)\n";
618 // If neither ES nor EPC has been set then create an EPC instance.
621 dbgs() << "ExecutorProcessControl not specified, "
622 "Creating SelfExecutorProcessControl instance\n";
624 if (auto EPCOrErr
= SelfExecutorProcessControl::Create())
625 EPC
= std::move(*EPCOrErr
);
627 return EPCOrErr
.takeError();
630 dbgs() << "Using explicitly specified ExecutorProcessControl instance "
631 << EPC
.get() << "\n";
634 // If the client didn't configure any linker options then auto-configure the
636 if (!CreateObjectLinkingLayer
) {
637 auto &TT
= JTMB
->getTargetTriple();
638 if (TT
.isOSBinFormatMachO() &&
639 (TT
.getArch() == Triple::aarch64
|| TT
.getArch() == Triple::x86_64
)) {
641 JTMB
->setRelocationModel(Reloc::PIC_
);
642 JTMB
->setCodeModel(CodeModel::Small
);
643 CreateObjectLinkingLayer
=
644 [](ExecutionSession
&ES
,
645 const Triple
&) -> Expected
<std::unique_ptr
<ObjectLayer
>> {
646 auto ObjLinkingLayer
= std::make_unique
<ObjectLinkingLayer
>(ES
);
647 ObjLinkingLayer
->addPlugin(std::make_unique
<EHFrameRegistrationPlugin
>(
648 ES
, std::make_unique
<jitlink::InProcessEHFrameRegistrar
>()));
649 return std::move(ObjLinkingLayer
);
654 return Error::success();
659 CompileThreads
->wait();
660 if (auto Err
= ES
->endSession())
661 ES
->reportError(std::move(Err
));
664 Error
LLJIT::addIRModule(ResourceTrackerSP RT
, ThreadSafeModule TSM
) {
665 assert(TSM
&& "Can not add null module");
668 TSM
.withModuleDo([&](Module
&M
) { return applyDataLayout(M
); }))
671 return InitHelperTransformLayer
->add(std::move(RT
), std::move(TSM
));
674 Error
LLJIT::addIRModule(JITDylib
&JD
, ThreadSafeModule TSM
) {
675 return addIRModule(JD
.getDefaultResourceTracker(), std::move(TSM
));
678 Error
LLJIT::addObjectFile(ResourceTrackerSP RT
,
679 std::unique_ptr
<MemoryBuffer
> Obj
) {
680 assert(Obj
&& "Can not add null object");
682 return ObjTransformLayer
->add(std::move(RT
), std::move(Obj
));
685 Error
LLJIT::addObjectFile(JITDylib
&JD
, std::unique_ptr
<MemoryBuffer
> Obj
) {
686 return addObjectFile(JD
.getDefaultResourceTracker(), std::move(Obj
));
689 Expected
<JITEvaluatedSymbol
> LLJIT::lookupLinkerMangled(JITDylib
&JD
,
690 SymbolStringPtr Name
) {
692 makeJITDylibSearchOrder(&JD
, JITDylibLookupFlags::MatchAllSymbols
), Name
);
695 Expected
<std::unique_ptr
<ObjectLayer
>>
696 LLJIT::createObjectLinkingLayer(LLJITBuilderState
&S
, ExecutionSession
&ES
) {
698 // If the config state provided an ObjectLinkingLayer factory then use it.
699 if (S
.CreateObjectLinkingLayer
)
700 return S
.CreateObjectLinkingLayer(ES
, S
.JTMB
->getTargetTriple());
702 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
703 // a new SectionMemoryManager for each object.
704 auto GetMemMgr
= []() { return std::make_unique
<SectionMemoryManager
>(); };
706 std::make_unique
<RTDyldObjectLinkingLayer
>(ES
, std::move(GetMemMgr
));
708 if (S
.JTMB
->getTargetTriple().isOSBinFormatCOFF()) {
709 Layer
->setOverrideObjectFlagsWithResponsibilityFlags(true);
710 Layer
->setAutoClaimResponsibilityForObjectSymbols(true);
713 // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence
714 // errors from some GCC / libstdc++ bots. Remove this conversion (i.e.
715 // just return ObjLinkingLayer) once those bots are upgraded.
716 return std::unique_ptr
<ObjectLayer
>(std::move(Layer
));
719 Expected
<std::unique_ptr
<IRCompileLayer::IRCompiler
>>
720 LLJIT::createCompileFunction(LLJITBuilderState
&S
,
721 JITTargetMachineBuilder JTMB
) {
723 /// If there is a custom compile function creator set then use it.
724 if (S
.CreateCompileFunction
)
725 return S
.CreateCompileFunction(std::move(JTMB
));
727 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
728 // depending on the number of threads requested.
729 if (S
.NumCompileThreads
> 0)
730 return std::make_unique
<ConcurrentIRCompiler
>(std::move(JTMB
));
732 auto TM
= JTMB
.createTargetMachine();
734 return TM
.takeError();
736 return std::make_unique
<TMOwningSimpleCompiler
>(std::move(*TM
));
739 LLJIT::LLJIT(LLJITBuilderState
&S
, Error
&Err
)
740 : DL(""), TT(S
.JTMB
->getTargetTriple()) {
742 ErrorAsOutParameter
_(&Err
);
744 assert(!(S
.EPC
&& S
.ES
) && "EPC and ES should not both be set");
747 ES
= std::make_unique
<ExecutionSession
>(std::move(S
.EPC
));
749 ES
= std::move(S
.ES
);
751 if (auto EPC
= SelfExecutorProcessControl::Create()) {
752 ES
= std::make_unique
<ExecutionSession
>(std::move(*EPC
));
754 Err
= EPC
.takeError();
759 if (auto MainOrErr
= this->ES
->createJITDylib("main"))
762 Err
= MainOrErr
.takeError();
767 DL
= std::move(*S
.DL
);
768 else if (auto DLOrErr
= S
.JTMB
->getDefaultDataLayoutForTarget())
769 DL
= std::move(*DLOrErr
);
771 Err
= DLOrErr
.takeError();
775 auto ObjLayer
= createObjectLinkingLayer(S
, *ES
);
777 Err
= ObjLayer
.takeError();
780 ObjLinkingLayer
= std::move(*ObjLayer
);
782 std::make_unique
<ObjectTransformLayer
>(*ES
, *ObjLinkingLayer
);
785 auto CompileFunction
= createCompileFunction(S
, std::move(*S
.JTMB
));
786 if (!CompileFunction
) {
787 Err
= CompileFunction
.takeError();
790 CompileLayer
= std::make_unique
<IRCompileLayer
>(
791 *ES
, *ObjTransformLayer
, std::move(*CompileFunction
));
792 TransformLayer
= std::make_unique
<IRTransformLayer
>(*ES
, *CompileLayer
);
793 InitHelperTransformLayer
=
794 std::make_unique
<IRTransformLayer
>(*ES
, *TransformLayer
);
797 if (S
.NumCompileThreads
> 0) {
798 InitHelperTransformLayer
->setCloneToNewContextOnEmit(true);
800 std::make_unique
<ThreadPool
>(hardware_concurrency(S
.NumCompileThreads
));
801 ES
->setDispatchTask([this](std::unique_ptr
<Task
> T
) {
802 // FIXME: We should be able to use move-capture here, but ThreadPool's
803 // AsyncTaskTys are std::functions rather than unique_functions
804 // (because MSVC's std::packaged_tasks don't support move-only types).
805 // Fix this when all the above gets sorted out.
806 CompileThreads
->async([UnownedT
= T
.release()]() mutable {
807 std::unique_ptr
<Task
> T(UnownedT
);
814 Err
= S
.SetUpPlatform(*this);
816 setUpGenericLLVMIRPlatform(*this);
819 std::string
LLJIT::mangle(StringRef UnmangledName
) const {
820 std::string MangledName
;
822 raw_string_ostream
MangledNameStream(MangledName
);
823 Mangler::getNameWithPrefix(MangledNameStream
, UnmangledName
, DL
);
828 Error
LLJIT::applyDataLayout(Module
&M
) {
829 if (M
.getDataLayout().isDefault())
832 if (M
.getDataLayout() != DL
)
833 return make_error
<StringError
>(
834 "Added modules have incompatible data layouts: " +
835 M
.getDataLayout().getStringRepresentation() + " (module) vs " +
836 DL
.getStringRepresentation() + " (jit)",
837 inconvertibleErrorCode());
839 return Error::success();
842 void setUpGenericLLVMIRPlatform(LLJIT
&J
) {
844 { dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; });
845 J
.setPlatformSupport(std::make_unique
<GenericLLVMIRPlatformSupport
>(J
));
848 Error
setUpInactivePlatform(LLJIT
&J
) {
850 { dbgs() << "Explicitly deactivated platform support for LLJIT\n"; });
851 J
.setPlatformSupport(std::make_unique
<InactivePlatformSupport
>());
852 return Error::success();
855 Error
LLLazyJITBuilderState::prepareForConstruction() {
856 if (auto Err
= LLJITBuilderState::prepareForConstruction())
858 TT
= JTMB
->getTargetTriple();
859 return Error::success();
862 Error
LLLazyJIT::addLazyIRModule(JITDylib
&JD
, ThreadSafeModule TSM
) {
863 assert(TSM
&& "Can not add null module");
865 if (auto Err
= TSM
.withModuleDo(
866 [&](Module
&M
) -> Error
{ return applyDataLayout(M
); }))
869 return CODLayer
->add(JD
, std::move(TSM
));
872 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState
&S
, Error
&Err
) : LLJIT(S
, Err
) {
874 // If LLJIT construction failed then bail out.
878 ErrorAsOutParameter
_(&Err
);
880 /// Take/Create the lazy-compile callthrough manager.
882 LCTMgr
= std::move(S
.LCTMgr
);
884 if (auto LCTMgrOrErr
= createLocalLazyCallThroughManager(
885 S
.TT
, *ES
, S
.LazyCompileFailureAddr
))
886 LCTMgr
= std::move(*LCTMgrOrErr
);
888 Err
= LCTMgrOrErr
.takeError();
893 // Take/Create the indirect stubs manager builder.
894 auto ISMBuilder
= std::move(S
.ISMBuilder
);
896 // If none was provided, try to build one.
898 ISMBuilder
= createLocalIndirectStubsManagerBuilder(S
.TT
);
900 // No luck. Bail out.
902 Err
= make_error
<StringError
>("Could not construct "
903 "IndirectStubsManagerBuilder for target " +
905 inconvertibleErrorCode());
909 // Create the COD layer.
910 CODLayer
= std::make_unique
<CompileOnDemandLayer
>(
911 *ES
, *InitHelperTransformLayer
, *LCTMgr
, std::move(ISMBuilder
));
913 if (S
.NumCompileThreads
> 0)
914 CODLayer
->setCloneToNewContextOnEmit(true);
917 } // End namespace orc.
918 } // End namespace llvm.