[PATCH] [NVPTXFavorNonGeneric] canonicalize global variable initializers

Jingyue Wu jingyue at google.com
Wed Apr 22 11:24:37 PDT 2015


Hi jholewinski, eliben,

This patch hoists addrspacecast in a global variable initializer to the
outermost possible level, so that NVPTXAsmPrinter can print it more likely
correctly.

http://reviews.llvm.org/D9204

Files:
  lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp
  test/CodeGen/NVPTX/addrspacecast-gvar.ll

Index: lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp
===================================================================
--- lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp
+++ lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp
@@ -63,16 +63,20 @@
   static char ID;
   NVPTXFavorNonGenericAddrSpaces() : FunctionPass(ID) {}
 
+  bool doInitialization(Module &M) override;
   bool runOnFunction(Function &F) override;
 
   /// Optimizes load/store instructions. Idx is the index of the pointer operand
   /// (0 for load, and 1 for store). Returns true if it changes anything.
   bool optimizeMemoryInstruction(Instruction *I, unsigned Idx);
   /// Transforms "gep (addrspacecast X), indices" into "addrspacecast (gep X,
-  /// indices)".  This reordering exposes to optimizeMemoryInstruction more
+  /// indices)". This reordering exposes to optimizeMemoryInstruction more
   /// optimization opportunities on loads and stores. Returns true if it changes
   /// the program.
   bool hoistAddrSpaceCastFromGEP(GEPOperator *GEP);
+  /// Run hoistAddrSpaceCastFromGEP on all the recursive elements of
+  /// \c Initializer.
+  bool canonicalizeInitializer(Constant *Initializer);
 };
 }
 
@@ -143,10 +147,11 @@
 
 bool NVPTXFavorNonGenericAddrSpaces::optimizeMemoryInstruction(Instruction *MI,
                                                                unsigned Idx) {
+  bool Changed = false;
   // If the pointer operand is a GEP, hoist the addrspacecast if any from the
   // GEP to expose more optimization opportunites.
   if (GEPOperator *GEP = dyn_cast<GEPOperator>(MI->getOperand(Idx))) {
-    hoistAddrSpaceCastFromGEP(GEP);
+    Changed |= hoistAddrSpaceCastFromGEP(GEP);
   }
 
   // load/store (addrspacecast X) => load/store X if shortcutting the
@@ -162,10 +167,41 @@
   if (Operator *Cast = dyn_cast<Operator>(MI->getOperand(Idx))) {
     if (IsEliminableAddrSpaceCast(Cast)) {
       MI->setOperand(Idx, Cast->getOperand(0));
-      return true;
+      Changed = true;
     }
   }
+  return Changed;
+}
 
+bool NVPTXFavorNonGenericAddrSpaces::doInitialization(Module &M) {
+  bool Changed = false;
+  // Canonicalizes all global variable initializers to hoist addrspacecast to
+  // the outermost possible level. This enables NVPTXAsmPrinter to correctly
+  // print more global variables.
+  for (auto &GV : M.globals()) {
+    if (GV.hasInitializer())
+      Changed |= canonicalizeInitializer(GV.getInitializer());
+  }
+  return Changed;
+}
+
+bool NVPTXFavorNonGenericAddrSpaces::canonicalizeInitializer(Constant *
+                                                             Initializer) {
+  if (GEPOperator *GEP = dyn_cast<GEPOperator>(Initializer)) {
+    return hoistAddrSpaceCastFromGEP(GEP);
+  }
+
+  bool Changed = false;
+  if (Initializer->getType()->isStructTy() ||
+      Initializer->getType()->isArrayTy() ||
+      Initializer->getType()->isVectorTy()) {
+    // Trace into the elements of Initializer if it is a struct, array, or
+    // vector.
+    for (unsigned I = 0; I != Initializer->getNumOperands(); ++I) {
+      Changed |=
+          canonicalizeInitializer(cast<Constant>(Initializer->getOperand(I)));
+    }
+  }
   return false;
 }
 
Index: test/CodeGen/NVPTX/addrspacecast-gvar.ll
===================================================================
--- test/CodeGen/NVPTX/addrspacecast-gvar.ll
+++ test/CodeGen/NVPTX/addrspacecast-gvar.ll
@@ -5,9 +5,11 @@
 ; CHECK: .visible .global .align 4 .u32 g3 = g;
 ; CHECK: .visible .global .align 8 .u32 g4[2] = {0, generic(g)};
 ; CHECK: .visible .global .align 8 .u32 g5[2] = {0, generic(g+8)};
+; CHECK: .visible .global .align 8 .u32 g6[2] = {0, generic(g+8)};
 
 @g = addrspace(1) global i32 42
 @g2 = addrspace(1) global i32* addrspacecast (i32 addrspace(1)* @g to i32*)
 @g3 = addrspace(1) global i32 addrspace(1)* @g
 @g4 = constant {i32*, i32*} {i32* null, i32* addrspacecast (i32 addrspace(1)* @g to i32*)}
 @g5 = constant {i32*, i32*} {i32* null, i32* addrspacecast (i32 addrspace(1)* getelementptr (i32, i32 addrspace(1)* @g, i32 2) to i32*)}
+ at g6 = constant {i32*, i32*} {i32* null, i32* getelementptr (i32, i32* addrspacecast (i32 addrspace(1)* @g to i32*), i32 2)}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9204.24248.patch
Type: text/x-patch
Size: 4189 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150422/22d0683c/attachment.bin>


More information about the llvm-commits mailing list