15 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
16 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
58 template <
typename BaseLayerT,
63 template <
typename MaterializerFtor>
66 LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
68 Value *materialize(
Value *V)
final {
return M(V); }
74 template <
typename MaterializerFtor>
75 LambdaMaterializer<MaterializerFtor>
76 createLambdaMaterializer(MaterializerFtor M) {
77 return LambdaMaterializer<MaterializerFtor>(std::move(M));
80 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
83 template <
typename ResourceT>
86 ResourceOwner() =
default;
87 ResourceOwner(
const ResourceOwner&) =
delete;
88 ResourceOwner& operator=(
const ResourceOwner&) =
delete;
89 virtual ~ResourceOwner() =
default;
91 virtual ResourceT& getResource()
const = 0;
94 template <
typename ResourceT,
typename ResourcePtrT>
95 class ResourceOwnerImpl :
public ResourceOwner<ResourceT> {
97 ResourceOwnerImpl(ResourcePtrT ResourcePtr)
98 : ResourcePtr(std::move(ResourcePtr)) {}
100 ResourceT& getResource()
const override {
return *ResourcePtr; }
103 ResourcePtrT ResourcePtr;
106 template <
typename ResourceT,
typename ResourcePtrT>
107 std::unique_ptr<ResourceOwner<ResourceT>>
108 wrapOwnership(ResourcePtrT ResourcePtr) {
109 typedef ResourceOwnerImpl<ResourceT, ResourcePtrT> RO;
110 return llvm::make_unique<RO>(std::move(ResourcePtr));
113 class StaticGlobalRenamer {
115 StaticGlobalRenamer() =
default;
116 StaticGlobalRenamer(StaticGlobalRenamer &&) =
default;
117 StaticGlobalRenamer &operator=(StaticGlobalRenamer &&) =
default;
121 if (
F.hasLocalLinkage())
122 F.setName(
"$static." +
Twine(NextId++));
123 for (
auto &
G : M.globals())
124 if (
G.hasLocalLinkage())
125 G.setName(
"$static." +
Twine(NextId++));
132 struct LogicalDylib {
133 typedef std::function<JITSymbol(const std::string&)> SymbolResolverFtor;
137 std::unique_ptr<Module>,
138 std::unique_ptr<JITSymbolResolver>)>
146 typedef std::vector<SourceModuleEntry> SourceModulesList;
147 typedef typename SourceModulesList::size_type SourceModuleHandle;
150 addSourceModule(std::unique_ptr<ResourceOwner<Module>> M) {
151 SourceModuleHandle
H = SourceModules.size();
153 SourceModules.back().SourceMod = std::move(M);
157 Module& getSourceModule(SourceModuleHandle
H) {
158 return SourceModules[
H].SourceMod->getResource();
161 std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
162 return SourceModules[
H].StubsToClone;
166 bool ExportedSymbolsOnly) {
167 if (
auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
169 for (
auto BLH : BaseLayerHandles)
170 if (
auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
175 std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver;
176 std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
177 std::unique_ptr<IndirectStubsMgrT> StubsMgr;
178 StaticGlobalRenamer StaticRenamer;
179 ModuleAdderFtor ModuleAdder;
180 SourceModulesList SourceModules;
181 std::vector<BaseLayerModuleSetHandleT> BaseLayerHandles;
184 typedef std::list<LogicalDylib> LogicalDylibList;
194 typedef std::function<std::unique_ptr<IndirectStubsMgrT>()>
199 CompileCallbackMgrT &CallbackMgr,
201 bool CloneStubsIntoPartitions =
true)
202 : BaseLayer(BaseLayer), Partition(std::move(Partition)),
203 CompileCallbackMgr(CallbackMgr),
204 CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
205 CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
208 template <
typename ModuleSetT,
typename MemoryManagerPtrT,
209 typename SymbolResolverPtrT>
211 MemoryManagerPtrT MemMgr,
212 SymbolResolverPtrT Resolver) {
214 LogicalDylibs.push_back(LogicalDylib());
215 auto &
LD = LogicalDylibs.back();
216 LD.ExternalSymbolResolver = std::move(Resolver);
217 LD.StubsMgr = CreateIndirectStubsManager();
219 auto &MemMgrRef = *MemMgr;
220 LD.MemMgr = wrapOwnership<RuntimeDyld::MemoryManager>(std::move(MemMgr));
223 [&MemMgrRef](BaseLayerT &
B, std::unique_ptr<Module> M,
224 std::unique_ptr<JITSymbolResolver> R) {
225 std::vector<std::unique_ptr<Module>> Ms;
226 Ms.push_back(std::move(M));
227 return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R));
232 addLogicalModule(LogicalDylibs.back(), std::move(M));
234 return std::prev(LogicalDylibs.end());
242 LogicalDylibs.erase(H);
250 for (
auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
252 if (
auto Sym = LDI->StubsMgr->findStub(Name, ExportedSymbolsOnly))
254 if (
auto Sym =
findSymbolIn(LDI, Name, ExportedSymbolsOnly))
257 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
263 bool ExportedSymbolsOnly) {
264 return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
278 auto LDI = LogicalDylibs.begin();
279 for (
auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
280 if (
auto LMResources = LDI->getLogicalModuleResourcesForSymbol(FuncName,
false)) {
281 Module &SrcM = LMResources->SourceModule->getResource();
282 std::string CalledFnName = mangle(FuncName, SrcM.
getDataLayout());
283 if (
auto EC = LMResources->StubsMgr->updatePointer(CalledFnName, FnBodyAddr))
293 template <
typename ModulePtrT>
294 void addLogicalModule(LogicalDylib &
LD, ModulePtrT SrcMPtr) {
299 LD.StaticRenamer.rename(*SrcMPtr);
307 auto LMId = LD.addSourceModule(wrapOwnership<Module>(std::move(SrcMPtr)));
312 typename IndirectStubsMgrT::StubInitsMap StubInits;
313 for (
auto &
F : SrcM) {
315 if (
F.isDeclaration())
319 auto MangledName = mangle(
F.getName(), DL);
320 if (
F.hasWeakLinkage() ||
F.hasLinkOnceLinkage())
321 if (
auto Sym = LD.findSymbol(BaseLayer, MangledName,
false))
325 if (CloneStubsIntoPartitions)
326 LD.getStubsToClone(LMId).insert(&
F);
331 auto CCInfo = CompileCallbackMgr.getCompileCallback();
332 StubInits[MangledName] =
333 std::make_pair(CCInfo.getAddress(),
335 CCInfo.setCompileAction([
this, &LD, LMId, &
F]() {
336 return this->extractAndCompile(LD, LMId,
F);
340 auto EC = LD.StubsMgr->createStubs(StubInits);
344 assert(!EC &&
"Error generating stubs");
350 if (SrcM.global_empty() && SrcM.alias_empty() &&
351 !SrcM.getModuleFlagsMetadata())
355 auto GVsM = llvm::make_unique<Module>((SrcM.getName() +
".globals").str(),
357 GVsM->setDataLayout(DL);
362 for (
auto &GV : SrcM.globals())
363 if (!GV.isDeclaration() && !VMap.count(&GV))
367 for (
auto &
A : SrcM.aliases())
378 auto Materializer = createLambdaMaterializer(
379 [
this, &LD, &GVsM](Value *V) -> Value* {
380 if (
auto *
F = dyn_cast<Function>(V)) {
382 if (
F->isDeclaration())
388 const DataLayout &DL = GVsM->getDataLayout();
389 std::string FName = mangle(
F->getName(), DL);
390 auto StubSym = LD.StubsMgr->findStub(FName,
false);
391 unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(
F->getType());
392 ConstantInt *StubAddr =
394 APInt(PtrBitWidth, StubSym.getAddress()));
396 StubAddr,
F->getType());
398 F->getType()->getAddressSpace(),
399 F->getLinkage(),
F->getName(),
407 for (
auto &GV : SrcM.globals())
408 if (!GV.isDeclaration())
412 for (
auto &
A : SrcM.aliases()) {
413 auto *NewA = cast<GlobalAlias>(VMap[&
A]);
414 assert(NewA &&
"Alias not cloned?");
417 NewA->setAliasee(cast<Constant>(Init));
422 [
this, &LD, LMId](
const std::string &Name) {
423 if (
auto Sym = LD.StubsMgr->findStub(Name,
false))
425 if (
auto Sym = LD.findSymbol(BaseLayer, Name,
false))
427 return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
429 [&
LD](
const std::string &
Name) {
430 return LD.ExternalSymbolResolver->findSymbol(Name);
433 auto GVsH = LD.ModuleAdder(BaseLayer, std::move(GVsM),
434 std::move(GVsResolver));
435 LD.BaseLayerHandles.push_back(GVsH);
438 static std::string mangle(StringRef Name,
const DataLayout &DL) {
439 std::string MangledName;
441 raw_string_ostream MangledNameStream(MangledName);
448 extractAndCompile(LogicalDylib &LD,
449 typename LogicalDylib::SourceModuleHandle LMId,
451 Module &SrcM = LD.getSourceModule(LMId);
454 if (F.isDeclaration())
458 std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
460 auto Part = Partition(F);
461 auto PartH = emitPartition(LD, LMId, Part);
464 for (
auto *SubF : Part) {
465 std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
466 auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName,
false);
467 assert(FnBodySym &&
"Couldn't find function body.");
474 CalledAddr = FnBodyAddr;
477 if (
auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
484 template <
typename PartitionT>
485 BaseLayerModuleSetHandleT
486 emitPartition(LogicalDylib &LD,
487 typename LogicalDylib::SourceModuleHandle LMId,
488 const PartitionT &Part) {
489 Module &SrcM = LD.getSourceModule(LMId);
492 std::string NewName = SrcM.getName();
493 for (
auto *F : Part) {
495 NewName += F->getName();
498 auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
499 M->setDataLayout(SrcM.getDataLayout());
502 auto Materializer = createLambdaMaterializer([
this, &LD, &LMId, &M,
503 &VMap](Value *V) -> Value * {
504 if (
auto *GV = dyn_cast<GlobalVariable>(V))
507 if (
auto *F = dyn_cast<Function>(V)) {
509 if (!LD.getStubsToClone(LMId).count(F))
515 F->getName() +
"$stub_ptr",
nullptr);
519 ClonedF->addFnAttr(Attribute::AlwaysInline);
523 if (
auto *
A = dyn_cast<GlobalAlias>(V)) {
524 auto *Ty =
A->getValueType();
525 if (Ty->isFunctionTy())
531 nullptr,
A->getName(),
nullptr,
533 A->getType()->getAddressSpace());
549 [
this, &LD, LMId](
const std::string &Name) {
550 if (
auto Sym = LD.findSymbol(BaseLayer, Name,
false))
552 return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
554 [
this, &
LD](
const std::string &
Name) {
555 return LD.ExternalSymbolResolver->findSymbol(Name);
558 return LD.ModuleAdder(BaseLayer, std::move(M), std::move(Resolver));
561 BaseLayerT &BaseLayer;
563 CompileCallbackMgrT &CompileCallbackMgr;
566 LogicalDylibList LogicalDylibs;
567 bool CloneStubsIntoPartitions;
573 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
LogicalDylibList::iterator ModuleSetHandleT
Handle to a set of loaded modules.
A parsed version of the target data layout string in and methods for querying it. ...
std::function< std::unique_ptr< IndirectStubsManager >)> IndirectStubsManagerBuilderT
Builder for IndirectStubsManagers.
Base class for managing collections of named indirect stubs.
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.
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. ...
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
Available for inspection, not emission.
std::unique_ptr< ResourceOwner< Module > > SourceMod
Externally visible function.
Target-independent base class for compile callback management.
bool updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr)
Update the stub for the given function to point at FnBodyAddr.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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...
std::unique_ptr< LambdaResolver< DylibLookupFtorT, ExternalLookupFtorT > > createLambdaResolver(DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor)
ModuleSetHandleT addModuleSet(ModuleSetT Ms, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver)
Add a module to the compile-on-demand layer.
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...
JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, bool ExportedSymbolsOnly)
Get the address of a symbol provided by this layer, or some layer below this one. ...
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...
CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition, CompileCallbackMgrT &CallbackMgr, IndirectStubsManagerBuilderT CreateIndirectStubsManager, bool CloneStubsIntoPartitions=true)
Construct a compile-on-demand layer instance.
void removeModuleSet(ModuleSetHandleT H)
Remove the module represented by the given handle.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
This is a class that can be implemented by clients to materialize Values on demand.
std::function< std::set< Function * >Function &)> PartitioningFtor
Module partitioning functor.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
uint64_t JITTargetAddress
Represents an address in the target process's address space.
ValueMap< const Value *, WeakVH > ValueToValueMapTy
std::set< Function * > StubsToClone
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.
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 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.
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
void makeAllSymbolsExternallyAccessible(Module &M)
Raise linkage types and rename as necessary to ensure that all symbols are accessible for other modul...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
static void rename(GlobalValue *GV)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly)
Search for the given named symbol.
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
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...