mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +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:
		| @@ -68,7 +68,54 @@ static cl::opt<bool, true>InterleaveSrc("nvptx-emit-src", | |||||||
|                                         cl::location(llvm::InterleaveSrcInPtx)); |                                         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 | // @TODO: This is a copy from AsmPrinter.cpp.  The function is static, so we | ||||||
| // cannot just link to the existing version. | // cannot just link to the existing version. | ||||||
| @@ -893,10 +940,27 @@ bool NVPTXAsmPrinter::doInitialization (Module &M) { | |||||||
|  |  | ||||||
|   emitDeclarations(M, OS2); |   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(); |   for (Module::global_iterator I = M.global_begin(), E = M.global_end(); | ||||||
|       I != E; ++I) |        I != E; ++I) | ||||||
|     printModuleLevelGV(I, OS2); |     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'; |   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 | ||||||
		Reference in New Issue
	
	Block a user