15 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
16 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
39 template <
typename BaseLayerT,
typename CompileCallbackMgrT,
40 typename PartitioningFtor =
41 std::function<std::set<Function*>(
Function&)>>
49 typedef std::set<const Function*> StubSet;
51 GlobalDeclMaterializer(
Module &Dst,
const StubSet *StubsToClone =
nullptr)
52 : Dst(Dst), StubsToClone(StubsToClone) {}
55 if (
auto *GV = dyn_cast<GlobalVariable>(V))
57 else if (
auto *
F = dyn_cast<Function>(V)) {
59 if (StubsToClone && StubsToClone->count(
F)) {
62 ClonedF->getName() +
"$orc_addr",
nullptr);
74 const StubSet *StubsToClone;
77 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
79 struct LogicalModuleResources {
80 std::shared_ptr<Module> SourceModule;
81 std::set<const Function*> StubsToClone;
84 struct LogicalDylibResources {
85 typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)>
87 SymbolResolverFtor ExternalSymbolResolver;
88 PartitioningFtor Partitioner;
95 typedef std::list<CODLogicalDylib> LogicalDylibList;
103 bool CloneStubsIntoPartitions)
104 : BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr),
105 CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
108 template <
typename ModuleSetT,
typename MemoryManagerPtrT,
109 typename SymbolResolverPtrT>
111 MemoryManagerPtrT MemMgr,
112 SymbolResolverPtrT Resolver) {
114 assert(MemMgr ==
nullptr &&
115 "User supplied memory managers not supported with COD yet.");
117 LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
118 auto &LDResources = LogicalDylibs.back().getDylibResources();
120 LDResources.ExternalSymbolResolver =
121 [Resolver](
const std::string &
Name) {
122 return Resolver->findSymbol(
Name);
125 LDResources.Partitioner =
127 std::set<Function*> Partition;
128 Partition.insert(&
F);
134 addLogicalModule(LogicalDylibs.back(),
135 std::shared_ptr<Module>(std::move(M)));
137 return std::prev(LogicalDylibs.end());
145 LogicalDylibs.erase(H);
153 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
159 bool ExportedSymbolsOnly) {
160 return H->findSymbol(Name, ExportedSymbolsOnly);
165 void addLogicalModule(CODLogicalDylib &
LD, std::shared_ptr<Module> SrcM) {
172 auto LMH = LD.createLogicalModule();
173 auto &LMResources = LD.getLogicalModuleResources(LMH);
174 LMResources.SourceModule = SrcM;
177 auto GVsAndStubsM = llvm::make_unique<Module>(
178 (SrcM->getName() +
".globals_and_stubs").str(),
180 GVsAndStubsM->setDataLayout(SrcM->getDataLayout());
187 for (
auto &
F : *SrcM) {
190 if (
F.isDeclaration())
194 if (CloneStubsIntoPartitions)
195 LMResources.StubsToClone.
insert(&
F);
200 auto CCInfo = CompileCallbackMgr.getCompileCallback(SrcM->getContext());
204 StubF->
getName() +
"$orc_addr",
206 CCInfo.getAddress()));
208 CCInfo.setCompileAction(
209 [
this, &LD, LMH, &
F]() {
210 return this->extractAndCompile(LD, LMH,
F);
215 GlobalDeclMaterializer GDMat(*GVsAndStubsM);
216 for (
auto &GV : SrcM->globals())
217 if (!GV.isDeclaration())
221 for (
auto &GV : SrcM->globals())
222 if (!GV.isDeclaration())
227 [&LD](
const std::string &
Name) {
228 return LD.getDylibResources().ExternalSymbolResolver(Name);
230 [](
const std::string &
Name) {
231 return RuntimeDyld::SymbolInfo(
nullptr);
234 std::vector<std::unique_ptr<Module>> GVsAndStubsMSet;
235 GVsAndStubsMSet.push_back(std::move(GVsAndStubsM));
237 BaseLayer.addModuleSet(std::move(GVsAndStubsMSet),
238 llvm::make_unique<SectionMemoryManager>(),
239 std::move(GVsAndStubsResolver));
240 LD.addToLogicalModule(LMH, GVsAndStubsH);
243 static std::string Mangle(StringRef Name,
const DataLayout &DL) {
244 std::string MangledName;
246 raw_string_ostream MangledNameStream(MangledName);
253 LogicalModuleHandle LMH,
255 Module &SrcM = *LD.getLogicalModuleResources(LMH).SourceModule;
258 if (F.isDeclaration())
262 std::string CalledFnName = Mangle(F.getName(), SrcM.getDataLayout());
264 auto Partition = LD.getDylibResources().Partitioner(F);
265 auto PartitionH = emitPartition(LD, LMH, Partition);
268 for (
auto *SubF : Partition) {
269 std::string FName = SubF->getName();
271 BaseLayer.findSymbolIn(PartitionH, Mangle(FName, SrcM.getDataLayout()),
274 BaseLayer.findSymbolIn(*LD.moduleHandlesBegin(LMH),
275 Mangle(FName +
"$orc_addr",
276 SrcM.getDataLayout()),
278 assert(FnBodySym &&
"Couldn't find function body.");
279 assert(FnPtrSym &&
"Couldn't find function body pointer.");
282 void *FnPtrAddr =
reinterpret_cast<void*
>(
283 static_cast<uintptr_t
>(FnPtrSym.getAddress()));
288 CalledAddr = FnBodyAddr;
290 memcpy(FnPtrAddr, &FnBodyAddr,
sizeof(uintptr_t));
296 template <
typename PartitionT>
297 BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
298 LogicalModuleHandle LMH,
299 const PartitionT &Partition) {
300 auto &LMResources = LD.getLogicalModuleResources(LMH);
301 Module &SrcM = *LMResources.SourceModule;
304 std::string NewName = SrcM.getName();
305 for (
auto *F : Partition) {
307 NewName += F->getName();
310 auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
311 M->setDataLayout(SrcM.getDataLayout());
313 GlobalDeclMaterializer GDM(*M, &LMResources.StubsToClone);
316 for (
auto *F : Partition)
320 for (
auto *F : Partition)
324 auto MemMgr = llvm::make_unique<SectionMemoryManager>();
326 [
this, &LD, LMH](
const std::string &Name) {
327 if (
auto Symbol = LD.findSymbolInternally(LMH, Name))
328 return RuntimeDyld::SymbolInfo(
Symbol.getAddress(),
330 return LD.getDylibResources().ExternalSymbolResolver(Name);
332 [
this, &
LD, LMH](
const std::string &
Name) {
333 if (
auto Symbol = LD.findSymbolInternally(LMH, Name))
334 return RuntimeDyld::SymbolInfo(
Symbol.getAddress(),
336 return RuntimeDyld::SymbolInfo(
nullptr);
338 std::vector<std::unique_ptr<Module>> PartMSet;
339 PartMSet.push_back(std::move(M));
340 return BaseLayer.addModuleSet(std::move(PartMSet), std::move(MemMgr),
341 std::move(Resolver));
344 BaseLayerT &BaseLayer;
345 CompileCallbackMgrT &CompileCallbackMgr;
346 LogicalDylibList LogicalDylibs;
347 bool CloneStubsIntoPartitions;
353 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A Module instance is used to store all the information related to an LLVM module. ...
Available for inspection, not emission.
StringRef getName() const
Return a constant reference to the value's name.
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. ...
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr, bool CloneStubsIntoPartitions)
Construct a compile-on-demand layer instance.
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...
ModuleSetHandleT addModuleSet(ModuleSetT Ms, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver)
Add a module to the compile-on-demand layer.
Constant * createIRTypedAddress(FunctionType &FT, TargetAddress Addr)
Build a function pointer of FunctionType with the given constant address.
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...
LogicalDylibList::iterator ModuleSetHandleT
Handle to a set of loaded modules.
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
ValueMaterializer - This is a class that can be implemented by clients to materialize Values on deman...
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly)
Search for the given named symbol.
Represents a symbol in the JIT.
ValueMap< const Value *, WeakVH > ValueToValueMapTy
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
LogicalModuleList::iterator LogicalModuleHandle
uint64_t TargetAddress
Represents an address in the target process's address space.
void removeModuleSet(ModuleSetHandleT H)
Remove the module represented by the given handle.
std::unique_ptr< LambdaResolver< ExternalLookupFtorT, DylibLookupFtorT > > createLambdaResolver(ExternalLookupFtorT ExternalLookupFtor, DylibLookupFtorT DylibLookupFtor)
void makeAllSymbolsExternallyAccessible(Module &M)
Raise linkage types and rename as necessary to ensure that all symbols are accessible for other modul...
PointerType * getType() const
Global values are always pointers.
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
FunctionType * getFunctionType() const
void makeStub(Function &F, GlobalVariable &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
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...