15 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 16 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H 63 class ExtractingIRMaterializationUnit;
71 std::function<std::unique_ptr<IndirectStubsManager>()>;
100 struct PerDylibResources {
103 std::unique_ptr<IndirectStubsManager> ISMgr)
104 : ImplD(ImplD), ISMgr(
std::move(ISMgr)) {}
105 JITDylib &getImplDylib() {
return ImplD; }
110 std::unique_ptr<IndirectStubsManager> ISMgr;
113 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>;
115 PerDylibResources &getPerDylibResources(
JITDylib &TargetD);
117 void cleanUpModule(
Module &M);
124 mutable std::mutex CODLayerMutex;
129 PerDylibResourcesMap DylibResources;
141 template <
typename BaseLayerT,
146 template <
typename MaterializerFtor>
149 LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
151 Value *materialize(
Value *V)
final {
return M(V); }
157 template <
typename MaterializerFtor>
158 LambdaMaterializer<MaterializerFtor>
159 createLambdaMaterializer(MaterializerFtor M) {
160 return LambdaMaterializer<MaterializerFtor>(std::move(M));
164 template <
typename ResourceT>
165 class ResourceOwner {
167 ResourceOwner() =
default;
168 ResourceOwner(
const ResourceOwner &) =
delete;
169 ResourceOwner &operator=(
const ResourceOwner &) =
delete;
170 virtual ~ResourceOwner() =
default;
172 virtual ResourceT& getResource()
const = 0;
175 template <
typename ResourceT,
typename ResourcePtrT>
176 class ResourceOwnerImpl :
public ResourceOwner<ResourceT> {
178 ResourceOwnerImpl(ResourcePtrT ResourcePtr)
179 : ResourcePtr(std::move(ResourcePtr)) {}
181 ResourceT& getResource()
const override {
return *ResourcePtr; }
184 ResourcePtrT ResourcePtr;
187 template <
typename ResourceT,
typename ResourcePtrT>
188 std::unique_ptr<ResourceOwner<ResourceT>>
189 wrapOwnership(ResourcePtrT ResourcePtr) {
190 using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
191 return llvm::make_unique<RO>(std::move(ResourcePtr));
194 struct LogicalDylib {
200 using SourceModulesList = std::vector<SourceModuleEntry>;
201 using SourceModuleHandle =
typename SourceModulesList::size_type;
203 LogicalDylib() =
default;
205 LogicalDylib(
VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
206 std::unique_ptr<IndirectStubsMgrT> StubsMgr)
207 : K(
std::move(K)), BackingResolver(
std::move(BackingResolver)),
208 StubsMgr(
std::move(StubsMgr)) {}
210 SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
211 SourceModuleHandle
H = SourceModules.size();
213 SourceModules.back().SourceMod = std::move(M);
217 Module& getSourceModule(SourceModuleHandle
H) {
218 return *SourceModules[
H].SourceMod;
221 std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
222 return SourceModules[
H].StubsToClone;
225 JITSymbol findSymbol(BaseLayerT &BaseLayer,
const std::string &
Name,
226 bool ExportedSymbolsOnly) {
227 if (
auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
229 for (
auto BLK : BaseLayerVModuleKeys)
230 if (
auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
232 else if (
auto Err = Sym.takeError())
233 return std::move(Err);
237 Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
238 for (
auto &BLK : BaseLayerVModuleKeys)
239 if (
auto Err = BaseLayer.removeModule(BLK))
245 std::shared_ptr<SymbolResolver> BackingResolver;
246 std::unique_ptr<IndirectStubsMgrT> StubsMgr;
248 SourceModulesList SourceModules;
249 std::vector<VModuleKey> BaseLayerVModuleKeys;
259 std::function<std::unique_ptr<IndirectStubsMgrT>()>;
262 std::function<std::shared_ptr<SymbolResolver>(
VModuleKey K)>;
265 std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
269 SymbolResolverGetter GetSymbolResolver,
270 SymbolResolverSetter SetSymbolResolver,
272 CompileCallbackMgrT &CallbackMgr,
273 IndirectStubsManagerBuilderT CreateIndirectStubsManager,
274 bool CloneStubsIntoPartitions =
true)
275 : ES(ES), BaseLayer(BaseLayer),
276 GetSymbolResolver(
std::move(GetSymbolResolver)),
277 SetSymbolResolver(
std::move(SetSymbolResolver)),
278 Partition(
std::move(Partition)), CompileCallbackMgr(CallbackMgr),
279 CreateIndirectStubsManager(
std::move(CreateIndirectStubsManager)),
280 CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
284 while (!LogicalDylibs.empty())
285 consumeError(removeModule(LogicalDylibs.begin()->first));
291 assert(!LogicalDylibs.count(K) &&
"VModuleKey K already in use");
292 auto I = LogicalDylibs.insert(
294 std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
295 CreateIndirectStubsManager())));
297 return addLogicalModule(I->second, std::move(M));
302 return addLogicalModule(LogicalDylibs[K], std::move(M));
310 auto I = LogicalDylibs.find(K);
311 assert(
I != LogicalDylibs.end() &&
"VModuleKey K not valid here");
312 auto Err =
I->second.removeModulesFromBaseLayer(BaseLayer);
313 LogicalDylibs.erase(
I);
322 for (
auto &KV : LogicalDylibs) {
323 if (
auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
325 if (
auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
327 else if (
auto Err = Sym.takeError())
328 return std::move(Err);
330 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
336 bool ExportedSymbolsOnly) {
337 assert(LogicalDylibs.count(K) &&
"VModuleKey K is not valid here");
338 return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
351 auto LDI = LogicalDylibs.begin();
352 for (
auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
353 if (
auto LMResources =
354 LDI->getLogicalModuleResourcesForSymbol(FuncName,
false)) {
355 Module &SrcM = LMResources->SourceModule->getResource();
356 std::string CalledFnName = mangle(FuncName, SrcM.
getDataLayout());
357 if (
auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
363 return make_error<JITSymbolNotFound>(FuncName);
367 Error addLogicalModule(LogicalDylib &
LD, std::unique_ptr<Module> SrcMPtr) {
371 LD.PromoteSymbols(*SrcMPtr);
375 auto LMId = LD.addSourceModule(std::move(SrcMPtr));
380 typename IndirectStubsMgrT::StubInitsMap StubInits;
381 for (
auto &
F : SrcM) {
383 if (
F.isDeclaration())
387 auto MangledName = mangle(
F.getName(), DL);
388 if (
F.hasWeakLinkage() ||
F.hasLinkOnceLinkage()) {
389 if (
auto Sym = LD.findSymbol(BaseLayer, MangledName,
false))
391 else if (
auto Err = Sym.takeError())
392 return std::move(Err);
396 if (CloneStubsIntoPartitions)
397 LD.getStubsToClone(LMId).insert(&
F);
403 if (
auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId,
F))
404 return *FnImplAddrOrErr;
412 CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
413 StubInits[MangledName] =
416 return CCAddr.takeError();
419 if (
auto Err = LD.StubsMgr->createStubs(StubInits))
431 auto GVsM = llvm::make_unique<Module>((SrcM.
getName() +
".globals").str(),
433 GVsM->setDataLayout(DL);
438 for (
auto &GV : SrcM.
globals())
439 if (!GV.isDeclaration() && !VMap.
count(&GV))
454 auto Materializer = createLambdaMaterializer(
456 if (
auto *
F = dyn_cast<Function>(V)) {
458 if (
F->isDeclaration())
465 std::string FName = mangle(
F->getName(), DL);
468 LD.StubsMgr->findStub(FName,
false).getAddress();
473 StubAddrCI,
F->getType());
475 F->getType()->getAddressSpace(),
476 F->getLinkage(),
F->getName(),
484 for (
auto &GV : SrcM.
globals())
485 if (!GV.isDeclaration())
489 for (
auto &A : SrcM.
aliases()) {
490 auto *NewA = cast<GlobalAlias>(VMap[&A]);
491 assert(NewA &&
"Alias not cloned?");
494 NewA->setAliasee(cast<Constant>(Init));
498 auto LegacyLookup = [
this, &
LD](
const std::string &
Name) ->
JITSymbol {
499 if (
auto Sym = LD.StubsMgr->findStub(
Name,
false))
502 if (
auto Sym = LD.findSymbol(BaseLayer,
Name,
false))
504 else if (
auto Err = Sym.takeError())
505 return std::move(Err);
516 RS.takeError(),
errs(),
517 "CODLayer/GVsResolver responsibility set lookup failed: ");
521 if (RS->size() == Symbols.
size())
525 for (
auto &S : Symbols)
527 NotFoundViaLegacyLookup.
insert(S);
529 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
537 LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery>
Query,
539 auto NotFoundViaLegacyLookup =
541 return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
544 SetSymbolResolver(LD.K, std::move(GVsResolver));
546 if (
auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
549 LD.BaseLayerVModuleKeys.push_back(LD.K);
555 std::string MangledName;
564 extractAndCompile(LogicalDylib &LD,
565 typename LogicalDylib::SourceModuleHandle LMId,
567 Module &SrcM = LD.getSourceModule(LMId);
577 auto Part = Partition(F);
578 if (
auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
579 auto &PartKey = *PartKeyOrErr;
580 for (
auto *SubF : Part) {
581 std::string FnName = mangle(SubF->getName(), SrcM.
getDataLayout());
582 if (
auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName,
false)) {
583 if (
auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
589 CalledAddr = FnBodyAddr;
592 if (
auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
596 return FnBodyAddrOrErr.takeError();
597 }
else if (
auto Err = FnBodySym.takeError())
598 return std::move(Err);
603 LD.BaseLayerVModuleKeys.push_back(PartKey);
605 return PartKeyOrErr.takeError();
610 template <
typename PartitionT>
612 emitPartition(LogicalDylib &LD,
613 typename LogicalDylib::SourceModuleHandle LMId,
614 const PartitionT &Part) {
615 Module &SrcM = LD.getSourceModule(LMId);
618 std::string NewName = SrcM.
getName();
619 for (
auto *F : Part) {
624 auto M = llvm::make_unique<Module>(NewName, SrcM.
getContext());
628 auto Materializer = createLambdaMaterializer([&LD, &LMId,
630 if (
auto *GV = dyn_cast<GlobalVariable>(V))
633 if (
auto *F = dyn_cast<Function>(V)) {
635 if (!LD.getStubsToClone(LMId).count(F))
641 F->
getName() +
"$stub_ptr",
nullptr);
649 if (
auto *A = dyn_cast<GlobalAlias>(V)) {
650 auto *Ty = A->getValueType();
651 if (Ty->isFunctionTy())
657 nullptr, A->getName(),
nullptr,
659 A->getType()->getAddressSpace());
673 auto K = ES.allocateVModule();
675 auto LegacyLookup = [
this, &
LD](
const std::string &
Name) ->
JITSymbol {
676 return LD.findSymbol(BaseLayer, Name,
false);
685 RS.takeError(),
errs(),
686 "CODLayer/SubResolver responsibility set lookup failed: ");
690 if (RS->size() == Symbols.
size())
694 for (
auto &S : Symbols)
696 NotFoundViaLegacyLookup.
insert(S);
699 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
706 [
this, &
LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
708 auto NotFoundViaLegacyLookup =
710 return LD.BackingResolver->lookup(Q,
711 std::move(NotFoundViaLegacyLookup));
713 SetSymbolResolver(K, std::move(
Resolver));
715 if (
auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
716 return std::move(Err);
722 BaseLayerT &BaseLayer;
723 SymbolResolverGetter GetSymbolResolver;
724 SymbolResolverSetter SetSymbolResolver;
726 CompileCallbackMgrT &CompileCallbackMgr;
727 IndirectStubsManagerBuilderT CreateIndirectStubsManager;
729 std::map<VModuleKey, LogicalDylib> LogicalDylibs;
730 bool CloneStubsIntoPartitions;
737 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H A parsed version of the target data layout string in and methods for querying it. ...
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Base class for managing collections of named indirect stubs.
Error removeModule(VModuleKey K)
Remove the module represented by the given key.
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV)
Construct a JITSymbolFlags value based on the flags of the given global value.
Represents a symbol in the JIT.
This class represents lattice values for constants.
GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
A Module instance is used to store all the information related to an LLVM module. ...
static Optional< GlobalValueSet > compileRequested(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles all requested symbols (usually a single function at a time)...
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
Available for inspection, not emission.
bool global_empty() const
Externally visible function.
StringRef getName() const
Get a short "name" for the module.
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
std::function< std::unique_ptr< IndirectStubsManager >()> IndirectStubsManagerBuilder
Builder for IndirectStubsManagers.
Target-independent base class for compile callback management.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
~LegacyCompileOnDemandLayer()
unsigned getPointerTypeSizeInBits(Type *) const
Layout pointer size, in bits, based on the type.
std::unique_ptr< LambdaSymbolResolver< typename std::remove_cv< typename std::remove_reference< GetResponsibilitySetFn >::type >::type, typename std::remove_cv< typename std::remove_reference< LookupFn >::type >::type > > createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet, LookupFn &&Lookup)
Creates a SymbolResolver implementation from the pair of supplied function objects.
GlobalVariable * createImplPointer(PointerType &PT, Module &M, const Twine &Name, Constant *Initializer)
Create a function pointer with the given type, name, and initializer in the given Module...
LLVMContext & getContext() const
Get the global data context.
std::function< Optional< GlobalValueSet >(GlobalValueSet Requested)> PartitionFunction
Partitioning function.
This file contains the simple types necessary to represent the attributes associated with functions a...
void moveGlobalVariableInitializer(GlobalVariable &OrigGV, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, GlobalVariable *NewGV=nullptr)
Move global variable GV from its parent module to cloned global declaration in a different module...
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, bool ExportedSymbolsOnly)
Get the address of a symbol provided by this layer, or some layer below this one. ...
Tagged union holding either a T or a Error.
This file implements a class to represent arbitrary precision integral constant values and operations...
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Error addModule(VModuleKey K, std::unique_ptr< Module > M)
Add a module to the compile-on-demand layer.
Expected< SymbolNameSet > getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols, FindSymbolFn FindSymbol)
Use the given legacy-style FindSymbol function (i.e.
Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr)
Update the stub for the given function to point at FnBodyAddr.
uint64_t JITTargetAddress
Represents an address in the target process's address space.
std::function< void(VModuleKey K, std::shared_ptr< SymbolResolver > R)> SymbolResolverSetter
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
This is a class that can be implemented by clients to materialize Values on demand.
void getModuleFlagsMetadata(SmallVectorImpl< ModuleFlagEntry > &Flags) const
Returns the module flags in the provided vector.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
std::pair< iterator, bool > insert(const ValueT &V)
Error addExtraModule(VModuleKey K, std::unique_ptr< Module > M)
Add extra modules to an existing logical module.
SymbolNameSet lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, const SymbolNameSet &Symbols, FindSymbolFn FindSymbol)
Use the given legacy-style FindSymbol function (i.e.
std::function< std::shared_ptr< SymbolResolver >(VModuleKey K)> SymbolResolverGetter
An LLVM Module together with a shared ThreadSafeContext.
std::unique_ptr< Module > SourceMod
void consumeError(Error Err)
Consume a Error without doing anything.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Look up or compute a value in the value map.
Interface for layers that accept LLVM IR.
static ErrorSuccess success()
Create a success value.
This is the shared class of boolean and integer constants.
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
Module.h This file contains the declarations for the Module class.
static Optional< GlobalValueSet > compileWholeModule(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles whole modules whenever any symbol in them is requested...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
An ExecutionSession represents a running JIT program.
Class for arbitrary precision integers.
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr, IndirectStubsManagerBuilder BuildIndirectStubsManager)
Construct a CompileOnDemandLayer.
std::function< std::set< Function * >(Function &)> PartitioningFtor
Module partitioning functor.
std::set< Function * > StubsToClone
StringRef getName() const
Return a constant reference to the value's name.
void setPartitionFunction(PartitionFunction Partition)
Sets the partition function.
static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly)
Search for the given named symbol.
LegacyCompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver, SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, CompileCallbackMgrT &CallbackMgr, IndirectStubsManagerBuilderT CreateIndirectStubsManager, bool CloneStubsIntoPartitions=true)
Construct a compile-on-demand layer instance.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
LLVM Value Representation.
std::function< std::unique_ptr< IndirectStubsMgrT >()> IndirectStubsManagerBuilderT
Builder for IndirectStubsManagers.
Manages a set of 'lazy call-through' trampolines.
Lightweight error class with error context and mandatory checking.
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
iterator_range< global_iterator > globals()
StringRef - Represent a constant reference to a string, i.e.
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override
Emits the given module.
void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, Function *NewF=nullptr)
Move the body of function 'F' to a cloned function declaration in a different module (See related clo...
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
PointerType * getType() const
Global values are always pointers.
std::set< const GlobalValue * > GlobalValueSet
A symbol table that supports asynchoronous symbol queries.
iterator_range< alias_iterator > aliases()