1 //===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===//
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 // JIT layer for breaking up modules and inserting callbacks to allow
10 // individual functions to be compiled on demand.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
17 #include "llvm/ADT/APInt.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/ExecutionEngine/JITSymbol.h"
23 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
24 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
25 #include "llvm/ExecutionEngine/Orc/Layer.h"
26 #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
27 #include "llvm/ExecutionEngine/Orc/Legacy.h"
28 #include "llvm/ExecutionEngine/Orc/OrcError.h"
29 #include "llvm/ExecutionEngine/Orc/Speculation.h"
30 #include "llvm/ExecutionEngine/RuntimeDyld.h"
31 #include "llvm/IR/Attributes.h"
32 #include "llvm/IR/Constant.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/DataLayout.h"
35 #include "llvm/IR/Function.h"
36 #include "llvm/IR/GlobalAlias.h"
37 #include "llvm/IR/GlobalValue.h"
38 #include "llvm/IR/GlobalVariable.h"
39 #include "llvm/IR/Instruction.h"
40 #include "llvm/IR/Mangler.h"
41 #include "llvm/IR/Module.h"
42 #include "llvm/IR/Type.h"
43 #include "llvm/Support/Casting.h"
44 #include "llvm/Support/raw_ostream.h"
45 #include "llvm/Transforms/Utils/ValueMapper.h"
63 class ExtractingIRMaterializationUnit
;
65 class CompileOnDemandLayer
: public IRLayer
{
66 friend class PartitioningIRMaterializationUnit
;
69 /// Builder for IndirectStubsManagers.
70 using IndirectStubsManagerBuilder
=
71 std::function
<std::unique_ptr
<IndirectStubsManager
>()>;
73 using GlobalValueSet
= std::set
<const GlobalValue
*>;
75 /// Partitioning function.
76 using PartitionFunction
=
77 std::function
<Optional
<GlobalValueSet
>(GlobalValueSet Requested
)>;
79 /// Off-the-shelf partitioning which compiles all requested symbols (usually
80 /// a single function at a time).
81 static Optional
<GlobalValueSet
> compileRequested(GlobalValueSet Requested
);
83 /// Off-the-shelf partitioning which compiles whole modules whenever any
84 /// symbol in them is requested.
85 static Optional
<GlobalValueSet
> compileWholeModule(GlobalValueSet Requested
);
87 /// Construct a CompileOnDemandLayer.
88 CompileOnDemandLayer(ExecutionSession
&ES
, IRLayer
&BaseLayer
,
89 LazyCallThroughManager
&LCTMgr
,
90 IndirectStubsManagerBuilder BuildIndirectStubsManager
);
92 /// Sets the partition function.
93 void setPartitionFunction(PartitionFunction Partition
);
95 /// Sets the ImplSymbolMap
96 void setImplMap(ImplSymbolMap
*Imp
);
97 /// Emits the given module. This should not be called by clients: it will be
98 /// called by the JIT when a definition added via the add method is requested.
99 void emit(MaterializationResponsibility R
, ThreadSafeModule TSM
) override
;
102 struct PerDylibResources
{
104 PerDylibResources(JITDylib
&ImplD
,
105 std::unique_ptr
<IndirectStubsManager
> ISMgr
)
106 : ImplD(ImplD
), ISMgr(std::move(ISMgr
)) {}
107 JITDylib
&getImplDylib() { return ImplD
; }
108 IndirectStubsManager
&getISManager() { return *ISMgr
; }
112 std::unique_ptr
<IndirectStubsManager
> ISMgr
;
115 using PerDylibResourcesMap
= std::map
<const JITDylib
*, PerDylibResources
>;
117 PerDylibResources
&getPerDylibResources(JITDylib
&TargetD
);
119 void cleanUpModule(Module
&M
);
121 void expandPartition(GlobalValueSet
&Partition
);
123 void emitPartition(MaterializationResponsibility R
, ThreadSafeModule TSM
,
124 IRMaterializationUnit::SymbolNameToDefinitionMap Defs
);
126 mutable std::mutex CODLayerMutex
;
129 LazyCallThroughManager
&LCTMgr
;
130 IndirectStubsManagerBuilder BuildIndirectStubsManager
;
131 PerDylibResourcesMap DylibResources
;
132 PartitionFunction Partition
= compileRequested
;
133 SymbolLinkagePromoter PromoteSymbols
;
134 ImplSymbolMap
*AliaseeImpls
= nullptr;
137 /// Compile-on-demand layer.
139 /// When a module is added to this layer a stub is created for each of its
140 /// function definitions. The stubs and other global values are immediately
141 /// added to the layer below. When a stub is called it triggers the extraction
142 /// of the function body from the original module. The extracted body is then
143 /// compiled and executed.
144 template <typename BaseLayerT
,
145 typename CompileCallbackMgrT
= JITCompileCallbackManager
,
146 typename IndirectStubsMgrT
= IndirectStubsManager
>
147 class LegacyCompileOnDemandLayer
{
149 template <typename MaterializerFtor
>
150 class LambdaMaterializer final
: public ValueMaterializer
{
152 LambdaMaterializer(MaterializerFtor M
) : M(std::move(M
)) {}
154 Value
*materialize(Value
*V
) final
{ return M(V
); }
160 template <typename MaterializerFtor
>
161 LambdaMaterializer
<MaterializerFtor
>
162 createLambdaMaterializer(MaterializerFtor M
) {
163 return LambdaMaterializer
<MaterializerFtor
>(std::move(M
));
166 // Provide type-erasure for the Modules and MemoryManagers.
167 template <typename ResourceT
>
168 class ResourceOwner
{
170 ResourceOwner() = default;
171 ResourceOwner(const ResourceOwner
&) = delete;
172 ResourceOwner
&operator=(const ResourceOwner
&) = delete;
173 virtual ~ResourceOwner() = default;
175 virtual ResourceT
& getResource() const = 0;
178 template <typename ResourceT
, typename ResourcePtrT
>
179 class ResourceOwnerImpl
: public ResourceOwner
<ResourceT
> {
181 ResourceOwnerImpl(ResourcePtrT ResourcePtr
)
182 : ResourcePtr(std::move(ResourcePtr
)) {}
184 ResourceT
& getResource() const override
{ return *ResourcePtr
; }
187 ResourcePtrT ResourcePtr
;
190 template <typename ResourceT
, typename ResourcePtrT
>
191 std::unique_ptr
<ResourceOwner
<ResourceT
>>
192 wrapOwnership(ResourcePtrT ResourcePtr
) {
193 using RO
= ResourceOwnerImpl
<ResourceT
, ResourcePtrT
>;
194 return std::make_unique
<RO
>(std::move(ResourcePtr
));
197 struct LogicalDylib
{
198 struct SourceModuleEntry
{
199 std::unique_ptr
<Module
> SourceMod
;
200 std::set
<Function
*> StubsToClone
;
203 using SourceModulesList
= std::vector
<SourceModuleEntry
>;
204 using SourceModuleHandle
= typename
SourceModulesList::size_type
;
206 LogicalDylib() = default;
208 LogicalDylib(VModuleKey K
, std::shared_ptr
<SymbolResolver
> BackingResolver
,
209 std::unique_ptr
<IndirectStubsMgrT
> StubsMgr
)
210 : K(std::move(K
)), BackingResolver(std::move(BackingResolver
)),
211 StubsMgr(std::move(StubsMgr
)) {}
213 SourceModuleHandle
addSourceModule(std::unique_ptr
<Module
> M
) {
214 SourceModuleHandle H
= SourceModules
.size();
215 SourceModules
.push_back(SourceModuleEntry());
216 SourceModules
.back().SourceMod
= std::move(M
);
220 Module
& getSourceModule(SourceModuleHandle H
) {
221 return *SourceModules
[H
].SourceMod
;
224 std::set
<Function
*>& getStubsToClone(SourceModuleHandle H
) {
225 return SourceModules
[H
].StubsToClone
;
228 JITSymbol
findSymbol(BaseLayerT
&BaseLayer
, const std::string
&Name
,
229 bool ExportedSymbolsOnly
) {
230 if (auto Sym
= StubsMgr
->findStub(Name
, ExportedSymbolsOnly
))
232 for (auto BLK
: BaseLayerVModuleKeys
)
233 if (auto Sym
= BaseLayer
.findSymbolIn(BLK
, Name
, ExportedSymbolsOnly
))
235 else if (auto Err
= Sym
.takeError())
236 return std::move(Err
);
240 Error
removeModulesFromBaseLayer(BaseLayerT
&BaseLayer
) {
241 for (auto &BLK
: BaseLayerVModuleKeys
)
242 if (auto Err
= BaseLayer
.removeModule(BLK
))
244 return Error::success();
248 std::shared_ptr
<SymbolResolver
> BackingResolver
;
249 std::unique_ptr
<IndirectStubsMgrT
> StubsMgr
;
250 SymbolLinkagePromoter PromoteSymbols
;
251 SourceModulesList SourceModules
;
252 std::vector
<VModuleKey
> BaseLayerVModuleKeys
;
257 /// Module partitioning functor.
258 using PartitioningFtor
= std::function
<std::set
<Function
*>(Function
&)>;
260 /// Builder for IndirectStubsManagers.
261 using IndirectStubsManagerBuilderT
=
262 std::function
<std::unique_ptr
<IndirectStubsMgrT
>()>;
264 using SymbolResolverGetter
=
265 std::function
<std::shared_ptr
<SymbolResolver
>(VModuleKey K
)>;
267 using SymbolResolverSetter
=
268 std::function
<void(VModuleKey K
, std::shared_ptr
<SymbolResolver
> R
)>;
270 /// Construct a compile-on-demand layer instance.
271 LLVM_ATTRIBUTE_DEPRECATED(
272 LegacyCompileOnDemandLayer(
273 ExecutionSession
&ES
, BaseLayerT
&BaseLayer
,
274 SymbolResolverGetter GetSymbolResolver
,
275 SymbolResolverSetter SetSymbolResolver
, PartitioningFtor Partition
,
276 CompileCallbackMgrT
&CallbackMgr
,
277 IndirectStubsManagerBuilderT CreateIndirectStubsManager
,
278 bool CloneStubsIntoPartitions
= true),
279 "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
281 "the ORCv2 LegacyCompileOnDemandLayer instead");
283 /// Legacy layer constructor with deprecation acknowledgement.
284 LegacyCompileOnDemandLayer(
285 ORCv1DeprecationAcknowledgement
, ExecutionSession
&ES
,
286 BaseLayerT
&BaseLayer
, SymbolResolverGetter GetSymbolResolver
,
287 SymbolResolverSetter SetSymbolResolver
, PartitioningFtor Partition
,
288 CompileCallbackMgrT
&CallbackMgr
,
289 IndirectStubsManagerBuilderT CreateIndirectStubsManager
,
290 bool CloneStubsIntoPartitions
= true)
291 : ES(ES
), BaseLayer(BaseLayer
),
292 GetSymbolResolver(std::move(GetSymbolResolver
)),
293 SetSymbolResolver(std::move(SetSymbolResolver
)),
294 Partition(std::move(Partition
)), CompileCallbackMgr(CallbackMgr
),
295 CreateIndirectStubsManager(std::move(CreateIndirectStubsManager
)),
296 CloneStubsIntoPartitions(CloneStubsIntoPartitions
) {}
298 ~LegacyCompileOnDemandLayer() {
299 // FIXME: Report error on log.
300 while (!LogicalDylibs
.empty())
301 consumeError(removeModule(LogicalDylibs
.begin()->first
));
304 /// Add a module to the compile-on-demand layer.
305 Error
addModule(VModuleKey K
, std::unique_ptr
<Module
> M
) {
307 assert(!LogicalDylibs
.count(K
) && "VModuleKey K already in use");
308 auto I
= LogicalDylibs
.insert(
310 std::make_pair(K
, LogicalDylib(K
, GetSymbolResolver(K
),
311 CreateIndirectStubsManager())));
313 return addLogicalModule(I
->second
, std::move(M
));
316 /// Add extra modules to an existing logical module.
317 Error
addExtraModule(VModuleKey K
, std::unique_ptr
<Module
> M
) {
318 return addLogicalModule(LogicalDylibs
[K
], std::move(M
));
321 /// Remove the module represented by the given key.
323 /// This will remove all modules in the layers below that were derived from
324 /// the module represented by K.
325 Error
removeModule(VModuleKey K
) {
326 auto I
= LogicalDylibs
.find(K
);
327 assert(I
!= LogicalDylibs
.end() && "VModuleKey K not valid here");
328 auto Err
= I
->second
.removeModulesFromBaseLayer(BaseLayer
);
329 LogicalDylibs
.erase(I
);
333 /// Search for the given named symbol.
334 /// @param Name The name of the symbol to search for.
335 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
336 /// @return A handle for the given named symbol, if it exists.
337 JITSymbol
findSymbol(StringRef Name
, bool ExportedSymbolsOnly
) {
338 for (auto &KV
: LogicalDylibs
) {
339 if (auto Sym
= KV
.second
.StubsMgr
->findStub(Name
, ExportedSymbolsOnly
))
341 if (auto Sym
= findSymbolIn(KV
.first
, Name
, ExportedSymbolsOnly
))
343 else if (auto Err
= Sym
.takeError())
344 return std::move(Err
);
346 return BaseLayer
.findSymbol(Name
, ExportedSymbolsOnly
);
349 /// Get the address of a symbol provided by this layer, or some layer
351 JITSymbol
findSymbolIn(VModuleKey K
, const std::string
&Name
,
352 bool ExportedSymbolsOnly
) {
353 assert(LogicalDylibs
.count(K
) && "VModuleKey K is not valid here");
354 return LogicalDylibs
[K
].findSymbol(BaseLayer
, Name
, ExportedSymbolsOnly
);
357 /// Update the stub for the given function to point at FnBodyAddr.
358 /// This can be used to support re-optimization.
359 /// @return true if the function exists and the stub is updated, false
362 // FIXME: We should track and free associated resources (unused compile
363 // callbacks, uncompiled IR, and no-longer-needed/reachable function
365 Error
updatePointer(std::string FuncName
, JITTargetAddress FnBodyAddr
) {
366 //Find out which logical dylib contains our symbol
367 auto LDI
= LogicalDylibs
.begin();
368 for (auto LDE
= LogicalDylibs
.end(); LDI
!= LDE
; ++LDI
) {
369 if (auto LMResources
=
370 LDI
->getLogicalModuleResourcesForSymbol(FuncName
, false)) {
371 Module
&SrcM
= LMResources
->SourceModule
->getResource();
372 std::string CalledFnName
= mangle(FuncName
, SrcM
.getDataLayout());
373 if (auto Err
= LMResources
->StubsMgr
->updatePointer(CalledFnName
,
376 return Error::success();
379 return make_error
<JITSymbolNotFound
>(FuncName
);
383 Error
addLogicalModule(LogicalDylib
&LD
, std::unique_ptr
<Module
> SrcMPtr
) {
385 // Rename anonymous globals and promote linkage to ensure that everything
386 // will resolve properly after we partition SrcM.
387 LD
.PromoteSymbols(*SrcMPtr
);
389 // Create a logical module handle for SrcM within the logical dylib.
390 Module
&SrcM
= *SrcMPtr
;
391 auto LMId
= LD
.addSourceModule(std::move(SrcMPtr
));
393 // Create stub functions.
394 const DataLayout
&DL
= SrcM
.getDataLayout();
396 typename
IndirectStubsMgrT::StubInitsMap StubInits
;
397 for (auto &F
: SrcM
) {
398 // Skip declarations.
399 if (F
.isDeclaration())
402 // Skip weak functions for which we already have definitions.
403 auto MangledName
= mangle(F
.getName(), DL
);
404 if (F
.hasWeakLinkage() || F
.hasLinkOnceLinkage()) {
405 if (auto Sym
= LD
.findSymbol(BaseLayer
, MangledName
, false))
407 else if (auto Err
= Sym
.takeError())
408 return std::move(Err
);
411 // Record all functions defined by this module.
412 if (CloneStubsIntoPartitions
)
413 LD
.getStubsToClone(LMId
).insert(&F
);
415 // Create a callback, associate it with the stub for the function,
416 // and set the compile action to compile the partition containing the
418 auto CompileAction
= [this, &LD
, LMId
, &F
]() -> JITTargetAddress
{
419 if (auto FnImplAddrOrErr
= this->extractAndCompile(LD
, LMId
, F
))
420 return *FnImplAddrOrErr
;
422 // FIXME: Report error, return to 'abort' or something similar.
423 consumeError(FnImplAddrOrErr
.takeError());
428 CompileCallbackMgr
.getCompileCallback(std::move(CompileAction
)))
429 StubInits
[MangledName
] =
430 std::make_pair(*CCAddr
, JITSymbolFlags::fromGlobalValue(F
));
432 return CCAddr
.takeError();
435 if (auto Err
= LD
.StubsMgr
->createStubs(StubInits
))
439 // If this module doesn't contain any globals, aliases, or module flags then
440 // we can bail out early and avoid the overhead of creating and managing an
441 // empty globals module.
442 if (SrcM
.global_empty() && SrcM
.alias_empty() &&
443 !SrcM
.getModuleFlagsMetadata())
444 return Error::success();
446 // Create the GlobalValues module.
447 auto GVsM
= std::make_unique
<Module
>((SrcM
.getName() + ".globals").str(),
449 GVsM
->setDataLayout(DL
);
451 ValueToValueMapTy VMap
;
453 // Clone global variable decls.
454 for (auto &GV
: SrcM
.globals())
455 if (!GV
.isDeclaration() && !VMap
.count(&GV
))
456 cloneGlobalVariableDecl(*GVsM
, GV
, &VMap
);
459 for (auto &A
: SrcM
.aliases())
461 cloneGlobalAliasDecl(*GVsM
, A
, VMap
);
463 // Clone the module flags.
464 cloneModuleFlagsMetadata(*GVsM
, SrcM
, VMap
);
466 // Now we need to clone the GV and alias initializers.
468 // Initializers may refer to functions declared (but not defined) in this
469 // module. Build a materializer to clone decls on demand.
470 auto Materializer
= createLambdaMaterializer(
471 [&LD
, &GVsM
](Value
*V
) -> Value
* {
472 if (auto *F
= dyn_cast
<Function
>(V
)) {
473 // Decls in the original module just get cloned.
474 if (F
->isDeclaration())
475 return cloneFunctionDecl(*GVsM
, *F
);
477 // Definitions in the original module (which we have emitted stubs
478 // for at this point) get turned into a constant alias to the stub
480 const DataLayout
&DL
= GVsM
->getDataLayout();
481 std::string FName
= mangle(F
->getName(), DL
);
482 unsigned PtrBitWidth
= DL
.getPointerTypeSizeInBits(F
->getType());
483 JITTargetAddress StubAddr
=
484 LD
.StubsMgr
->findStub(FName
, false).getAddress();
486 ConstantInt
*StubAddrCI
=
487 ConstantInt::get(GVsM
->getContext(), APInt(PtrBitWidth
, StubAddr
));
488 Constant
*Init
= ConstantExpr::getCast(Instruction::IntToPtr
,
489 StubAddrCI
, F
->getType());
490 return GlobalAlias::create(F
->getFunctionType(),
491 F
->getType()->getAddressSpace(),
492 F
->getLinkage(), F
->getName(),
499 // Clone the global variable initializers.
500 for (auto &GV
: SrcM
.globals())
501 if (!GV
.isDeclaration())
502 moveGlobalVariableInitializer(GV
, VMap
, &Materializer
);
504 // Clone the global alias initializers.
505 for (auto &A
: SrcM
.aliases()) {
506 auto *NewA
= cast
<GlobalAlias
>(VMap
[&A
]);
507 assert(NewA
&& "Alias not cloned?");
508 Value
*Init
= MapValue(A
.getAliasee(), VMap
, RF_None
, nullptr,
510 NewA
->setAliasee(cast
<Constant
>(Init
));
513 // Build a resolver for the globals module and add it to the base layer.
514 auto LegacyLookup
= [this, &LD
](const std::string
&Name
) -> JITSymbol
{
515 if (auto Sym
= LD
.StubsMgr
->findStub(Name
, false))
518 if (auto Sym
= LD
.findSymbol(BaseLayer
, Name
, false))
520 else if (auto Err
= Sym
.takeError())
521 return std::move(Err
);
526 auto GVsResolver
= createSymbolResolver(
527 [&LD
, LegacyLookup
](const SymbolNameSet
&Symbols
) {
528 auto RS
= getResponsibilitySetWithLegacyFn(Symbols
, LegacyLookup
);
531 logAllUnhandledErrors(
532 RS
.takeError(), errs(),
533 "CODLayer/GVsResolver responsibility set lookup failed: ");
534 return SymbolNameSet();
537 if (RS
->size() == Symbols
.size())
540 SymbolNameSet NotFoundViaLegacyLookup
;
541 for (auto &S
: Symbols
)
543 NotFoundViaLegacyLookup
.insert(S
);
545 LD
.BackingResolver
->getResponsibilitySet(NotFoundViaLegacyLookup
);
553 LegacyLookup
](std::shared_ptr
<AsynchronousSymbolQuery
> Query
,
554 SymbolNameSet Symbols
) {
555 auto NotFoundViaLegacyLookup
=
556 lookupWithLegacyFn(ES
, *Query
, Symbols
, LegacyLookup
);
557 return LD
.BackingResolver
->lookup(Query
, NotFoundViaLegacyLookup
);
560 SetSymbolResolver(LD
.K
, std::move(GVsResolver
));
562 if (auto Err
= BaseLayer
.addModule(LD
.K
, std::move(GVsM
)))
565 LD
.BaseLayerVModuleKeys
.push_back(LD
.K
);
567 return Error::success();
570 static std::string
mangle(StringRef Name
, const DataLayout
&DL
) {
571 std::string MangledName
;
573 raw_string_ostream
MangledNameStream(MangledName
);
574 Mangler::getNameWithPrefix(MangledNameStream
, Name
, DL
);
579 Expected
<JITTargetAddress
>
580 extractAndCompile(LogicalDylib
&LD
,
581 typename
LogicalDylib::SourceModuleHandle LMId
,
583 Module
&SrcM
= LD
.getSourceModule(LMId
);
585 // If F is a declaration we must already have compiled it.
586 if (F
.isDeclaration())
589 // Grab the name of the function being called here.
590 std::string CalledFnName
= mangle(F
.getName(), SrcM
.getDataLayout());
592 JITTargetAddress CalledAddr
= 0;
593 auto Part
= Partition(F
);
594 if (auto PartKeyOrErr
= emitPartition(LD
, LMId
, Part
)) {
595 auto &PartKey
= *PartKeyOrErr
;
596 for (auto *SubF
: Part
) {
597 std::string FnName
= mangle(SubF
->getName(), SrcM
.getDataLayout());
598 if (auto FnBodySym
= BaseLayer
.findSymbolIn(PartKey
, FnName
, false)) {
599 if (auto FnBodyAddrOrErr
= FnBodySym
.getAddress()) {
600 JITTargetAddress FnBodyAddr
= *FnBodyAddrOrErr
;
602 // If this is the function we're calling record the address so we can
603 // return it from this function.
605 CalledAddr
= FnBodyAddr
;
607 // Update the function body pointer for the stub.
608 if (auto EC
= LD
.StubsMgr
->updatePointer(FnName
, FnBodyAddr
))
612 return FnBodyAddrOrErr
.takeError();
613 } else if (auto Err
= FnBodySym
.takeError())
614 return std::move(Err
);
616 llvm_unreachable("Function not emitted for partition");
619 LD
.BaseLayerVModuleKeys
.push_back(PartKey
);
621 return PartKeyOrErr
.takeError();
626 template <typename PartitionT
>
628 emitPartition(LogicalDylib
&LD
,
629 typename
LogicalDylib::SourceModuleHandle LMId
,
630 const PartitionT
&Part
) {
631 Module
&SrcM
= LD
.getSourceModule(LMId
);
633 // Create the module.
634 std::string NewName
= SrcM
.getName();
635 for (auto *F
: Part
) {
637 NewName
+= F
->getName();
640 auto M
= std::make_unique
<Module
>(NewName
, SrcM
.getContext());
641 M
->setDataLayout(SrcM
.getDataLayout());
642 ValueToValueMapTy VMap
;
644 auto Materializer
= createLambdaMaterializer([&LD
, &LMId
,
645 &M
](Value
*V
) -> Value
* {
646 if (auto *GV
= dyn_cast
<GlobalVariable
>(V
))
647 return cloneGlobalVariableDecl(*M
, *GV
);
649 if (auto *F
= dyn_cast
<Function
>(V
)) {
650 // Check whether we want to clone an available_externally definition.
651 if (!LD
.getStubsToClone(LMId
).count(F
))
652 return cloneFunctionDecl(*M
, *F
);
654 // Ok - we want an inlinable stub. For that to work we need a decl
655 // for the stub pointer.
656 auto *StubPtr
= createImplPointer(*F
->getType(), *M
,
657 F
->getName() + "$stub_ptr", nullptr);
658 auto *ClonedF
= cloneFunctionDecl(*M
, *F
);
659 makeStub(*ClonedF
, *StubPtr
);
660 ClonedF
->setLinkage(GlobalValue::AvailableExternallyLinkage
);
661 ClonedF
->addFnAttr(Attribute::AlwaysInline
);
665 if (auto *A
= dyn_cast
<GlobalAlias
>(V
)) {
666 auto *Ty
= A
->getValueType();
667 if (Ty
->isFunctionTy())
668 return Function::Create(cast
<FunctionType
>(Ty
),
669 GlobalValue::ExternalLinkage
, A
->getName(),
672 return new GlobalVariable(*M
, Ty
, false, GlobalValue::ExternalLinkage
,
673 nullptr, A
->getName(), nullptr,
674 GlobalValue::NotThreadLocal
,
675 A
->getType()->getAddressSpace());
681 // Create decls in the new module.
683 cloneFunctionDecl(*M
, *F
, &VMap
);
685 // Move the function bodies.
687 moveFunctionBody(*F
, VMap
, &Materializer
);
689 auto K
= ES
.allocateVModule();
691 auto LegacyLookup
= [this, &LD
](const std::string
&Name
) -> JITSymbol
{
692 return LD
.findSymbol(BaseLayer
, Name
, false);
695 // Create memory manager and symbol resolver.
696 auto Resolver
= createSymbolResolver(
697 [&LD
, LegacyLookup
](const SymbolNameSet
&Symbols
) {
698 auto RS
= getResponsibilitySetWithLegacyFn(Symbols
, LegacyLookup
);
700 logAllUnhandledErrors(
701 RS
.takeError(), errs(),
702 "CODLayer/SubResolver responsibility set lookup failed: ");
703 return SymbolNameSet();
706 if (RS
->size() == Symbols
.size())
709 SymbolNameSet NotFoundViaLegacyLookup
;
710 for (auto &S
: Symbols
)
712 NotFoundViaLegacyLookup
.insert(S
);
715 LD
.BackingResolver
->getResponsibilitySet(NotFoundViaLegacyLookup
);
722 [this, &LD
, LegacyLookup
](std::shared_ptr
<AsynchronousSymbolQuery
> Q
,
723 SymbolNameSet Symbols
) {
724 auto NotFoundViaLegacyLookup
=
725 lookupWithLegacyFn(ES
, *Q
, Symbols
, LegacyLookup
);
726 return LD
.BackingResolver
->lookup(Q
,
727 std::move(NotFoundViaLegacyLookup
));
729 SetSymbolResolver(K
, std::move(Resolver
));
731 if (auto Err
= BaseLayer
.addModule(std::move(K
), std::move(M
)))
732 return std::move(Err
);
737 ExecutionSession
&ES
;
738 BaseLayerT
&BaseLayer
;
739 SymbolResolverGetter GetSymbolResolver
;
740 SymbolResolverSetter SetSymbolResolver
;
741 PartitioningFtor Partition
;
742 CompileCallbackMgrT
&CompileCallbackMgr
;
743 IndirectStubsManagerBuilderT CreateIndirectStubsManager
;
745 std::map
<VModuleKey
, LogicalDylib
> LogicalDylibs
;
746 bool CloneStubsIntoPartitions
;
749 template <typename BaseLayerT
, typename CompileCallbackMgrT
,
750 typename IndirectStubsMgrT
>
751 LegacyCompileOnDemandLayer
<BaseLayerT
, CompileCallbackMgrT
, IndirectStubsMgrT
>::
752 LegacyCompileOnDemandLayer(
753 ExecutionSession
&ES
, BaseLayerT
&BaseLayer
,
754 SymbolResolverGetter GetSymbolResolver
,
755 SymbolResolverSetter SetSymbolResolver
, PartitioningFtor Partition
,
756 CompileCallbackMgrT
&CallbackMgr
,
757 IndirectStubsManagerBuilderT CreateIndirectStubsManager
,
758 bool CloneStubsIntoPartitions
)
759 : ES(ES
), BaseLayer(BaseLayer
),
760 GetSymbolResolver(std::move(GetSymbolResolver
)),
761 SetSymbolResolver(std::move(SetSymbolResolver
)),
762 Partition(std::move(Partition
)), CompileCallbackMgr(CallbackMgr
),
763 CreateIndirectStubsManager(std::move(CreateIndirectStubsManager
)),
764 CloneStubsIntoPartitions(CloneStubsIntoPartitions
) {}
766 } // end namespace orc
767 } // end namespace llvm
769 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H