mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-29 10:25:12 +00:00
[Orc] Fix a bug in the CompileOnDemand layer where stub decls were not cloned
into partitions. Also, add an option to clone stub definitions (not just decls) into partitions: these definitions could be inlined in some places to avoid the overhead of calling via the stub. Found by inspection - no test case yet, although I plan to add a unit test for this once the CompileOnDemand layer refactoring settles down. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239640 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -46,23 +46,39 @@ private:
|
|||||||
// variables.
|
// variables.
|
||||||
class GlobalDeclMaterializer : public ValueMaterializer {
|
class GlobalDeclMaterializer : public ValueMaterializer {
|
||||||
public:
|
public:
|
||||||
GlobalDeclMaterializer(Module &Dst) : Dst(Dst) {}
|
typedef std::set<const Function*> StubSet;
|
||||||
|
|
||||||
|
GlobalDeclMaterializer(Module &Dst, const StubSet *StubsToClone = nullptr)
|
||||||
|
: Dst(Dst), StubsToClone(StubsToClone) {}
|
||||||
|
|
||||||
Value* materializeValueFor(Value *V) final {
|
Value* materializeValueFor(Value *V) final {
|
||||||
if (auto *GV = dyn_cast<GlobalVariable>(V))
|
if (auto *GV = dyn_cast<GlobalVariable>(V))
|
||||||
return cloneGlobalVariableDecl(Dst, *GV);
|
return cloneGlobalVariableDecl(Dst, *GV);
|
||||||
else if (auto *F = dyn_cast<Function>(V))
|
else if (auto *F = dyn_cast<Function>(V)) {
|
||||||
return cloneFunctionDecl(Dst, *F);
|
auto *ClonedF = cloneFunctionDecl(Dst, *F);
|
||||||
|
if (StubsToClone && StubsToClone->count(F)) {
|
||||||
|
GlobalVariable *FnBodyPtr =
|
||||||
|
createImplPointer(*ClonedF->getType(), *ClonedF->getParent(),
|
||||||
|
ClonedF->getName() + "$orc_addr", nullptr);
|
||||||
|
makeStub(*ClonedF, *FnBodyPtr);
|
||||||
|
ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
|
||||||
|
ClonedF->addFnAttr(Attribute::AlwaysInline);
|
||||||
|
}
|
||||||
|
return ClonedF;
|
||||||
|
}
|
||||||
// Else.
|
// Else.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Module &Dst;
|
Module &Dst;
|
||||||
|
const StubSet *StubsToClone;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
|
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
|
||||||
|
|
||||||
struct LogicalModuleResources {
|
struct LogicalModuleResources {
|
||||||
std::shared_ptr<Module> SourceModule;
|
std::shared_ptr<Module> SourceModule;
|
||||||
|
std::set<const Function*> StubsToClone;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LogicalDylibResources {
|
struct LogicalDylibResources {
|
||||||
@@ -83,8 +99,10 @@ public:
|
|||||||
typedef typename LogicalDylibList::iterator ModuleSetHandleT;
|
typedef typename LogicalDylibList::iterator ModuleSetHandleT;
|
||||||
|
|
||||||
/// @brief Construct a compile-on-demand layer instance.
|
/// @brief Construct a compile-on-demand layer instance.
|
||||||
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
|
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr,
|
||||||
: BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {}
|
bool CloneStubsIntoPartitions)
|
||||||
|
: BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr),
|
||||||
|
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
|
||||||
|
|
||||||
/// @brief Add a module to the compile-on-demand layer.
|
/// @brief Add a module to the compile-on-demand layer.
|
||||||
template <typename ModuleSetT, typename MemoryManagerPtrT,
|
template <typename ModuleSetT, typename MemoryManagerPtrT,
|
||||||
@@ -97,14 +115,14 @@ public:
|
|||||||
"User supplied memory managers not supported with COD yet.");
|
"User supplied memory managers not supported with COD yet.");
|
||||||
|
|
||||||
LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
|
LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
|
||||||
auto &LDLResources = LogicalDylibs.back().getDylibResources();
|
auto &LDResources = LogicalDylibs.back().getDylibResources();
|
||||||
|
|
||||||
LDLResources.ExternalSymbolResolver =
|
LDResources.ExternalSymbolResolver =
|
||||||
[Resolver](const std::string &Name) {
|
[Resolver](const std::string &Name) {
|
||||||
return Resolver->findSymbol(Name);
|
return Resolver->findSymbol(Name);
|
||||||
};
|
};
|
||||||
|
|
||||||
LDLResources.Partitioner =
|
LDResources.Partitioner =
|
||||||
[](Function &F) {
|
[](Function &F) {
|
||||||
std::set<Function*> Partition;
|
std::set<Function*> Partition;
|
||||||
Partition.insert(&F);
|
Partition.insert(&F);
|
||||||
@@ -152,7 +170,8 @@ private:
|
|||||||
|
|
||||||
// Create a logical module handle for SrcM within the logical dylib.
|
// Create a logical module handle for SrcM within the logical dylib.
|
||||||
auto LMH = LD.createLogicalModule();
|
auto LMH = LD.createLogicalModule();
|
||||||
LD.getLogicalModuleResources(LMH).SourceModule = SrcM;
|
auto &LMResources = LD.getLogicalModuleResources(LMH);
|
||||||
|
LMResources.SourceModule = SrcM;
|
||||||
|
|
||||||
// Create the GVs-and-stubs module.
|
// Create the GVs-and-stubs module.
|
||||||
auto GVsAndStubsM = llvm::make_unique<Module>(
|
auto GVsAndStubsM = llvm::make_unique<Module>(
|
||||||
@@ -171,6 +190,10 @@ private:
|
|||||||
if (F.isDeclaration())
|
if (F.isDeclaration())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Record all functions defined by this module.
|
||||||
|
if (CloneStubsIntoPartitions)
|
||||||
|
LMResources.StubsToClone.insert(&F);
|
||||||
|
|
||||||
// For each definition: create a callback, a stub, and a function body
|
// For each definition: create a callback, a stub, and a function body
|
||||||
// pointer. Initialize the function body pointer to point at the callback,
|
// pointer. Initialize the function body pointer to point at the callback,
|
||||||
// and set the callback to compile the function body.
|
// and set the callback to compile the function body.
|
||||||
@@ -274,7 +297,8 @@ private:
|
|||||||
BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
|
BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
|
||||||
LogicalModuleHandle LMH,
|
LogicalModuleHandle LMH,
|
||||||
const std::set<Function*> &Partition) {
|
const std::set<Function*> &Partition) {
|
||||||
Module &SrcM = *LD.getLogicalModuleResources(LMH).SourceModule;
|
auto &LMResources = LD.getLogicalModuleResources(LMH);
|
||||||
|
Module &SrcM = *LMResources.SourceModule;
|
||||||
|
|
||||||
// Create the module.
|
// Create the module.
|
||||||
std::string NewName(SrcM.getName());
|
std::string NewName(SrcM.getName());
|
||||||
@@ -286,7 +310,7 @@ private:
|
|||||||
auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
|
auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
|
||||||
M->setDataLayout(SrcM.getDataLayout());
|
M->setDataLayout(SrcM.getDataLayout());
|
||||||
ValueToValueMapTy VMap;
|
ValueToValueMapTy VMap;
|
||||||
GlobalDeclMaterializer GDM(*M);
|
GlobalDeclMaterializer GDM(*M, &LMResources.StubsToClone);
|
||||||
|
|
||||||
// Create decls in the new module.
|
// Create decls in the new module.
|
||||||
for (auto *F : Partition)
|
for (auto *F : Partition)
|
||||||
@@ -294,7 +318,7 @@ private:
|
|||||||
|
|
||||||
// Move the function bodies.
|
// Move the function bodies.
|
||||||
for (auto *F : Partition)
|
for (auto *F : Partition)
|
||||||
moveFunctionBody(*F, VMap);
|
moveFunctionBody(*F, VMap, &GDM);
|
||||||
|
|
||||||
// Create memory manager and symbol resolver.
|
// Create memory manager and symbol resolver.
|
||||||
auto MemMgr = llvm::make_unique<SectionMemoryManager>();
|
auto MemMgr = llvm::make_unique<SectionMemoryManager>();
|
||||||
@@ -320,6 +344,7 @@ private:
|
|||||||
BaseLayerT &BaseLayer;
|
BaseLayerT &BaseLayer;
|
||||||
CompileCallbackMgrT &CompileCallbackMgr;
|
CompileCallbackMgrT &CompileCallbackMgr;
|
||||||
LogicalDylibList LogicalDylibs;
|
LogicalDylibList LogicalDylibs;
|
||||||
|
bool CloneStubsIntoPartitions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End namespace orc.
|
} // End namespace orc.
|
||||||
|
@@ -30,8 +30,6 @@ Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr) {
|
|||||||
|
|
||||||
GlobalVariable* createImplPointer(PointerType &PT, Module &M,
|
GlobalVariable* createImplPointer(PointerType &PT, Module &M,
|
||||||
const Twine &Name, Constant *Initializer) {
|
const Twine &Name, Constant *Initializer) {
|
||||||
if (!Initializer)
|
|
||||||
Initializer = Constant::getNullValue(&PT);
|
|
||||||
auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
|
auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
|
||||||
Initializer, Name, nullptr,
|
Initializer, Name, nullptr,
|
||||||
GlobalValue::NotThreadLocal, 0, true);
|
GlobalValue::NotThreadLocal, 0, true);
|
||||||
|
@@ -55,7 +55,7 @@ public:
|
|||||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
|
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
|
||||||
IRDumpLayer(CompileLayer, createDebugDumper()),
|
IRDumpLayer(CompileLayer, createDebugDumper()),
|
||||||
CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)),
|
CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)),
|
||||||
CODLayer(IRDumpLayer, *CCMgr),
|
CODLayer(IRDumpLayer, *CCMgr, false),
|
||||||
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
|
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
|
||||||
|
|
||||||
~OrcLazyJIT() {
|
~OrcLazyJIT() {
|
||||||
|
Reference in New Issue
Block a user