mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
[NVPTX] Order global variables in def-use order before emiting them in the final assembly
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168198 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eaff2d55a9
commit
2085d00d09
@ -68,7 +68,54 @@ static cl::opt<bool, true>InterleaveSrc("nvptx-emit-src",
|
||||
cl::location(llvm::InterleaveSrcInPtx));
|
||||
|
||||
|
||||
namespace {
|
||||
/// DiscoverDependentGlobals - Return a set of GlobalVariables on which \p V
|
||||
/// depends.
|
||||
void DiscoverDependentGlobals(Value *V,
|
||||
DenseSet<GlobalVariable*> &Globals) {
|
||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
|
||||
Globals.insert(GV);
|
||||
else {
|
||||
if (User *U = dyn_cast<User>(V)) {
|
||||
for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) {
|
||||
DiscoverDependentGlobals(U->getOperand(i), Globals);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// VisitGlobalVariableForEmission - Add \p GV to the list of GlobalVariable
|
||||
/// instances to be emitted, but only after any dependents have been added
|
||||
/// first.
|
||||
void VisitGlobalVariableForEmission(GlobalVariable *GV,
|
||||
SmallVectorImpl<GlobalVariable*> &Order,
|
||||
DenseSet<GlobalVariable*> &Visited,
|
||||
DenseSet<GlobalVariable*> &Visiting) {
|
||||
// Have we already visited this one?
|
||||
if (Visited.count(GV)) return;
|
||||
|
||||
// Do we have a circular dependency?
|
||||
if (Visiting.count(GV))
|
||||
report_fatal_error("Circular dependency found in global variable set");
|
||||
|
||||
// Start visiting this global
|
||||
Visiting.insert(GV);
|
||||
|
||||
// Make sure we visit all dependents first
|
||||
DenseSet<GlobalVariable*> Others;
|
||||
for (unsigned i = 0, e = GV->getNumOperands(); i != e; ++i)
|
||||
DiscoverDependentGlobals(GV->getOperand(i), Others);
|
||||
|
||||
for (DenseSet<GlobalVariable*>::iterator I = Others.begin(),
|
||||
E = Others.end(); I != E; ++I)
|
||||
VisitGlobalVariableForEmission(*I, Order, Visited, Visiting);
|
||||
|
||||
// Now we can visit ourself
|
||||
Order.push_back(GV);
|
||||
Visited.insert(GV);
|
||||
Visiting.erase(GV);
|
||||
}
|
||||
}
|
||||
|
||||
// @TODO: This is a copy from AsmPrinter.cpp. The function is static, so we
|
||||
// cannot just link to the existing version.
|
||||
@ -893,10 +940,27 @@ bool NVPTXAsmPrinter::doInitialization (Module &M) {
|
||||
|
||||
emitDeclarations(M, OS2);
|
||||
|
||||
// Print out module-level global variables here.
|
||||
// As ptxas does not support forward references of globals, we need to first
|
||||
// sort the list of module-level globals in def-use order. We visit each
|
||||
// global variable in order, and ensure that we emit it *after* its dependent
|
||||
// globals. We use a little extra memory maintaining both a set and a list to
|
||||
// have fast searches while maintaining a strict ordering.
|
||||
SmallVector<GlobalVariable*,8> Globals;
|
||||
DenseSet<GlobalVariable*> GVVisited;
|
||||
DenseSet<GlobalVariable*> GVVisiting;
|
||||
|
||||
// Visit each global variable, in order
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I)
|
||||
printModuleLevelGV(I, OS2);
|
||||
I != E; ++I)
|
||||
VisitGlobalVariableForEmission(I, Globals, GVVisited, GVVisiting);
|
||||
|
||||
assert(GVVisited.size() == M.getGlobalList().size() &&
|
||||
"Missed a global variable");
|
||||
assert(GVVisiting.size() == 0 && "Did not fully process a global variable");
|
||||
|
||||
// Print out module-level global variables in proper order
|
||||
for (unsigned i = 0, e = Globals.size(); i != e; ++i)
|
||||
printModuleLevelGV(Globals[i], OS2);
|
||||
|
||||
OS2 << '\n';
|
||||
|
||||
|
20
test/CodeGen/NVPTX/global-ordering.ll
Normal file
20
test/CodeGen/NVPTX/global-ordering.ll
Normal file
@ -0,0 +1,20 @@
|
||||
; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s --check-prefix=PTX32
|
||||
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s --check-prefix=PTX64
|
||||
|
||||
; Make sure we emit these globals in def-use order
|
||||
|
||||
|
||||
; PTX32: .visible .global .align 1 .u8 a = 2;
|
||||
; PTX32-NEXT: .visible .global .align 4 .u32 a2 = a;
|
||||
; PTX64: .visible .global .align 1 .u8 a = 2;
|
||||
; PTX64-NEXT: .visible .global .align 8 .u64 a2 = a;
|
||||
@a2 = addrspace(1) global i8 addrspace(1)* @a
|
||||
@a = addrspace(1) global i8 2
|
||||
|
||||
|
||||
; PTX32: .visible .global .align 1 .u8 b = 1;
|
||||
; PTX32-NEXT: .visible .global .align 4 .u32 b2[2] = {b, b};
|
||||
; PTX64: .visible .global .align 1 .u8 b = 1;
|
||||
; PTX64-NEXT: .visible .global .align 8 .u64 b2[2] = {b, b};
|
||||
@b2 = addrspace(1) global [2 x i8 addrspace(1)*] [i8 addrspace(1)* @b, i8 addrspace(1)* @b]
|
||||
@b = addrspace(1) global i8 1
|
Loading…
x
Reference in New Issue
Block a user