/// of the function body from the original module. The extracted body is then
/// compiled and executed.
template <typename BaseLayerT,
- typename CompileCallbackMgrT = JITCompileCallbackManagerBase,
- typename IndirectStubsMgrT = IndirectStubsManagerBase>
+ typename CompileCallbackMgrT = JITCompileCallbackManager,
+ typename IndirectStubsMgrT = IndirectStubsManager>
class CompileOnDemandLayer {
private:
class LambdaMaterializer final : public ValueMaterializer {
public:
LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
- Value* materializeValueFor(Value *V) final {
- return M(V);
- }
+ Value *materializeDeclFor(Value *V) final { return M(V); }
+
private:
MaterializerFtor M;
};
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
+ 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:
+ ModulePtrT ModulePtr;
+ };
+
+ template <typename ModulePtrT>
+ std::unique_ptr<ModuleOwner> wrapOwnership(ModulePtrT ModulePtr) {
+ return llvm::make_unique<ModuleOwnerImpl<ModulePtrT>>(std::move(ModulePtr));
+ }
+
struct LogicalModuleResources {
- std::shared_ptr<Module> SourceModule;
+ std::unique_ptr<ModuleOwner> SourceModuleOwner;
std::set<const Function*> StubsToClone;
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
// Explicit move constructor to make MSVC happy.
LogicalModuleResources(LogicalModuleResources &&Other)
- : SourceModule(std::move(Other.SourceModule)),
+ : SourceModuleOwner(std::move(Other.SourceModuleOwner)),
StubsToClone(std::move(Other.StubsToClone)),
StubsMgr(std::move(Other.StubsMgr)) {}
// Explicit move assignment to make MSVC happy.
LogicalModuleResources& operator=(LogicalModuleResources &&Other) {
- SourceModule = std::move(Other.SourceModule);
+ SourceModuleOwner = std::move(Other.SourceModuleOwner);
StubsToClone = std::move(Other.StubsToClone);
StubsMgr = std::move(Other.StubsMgr);
}
};
+
+
struct LogicalDylibResources {
typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)>
SymbolResolverFtor;
// Process each of the modules in this module set.
for (auto &M : Ms)
- addLogicalModule(LogicalDylibs.back(),
- std::shared_ptr<Module>(std::move(M)));
+ addLogicalModule(LogicalDylibs.back(), std::move(M));
return std::prev(LogicalDylibs.end());
}
private:
- void addLogicalModule(CODLogicalDylib &LD, std::shared_ptr<Module> SrcM) {
+ 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(*SrcM);
+ makeAllSymbolsExternallyAccessible(*SrcMPtr);
// Create a logical module handle for SrcM within the logical dylib.
auto LMH = LD.createLogicalModule();
auto &LMResources = LD.getLogicalModuleResources(LMH);
- LMResources.SourceModule = SrcM;
+ 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());
+ 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) {
+ for (auto &F : SrcM) {
// Skip declarations.
if (F.isDeclaration())
continue;
// 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(SrcM->getContext());
+ 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);
- });
+ CCInfo.setCompileAction([this, &LD, LMH, &F]() {
+ return this->extractAndCompile(LD, LMH, F);
+ });
}
LMResources.StubsMgr = CreateIndirectStubsManager();
- auto EC = LMResources.StubsMgr->init(StubInits);
+ auto EC = LMResources.StubsMgr->createStubs(StubInits);
(void)EC;
// FIXME: This should be propagated back to the user. Stub creation may
// fail for remote JITs.
}
// Clone global variable decls.
- for (auto &GV : SrcM->globals())
+ for (auto &GV : SrcM.globals())
if (!GV.isDeclaration() && !VMap.count(&GV))
cloneGlobalVariableDecl(*GVsM, GV, &VMap);
// And the aliases.
- for (auto &A : SrcM->aliases())
+ for (auto &A : SrcM.aliases())
if (!VMap.count(&A))
cloneGlobalAliasDecl(*GVsM, A, VMap);
});
// Clone the global variable initializers.
- for (auto &GV : SrcM->globals())
+ for (auto &GV : SrcM.globals())
if (!GV.isDeclaration())
moveGlobalVariableInitializer(GV, VMap, &Materializer);
// Clone the global alias initializers.
- for (auto &A : SrcM->aliases()) {
+ 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,
LogicalModuleHandle LMH,
Function &F) {
auto &LMResources = LD.getLogicalModuleResources(LMH);
- Module &SrcM = *LMResources.SourceModule;
+ Module &SrcM = LMResources.SourceModuleOwner->getModule();
// If F is a declaration we must already have compiled it.
if (F.isDeclaration())
LogicalModuleHandle LMH,
const PartitionT &Part) {
auto &LMResources = LD.getLogicalModuleResources(LMH);
- Module &SrcM = *LMResources.SourceModule;
+ Module &SrcM = LMResources.SourceModuleOwner->getModule();
// Create the module.
std::string NewName = SrcM.getName();
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);
- } else if (auto *F = dyn_cast<Function>(V)) {
- // Check whether we want to clone an available_externally definition.
- if (LMResources.StubsToClone.count(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;
- }
+ 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);
- } else if (auto *A = dyn_cast<GlobalAlias>(V)) {
- auto *PTy = cast<PointerType>(A->getType());
- if (PTy->getElementType()->isFunctionTy())
- return Function::Create(cast<FunctionType>(PTy->getElementType()),
- GlobalValue::ExternalLinkage,
- A->getName(), M.get());
- // else
- return new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalLinkage,
- nullptr, A->getName(), nullptr,
- GlobalValue::NotThreadLocal,
- PTy->getAddressSpace());
- }
- // Else.
- return nullptr;
- });
+
+ // 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)