#define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
#include "IndirectionUtils.h"
-#include "LookasideRTDyldMM.h"
+#include "LambdaResolver.h"
+#include "LogicalDylib.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/Transforms/Utils/Cloning.h"
#include <list>
+#include <memory>
+#include <set>
+
+#include "llvm/Support/Debug.h"
namespace llvm {
+namespace orc {
/// @brief Compile-on-demand layer.
///
-/// Modules added to this layer have their calls indirected, and are then
-/// broken up into a set of single-function modules, each of which is added
-/// to the layer below in a singleton set. The lower layer can be any layer that
-/// accepts IR module sets.
-///
-/// It is expected that this layer will frequently be used on top of a
-/// LazyEmittingLayer. The combination of the two ensures that each function is
-/// compiled only when it is first called.
-template <typename BaseLayerT> class CompileOnDemandLayer {
-public:
- /// @brief Lookup helper that provides compatibility with the classic
- /// static-compilation symbol resolution process.
- ///
- /// The CompileOnDemand (COD) layer splits modules up into multiple
- /// sub-modules, each held in its own llvm::Module instance, in order to
- /// support lazy compilation. When a module that contains private symbols is
- /// broken up symbol linkage changes may be required to enable access to
- /// "private" data that now resides in a different llvm::Module instance. To
- /// retain expected symbol resolution behavior for clients of the COD layer,
- /// the CODScopedLookup class uses a two-tiered lookup system to resolve
- /// symbols. Lookup first scans sibling modules that were split from the same
- /// original module (logical-module scoped lookup), then scans all other
- /// modules that have been added to the lookup scope (logical-dylib scoped
- /// lookup).
- class CODScopedLookup {
- private:
- typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
- typedef std::vector<BaseLayerModuleSetHandleT> SiblingHandlesList;
- typedef std::list<SiblingHandlesList> PseudoDylibModuleSetHandlesList;
+/// When a module is added to this layer a stub is created for each of its
+/// function definitions. The stubs and other global values are immediately
+/// added to the layer below. When a stub is called it triggers the extraction
+/// of the function body from the original module. The extracted body is then
+/// compiled and executed.
+template <typename BaseLayerT,
+ typename CompileCallbackMgrT = JITCompileCallbackManager,
+ typename IndirectStubsMgrT = IndirectStubsManager>
+class CompileOnDemandLayer {
+private:
+ template <typename MaterializerFtor>
+ class LambdaMaterializer final : public ValueMaterializer {
public:
- /// @brief Handle for a logical module.
- typedef typename PseudoDylibModuleSetHandlesList::iterator LMHandle;
-
- /// @brief Construct a scoped lookup.
- CODScopedLookup(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
-
- /// @brief Start a new context for a single logical module.
- LMHandle createLogicalModule() {
- Handles.push_back(SiblingHandlesList());
- return std::prev(Handles.end());
- }
-
- /// @brief Add a concrete Module's handle to the given logical Module's
- /// lookup scope.
- void addToLogicalModule(LMHandle LMH, BaseLayerModuleSetHandleT H) {
- LMH->push_back(H);
- }
+ LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
+ Value *materializeDeclFor(Value *V) final { return M(V); }
- /// @brief Remove a logical Module from the CODScopedLookup entirely.
- void removeLogicalModule(LMHandle LMH) { Handles.erase(LMH); }
+ private:
+ MaterializerFtor M;
+ };
- /// @brief Look up a symbol in this context.
- uint64_t lookup(LMHandle LMH, const std::string &Name) {
- if (uint64_t Addr = lookupOnlyIn(LMH, Name))
- return Addr;
+ template <typename MaterializerFtor>
+ LambdaMaterializer<MaterializerFtor>
+ createLambdaMaterializer(MaterializerFtor M) {
+ return LambdaMaterializer<MaterializerFtor>(std::move(M));
+ }
- for (auto I = Handles.begin(), E = Handles.end(); I != E; ++I)
- if (I != LMH)
- if (uint64_t Addr = lookupOnlyIn(I, Name))
- return Addr;
+ typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
- return 0;
- }
+ class ModuleOwner {
+ public:
+ ModuleOwner() = default;
+ ModuleOwner(const ModuleOwner&) = delete;
+ ModuleOwner& operator=(const ModuleOwner&) = delete;
+ virtual ~ModuleOwner() { }
+ virtual Module& getModule() const = 0;
+ };
+ template <typename ModulePtrT>
+ class ModuleOwnerImpl : public ModuleOwner {
+ public:
+ ModuleOwnerImpl(ModulePtrT ModulePtr) : ModulePtr(std::move(ModulePtr)) {}
+ Module& getModule() const override { return *ModulePtr; }
private:
- uint64_t lookupOnlyIn(LMHandle LMH, const std::string &Name) {
- for (auto H : *LMH)
- if (uint64_t Addr = BaseLayer.lookupSymbolAddressIn(H, Name, false))
- return Addr;
- return 0;
- }
-
- BaseLayerT &BaseLayer;
- PseudoDylibModuleSetHandlesList Handles;
+ ModulePtrT ModulePtr;
};
-private:
- typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
- typedef std::vector<BaseLayerModuleSetHandleT> BaseLayerModuleSetHandleListT;
+ template <typename ModulePtrT>
+ std::unique_ptr<ModuleOwner> wrapOwnership(ModulePtrT ModulePtr) {
+ return llvm::make_unique<ModuleOwnerImpl<ModulePtrT>>(std::move(ModulePtr));
+ }
- struct ModuleSetInfo {
- // Symbol lookup - just one for the whole module set.
- std::shared_ptr<CODScopedLookup> Lookup;
+ struct LogicalModuleResources {
+ std::unique_ptr<ModuleOwner> SourceModuleOwner;
+ std::set<const Function*> StubsToClone;
+ std::unique_ptr<IndirectStubsMgrT> StubsMgr;
- // Logical module handles.
- std::vector<typename CODScopedLookup::LMHandle> LMHandles;
+ LogicalModuleResources() = default;
- // Persistent manglers - one per TU.
- std::vector<PersistentMangler> PersistentManglers;
+ // Explicit move constructor to make MSVC happy.
+ LogicalModuleResources(LogicalModuleResources &&Other)
+ : SourceModuleOwner(std::move(Other.SourceModuleOwner)),
+ StubsToClone(std::move(Other.StubsToClone)),
+ StubsMgr(std::move(Other.StubsMgr)) {}
- // Symbol resolution callback handlers - one per TU.
- std::vector<std::unique_ptr<JITResolveCallbackHandler>>
- JITResolveCallbackHandlers;
+ // Explicit move assignment to make MSVC happy.
+ LogicalModuleResources& operator=(LogicalModuleResources &&Other) {
+ SourceModuleOwner = std::move(Other.SourceModuleOwner);
+ StubsToClone = std::move(Other.StubsToClone);
+ StubsMgr = std::move(Other.StubsMgr);
+ }
- // List of vectors of module set handles:
- // One vector per logical module - each vector holds the handles for the
- // exploded modules for that logical module in the base layer.
- BaseLayerModuleSetHandleListT BaseLayerModuleSetHandles;
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
+ if (Name.endswith("$stub_ptr") && !ExportedSymbolsOnly) {
+ assert(!ExportedSymbolsOnly && "Stubs are never exported");
+ return StubsMgr->findPointer(Name.drop_back(9));
+ }
+ return StubsMgr->findStub(Name, ExportedSymbolsOnly);
+ }
- ModuleSetInfo(std::shared_ptr<CODScopedLookup> Lookup)
- : Lookup(std::move(Lookup)) {}
+ };
- void releaseResources(BaseLayerT &BaseLayer) {
- for (auto LMH : LMHandles)
- Lookup->removeLogicalModule(LMH);
- for (auto H : BaseLayerModuleSetHandles)
- BaseLayer.removeModuleSet(H);
- }
+
+
+ struct LogicalDylibResources {
+ typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)>
+ SymbolResolverFtor;
+ SymbolResolverFtor ExternalSymbolResolver;
};
- typedef std::list<ModuleSetInfo> ModuleSetInfoListT;
+ typedef LogicalDylib<BaseLayerT, LogicalModuleResources,
+ LogicalDylibResources> CODLogicalDylib;
+
+ typedef typename CODLogicalDylib::LogicalModuleHandle LogicalModuleHandle;
+ typedef std::list<CODLogicalDylib> LogicalDylibList;
public:
+
/// @brief Handle to a set of loaded modules.
- typedef typename ModuleSetInfoListT::iterator ModuleSetHandleT;
+ typedef typename LogicalDylibList::iterator ModuleSetHandleT;
- /// @brief Convenience typedef for callback inserter.
- typedef std::function<void(Module&, JITResolveCallbackHandler&)>
- InsertCallbackAsmFtor;
+ /// @brief Module partitioning functor.
+ typedef std::function<std::set<Function*>(Function&)> PartitioningFtor;
+
+ /// @brief Builder for IndirectStubsManagers.
+ typedef std::function<std::unique_ptr<IndirectStubsMgrT>()>
+ IndirectStubsManagerBuilderT;
/// @brief Construct a compile-on-demand layer instance.
- CompileOnDemandLayer(BaseLayerT &BaseLayer,
- InsertCallbackAsmFtor InsertCallbackAsm)
- : BaseLayer(BaseLayer), InsertCallbackAsm(InsertCallbackAsm) {}
+ CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
+ CompileCallbackMgrT &CallbackMgr,
+ IndirectStubsManagerBuilderT CreateIndirectStubsManager,
+ bool CloneStubsIntoPartitions = true)
+ : BaseLayer(BaseLayer), Partition(Partition),
+ CompileCallbackMgr(CallbackMgr),
+ CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
+ CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
/// @brief Add a module to the compile-on-demand layer.
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM) {
-
- const char *JITAddrSuffix = "$orc_addr";
- const char *JITImplSuffix = "$orc_impl";
-
- // Create a symbol lookup context and ModuleSetInfo for this module set.
- auto DylibLookup = std::make_shared<CODScopedLookup>(BaseLayer);
- ModuleSetHandleT H =
- ModuleSetInfos.insert(ModuleSetInfos.end(), ModuleSetInfo(DylibLookup));
- ModuleSetInfo &MSI = ModuleSetInfos.back();
-
- // Process each of the modules in this module set. All modules share the
- // same lookup context, but each will get its own TU lookup context.
- for (auto &M : Ms) {
-
- // Create a TU lookup context for this module.
- auto LMH = DylibLookup->createLogicalModule();
- MSI.LMHandles.push_back(LMH);
-
- // Create a persistent mangler for this module.
- MSI.PersistentManglers.emplace_back(*M->getDataLayout());
-
- // Make all calls to functions defined in this module indirect.
- JITIndirections Indirections =
- makeCallsDoubleIndirect(*M, [](const Function &) { return true; },
- JITImplSuffix, JITAddrSuffix);
-
- // Then carve up the module into a bunch of single-function modules.
- std::vector<std::unique_ptr<Module>> ExplodedModules =
- explode(*M, Indirections);
-
- // Add a resolve-callback handler for this module to look up symbol
- // addresses when requested via a callback.
- MSI.JITResolveCallbackHandlers.push_back(
- createCallbackHandlerFromJITIndirections(
- Indirections, MSI.PersistentManglers.back(),
- [=](StringRef S) { return DylibLookup->lookup(LMH, S); }));
-
- // Insert callback asm code into the first module.
- InsertCallbackAsm(*ExplodedModules[0],
- *MSI.JITResolveCallbackHandlers.back());
-
- // Now we need to take each of the extracted Modules and add them to
- // base layer. Each Module will be added individually to make sure they
- // can be compiled separately, and each will get its own lookaside
- // memory manager with lookup functors that resolve symbols in sibling
- // modules first.OA
- for (auto &M : ExplodedModules) {
- std::vector<std::unique_ptr<Module>> MSet;
- MSet.push_back(std::move(M));
-
- BaseLayerModuleSetHandleT H = BaseLayer.addModuleSet(
- std::move(MSet),
- createLookasideRTDyldMM<SectionMemoryManager>(
- [=](const std::string &Name) {
- if (uint64_t Addr = DylibLookup->lookup(LMH, Name))
- return Addr;
- return getSymbolAddress(Name, true);
- },
- [=](const std::string &Name) {
- return DylibLookup->lookup(LMH, Name);
- }));
- DylibLookup->addToLogicalModule(LMH, H);
- MSI.BaseLayerModuleSetHandles.push_back(H);
- }
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
- initializeFuncAddrs(*MSI.JITResolveCallbackHandlers.back(), Indirections,
- MSI.PersistentManglers.back(), [=](StringRef S) {
- return DylibLookup->lookup(LMH, S);
- });
- }
+ assert(MemMgr == nullptr &&
+ "User supplied memory managers not supported with COD yet.");
+
+ LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
+ auto &LDResources = LogicalDylibs.back().getDylibResources();
- return H;
+ LDResources.ExternalSymbolResolver =
+ [Resolver](const std::string &Name) {
+ return Resolver->findSymbol(Name);
+ };
+
+ // Process each of the modules in this module set.
+ for (auto &M : Ms)
+ addLogicalModule(LogicalDylibs.back(), std::move(M));
+
+ return std::prev(LogicalDylibs.end());
}
/// @brief Remove the module represented by the given handle.
/// This will remove all modules in the layers below that were derived from
/// the module represented by H.
void removeModuleSet(ModuleSetHandleT H) {
- H->releaseResources(BaseLayer);
- ModuleSetInfos.erase(H);
+ LogicalDylibs.erase(H);
}
- /// @brief Get the address of a symbol provided by this layer, or some layer
- /// below this one.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
+ for (auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
+ LDI != LDE; ++LDI)
+ if (auto Symbol = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
+ return Symbol;
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of a symbol provided by this layer, or some layer
/// below this one.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second;
- for (auto &BH : BaseLayerHandles) {
- if (uint64_t Addr =
- BaseLayer.lookupSymbolAddressIn(BH, Name, ExportedSymbolsOnly))
- return Addr;
- }
- return 0;
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return H->findSymbol(Name, ExportedSymbolsOnly);
}
private:
+
+ template <typename ModulePtrT>
+ void addLogicalModule(CODLogicalDylib &LD, ModulePtrT SrcMPtr) {
+
+ // Bump the linkage and rename any anonymous/privote members in SrcM to
+ // ensure that everything will resolve properly after we partition SrcM.
+ makeAllSymbolsExternallyAccessible(*SrcMPtr);
+
+ // Create a logical module handle for SrcM within the logical dylib.
+ auto LMH = LD.createLogicalModule();
+ auto &LMResources = LD.getLogicalModuleResources(LMH);
+
+ LMResources.SourceModuleOwner = wrapOwnership(std::move(SrcMPtr));
+
+ Module &SrcM = LMResources.SourceModuleOwner->getModule();
+
+ // Create the GlobalValues module.
+ const DataLayout &DL = SrcM.getDataLayout();
+ auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
+ SrcM.getContext());
+ GVsM->setDataLayout(DL);
+
+ // Create function stubs.
+ ValueToValueMapTy VMap;
+ {
+ typename IndirectStubsMgrT::StubInitsMap StubInits;
+ for (auto &F : SrcM) {
+ // Skip declarations.
+ if (F.isDeclaration())
+ continue;
+
+ // Record all functions defined by this module.
+ if (CloneStubsIntoPartitions)
+ LMResources.StubsToClone.insert(&F);
+
+ // Create a callback, associate it with the stub for the function,
+ // and set the compile action to compile the partition containing the
+ // function.
+ auto CCInfo = CompileCallbackMgr.getCompileCallback();
+ StubInits[mangle(F.getName(), DL)] =
+ std::make_pair(CCInfo.getAddress(),
+ JITSymbolBase::flagsFromGlobalValue(F));
+ CCInfo.setCompileAction([this, &LD, LMH, &F]() {
+ return this->extractAndCompile(LD, LMH, F);
+ });
+ }
+
+ LMResources.StubsMgr = CreateIndirectStubsManager();
+ auto EC = LMResources.StubsMgr->createStubs(StubInits);
+ (void)EC;
+ // FIXME: This should be propagated back to the user. Stub creation may
+ // fail for remote JITs.
+ assert(!EC && "Error generating stubs");
+ }
+
+ // Clone global variable decls.
+ for (auto &GV : SrcM.globals())
+ if (!GV.isDeclaration() && !VMap.count(&GV))
+ cloneGlobalVariableDecl(*GVsM, GV, &VMap);
+
+ // And the aliases.
+ for (auto &A : SrcM.aliases())
+ if (!VMap.count(&A))
+ cloneGlobalAliasDecl(*GVsM, A, VMap);
+
+ // Now we need to clone the GV and alias initializers.
+
+ // Initializers may refer to functions declared (but not defined) in this
+ // module. Build a materializer to clone decls on demand.
+ auto Materializer = createLambdaMaterializer(
+ [this, &GVsM, &LMResources](Value *V) -> Value* {
+ if (auto *F = dyn_cast<Function>(V)) {
+ // Decls in the original module just get cloned.
+ if (F->isDeclaration())
+ return cloneFunctionDecl(*GVsM, *F);
+
+ // Definitions in the original module (which we have emitted stubs
+ // for at this point) get turned into a constant alias to the stub
+ // instead.
+ const DataLayout &DL = GVsM->getDataLayout();
+ std::string FName = mangle(F->getName(), DL);
+ auto StubSym = LMResources.StubsMgr->findStub(FName, false);
+ unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
+ ConstantInt *StubAddr =
+ ConstantInt::get(GVsM->getContext(),
+ APInt(PtrBitWidth, StubSym.getAddress()));
+ Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
+ StubAddr, F->getType());
+ return GlobalAlias::create(F->getFunctionType(),
+ F->getType()->getAddressSpace(),
+ F->getLinkage(), F->getName(),
+ Init, GVsM.get());
+ }
+ // else....
+ return nullptr;
+ });
+
+ // Clone the global variable initializers.
+ for (auto &GV : SrcM.globals())
+ if (!GV.isDeclaration())
+ moveGlobalVariableInitializer(GV, VMap, &Materializer);
+
+ // Clone the global alias initializers.
+ for (auto &A : SrcM.aliases()) {
+ auto *NewA = cast<GlobalAlias>(VMap[&A]);
+ assert(NewA && "Alias not cloned?");
+ Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
+ &Materializer);
+ NewA->setAliasee(cast<Constant>(Init));
+ }
+
+ // Build a resolver for the globals module and add it to the base layer.
+ auto GVsResolver = createLambdaResolver(
+ [&LD, LMH](const std::string &Name) {
+ auto &LMResources = LD.getLogicalModuleResources(LMH);
+ if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ return LD.getDylibResources().ExternalSymbolResolver(Name);
+ },
+ [](const std::string &Name) {
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ std::vector<std::unique_ptr<Module>> GVsMSet;
+ GVsMSet.push_back(std::move(GVsM));
+ auto GVsH =
+ BaseLayer.addModuleSet(std::move(GVsMSet),
+ llvm::make_unique<SectionMemoryManager>(),
+ std::move(GVsResolver));
+ LD.addToLogicalModule(LMH, GVsH);
+ }
+
+ static std::string mangle(StringRef Name, const DataLayout &DL) {
+ std::string MangledName;
+ {
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ }
+ return MangledName;
+ }
+
+ TargetAddress extractAndCompile(CODLogicalDylib &LD,
+ LogicalModuleHandle LMH,
+ Function &F) {
+ auto &LMResources = LD.getLogicalModuleResources(LMH);
+ Module &SrcM = LMResources.SourceModuleOwner->getModule();
+
+ // If F is a declaration we must already have compiled it.
+ if (F.isDeclaration())
+ return 0;
+
+ // Grab the name of the function being called here.
+ std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
+
+ auto Part = Partition(F);
+ auto PartH = emitPartition(LD, LMH, Part);
+
+ TargetAddress CalledAddr = 0;
+ for (auto *SubF : Part) {
+ std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
+ auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
+ assert(FnBodySym && "Couldn't find function body.");
+
+ TargetAddress FnBodyAddr = FnBodySym.getAddress();
+
+ // If this is the function we're calling record the address so we can
+ // return it from this function.
+ if (SubF == &F)
+ CalledAddr = FnBodyAddr;
+
+ // Update the function body pointer for the stub.
+ if (auto EC = LMResources.StubsMgr->updatePointer(FnName, FnBodyAddr))
+ return 0;
+ }
+
+ return CalledAddr;
+ }
+
+ template <typename PartitionT>
+ BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
+ LogicalModuleHandle LMH,
+ const PartitionT &Part) {
+ auto &LMResources = LD.getLogicalModuleResources(LMH);
+ Module &SrcM = LMResources.SourceModuleOwner->getModule();
+
+ // Create the module.
+ std::string NewName = SrcM.getName();
+ for (auto *F : Part) {
+ NewName += ".";
+ NewName += F->getName();
+ }
+
+ auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
+ M->setDataLayout(SrcM.getDataLayout());
+ ValueToValueMapTy VMap;
+
+ auto Materializer = createLambdaMaterializer([this, &LMResources, &M,
+ &VMap](Value *V) -> Value * {
+ if (auto *GV = dyn_cast<GlobalVariable>(V))
+ return cloneGlobalVariableDecl(*M, *GV);
+
+ if (auto *F = dyn_cast<Function>(V)) {
+ // Check whether we want to clone an available_externally definition.
+ if (!LMResources.StubsToClone.count(F))
+ return cloneFunctionDecl(*M, *F);
+
+ // Ok - we want an inlinable stub. For that to work we need a decl
+ // for the stub pointer.
+ auto *StubPtr = createImplPointer(*F->getType(), *M,
+ F->getName() + "$stub_ptr", nullptr);
+ auto *ClonedF = cloneFunctionDecl(*M, *F);
+ makeStub(*ClonedF, *StubPtr);
+ ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
+ ClonedF->addFnAttr(Attribute::AlwaysInline);
+ return ClonedF;
+ }
+
+ if (auto *A = dyn_cast<GlobalAlias>(V)) {
+ auto *Ty = A->getValueType();
+ if (Ty->isFunctionTy())
+ return Function::Create(cast<FunctionType>(Ty),
+ GlobalValue::ExternalLinkage, A->getName(),
+ M.get());
+
+ return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
+ nullptr, A->getName(), nullptr,
+ GlobalValue::NotThreadLocal,
+ A->getType()->getAddressSpace());
+ }
+
+ return nullptr;
+ });
+
+ // Create decls in the new module.
+ for (auto *F : Part)
+ cloneFunctionDecl(*M, *F, &VMap);
+
+ // Move the function bodies.
+ for (auto *F : Part)
+ moveFunctionBody(*F, VMap, &Materializer);
+
+ // Create memory manager and symbol resolver.
+ auto MemMgr = llvm::make_unique<SectionMemoryManager>();
+ auto Resolver = createLambdaResolver(
+ [this, &LD, LMH](const std::string &Name) {
+ if (auto Symbol = LD.findSymbolInternally(LMH, Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return LD.getDylibResources().ExternalSymbolResolver(Name);
+ },
+ [this, &LD, LMH](const std::string &Name) {
+ if (auto Symbol = LD.findSymbolInternally(LMH, Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+ std::vector<std::unique_ptr<Module>> PartMSet;
+ PartMSet.push_back(std::move(M));
+ return BaseLayer.addModuleSet(std::move(PartMSet), std::move(MemMgr),
+ std::move(Resolver));
+ }
+
BaseLayerT &BaseLayer;
- InsertCallbackAsmFtor InsertCallbackAsm;
- ModuleSetInfoListT ModuleSetInfos;
+ PartitioningFtor Partition;
+ CompileCallbackMgrT &CompileCallbackMgr;
+ IndirectStubsManagerBuilderT CreateIndirectStubsManager;
+
+ LogicalDylibList LogicalDylibs;
+ bool CloneStubsIntoPartitions;
};
-}
+
+} // End namespace orc.
+} // End namespace llvm.
#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H