[llvm-commits] [llvm] r120202 - in /llvm/trunk: include/llvm/Transforms/Utils/AddrModeMatcher.h lib/Transforms/Scalar/CodeGenPrepare.cpp

Owen Anderson resistor at mac.com
Sat Nov 27 00:15:55 PST 2010


Author: resistor
Date: Sat Nov 27 02:15:55 2010
New Revision: 120202

URL: http://llvm.org/viewvc/llvm-project?rev=120202&view=rev
Log:
Second attempt at fixing the performance regressions introduced
by my recent GVN improvement.  Looking through a single layer of
PHI nodes when attempting to sink GEPs, we need to iteratively
look through arbitrary PHI nests.

Modified:
    llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h
    llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp

Modified: llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h?rev=120202&r1=120201&r2=120202&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h Sat Nov 27 02:15:55 2010
@@ -39,6 +39,12 @@
   ExtAddrMode() : BaseReg(0), ScaledReg(0) {}
   void print(raw_ostream &OS) const;
   void dump() const;
+  
+  bool operator==(const ExtAddrMode& O) const {
+    return (BaseReg == O.BaseReg) && (ScaledReg == O.ScaledReg) &&
+           (BaseGV == O.BaseGV) && (BaseOffs == O.BaseOffs) &&
+           (HasBaseReg == O.HasBaseReg) && (Scale == O.Scale);
+  }
 };
 
 static inline raw_ostream &operator<<(raw_ostream &OS, const ExtAddrMode &AM) {

Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=120202&r1=120201&r2=120202&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Sat Nov 27 02:15:55 2010
@@ -618,37 +618,68 @@
 bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
                                         const Type *AccessTy,
                                         DenseMap<Value*,Value*> &SunkAddrs) {
+  Value *Repl = Addr;
+  
   // Try to collapse single-value PHI nodes.  This is necessary to undo 
   // unprofitable PRE transformations.
-  Value *Repl = Addr;
-  if (isa<PHINode>(Addr) && MemoryInst->hasOneUse()) {
-    PHINode *P = cast<PHINode>(Addr);
-    Instruction *Consensus = 0;
-    unsigned NumUses = 0;
-    for (unsigned i = 0, e = P->getNumIncomingValues(); i != e; ++i) {
-      Instruction *Incoming = dyn_cast<Instruction>(P->getIncomingValue(i));
-      if (!Incoming || (Consensus && !Incoming->isIdenticalTo(Consensus))) {
-        Consensus = 0;
-        break;
-      }
-      
-      if (!Consensus || Incoming->isIdenticalTo(Consensus)) {
-        if (Incoming->getNumUses() > NumUses) {
-          Consensus = Incoming;
-          NumUses = Incoming->getNumUses();
-        }
-        continue;
+  std::vector<Value*> worklist;
+  SmallPtrSet<Value*, 4> Visited;
+  worklist.push_back(Addr);
+  
+  // Use a worklist to iteratively look through PHI nodes, and ensure that
+  // the addressing mode obtained from the non-PHI roots of the graph
+  // are equivalent.
+  Value *Consensus = 0;
+  unsigned NumUses = 0;
+  SmallVector<Instruction*, 16> AddrModeInsts;
+  ExtAddrMode AddrMode;
+  while (!worklist.empty()) {
+    Value *V = worklist.back();
+    worklist.pop_back();
+    
+    // Break use-def graph loops.
+    if (Visited.count(V)) {
+      Consensus = 0;
+      break;
+    }
+    
+    Visited.insert(V);
+    
+    // For a PHI node, push all of its incoming values.
+    if (PHINode *P = dyn_cast<PHINode>(V)) {
+      for (unsigned i = 0, e = P->getNumIncomingValues(); i != e; ++i)
+        worklist.push_back(P->getIncomingValue(i));
+      continue;
+    }
+    
+    // For non-PHIs, determine the addressing mode being computed.
+    SmallVector<Instruction*, 16> NewAddrModeInsts;
+    ExtAddrMode NewAddrMode =
+      AddressingModeMatcher::Match(V, AccessTy,MemoryInst,
+                                   NewAddrModeInsts, *TLI);
+    
+    // Ensure that the obtained addressing mode is equivalent to that obtained
+    // for all other roots of the PHI traversal.  Also, when choosing one
+    // such root as representative, select the one with the most uses in order
+    // to keep the cost modeling heuristics in AddressingModeMatcher applicable.
+    if (!Consensus || NewAddrMode == AddrMode) {
+      if (V->getNumUses() > NumUses) {
+        Consensus = V;
+        NumUses = V->getNumUses();
+        AddrMode = NewAddrMode;
+        AddrModeInsts = NewAddrModeInsts;
       }
+      continue;
     }
     
-    if (Consensus) Addr = Consensus;
+    Consensus = 0;
+    break;
   }
   
-  // Figure out what addressing mode will be built up for this operation.
-  SmallVector<Instruction*, 16> AddrModeInsts;
-  ExtAddrMode AddrMode = AddressingModeMatcher::Match(Addr, AccessTy,MemoryInst,
-                                                      AddrModeInsts, *TLI);
-
+  // If the addressing mode couldn't be determined, or if multiple different
+  // ones were determined, bail out now.
+  if (!Consensus) return false;
+  
   // Check to see if any of the instructions supersumed by this addr mode are
   // non-local to I's BB.
   bool AnyNonLocal = false;





More information about the llvm-commits mailing list