[llvm-branch-commits] [llvm-branch] r96491 - in /llvm/branches/Apple/Hermes: include/llvm/Analysis/MemoryDependenceAnalysis.h include/llvm/Transforms/Utils/BasicBlockUtils.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Utils/BasicBlockUtils.cpp test/Transforms/GVN/pre-load.ll

Bob Wilson bob.wilson at apple.com
Wed Feb 17 10:44:31 PST 2010


Author: bwilson
Date: Wed Feb 17 12:44:30 2010
New Revision: 96491

URL: http://llvm.org/viewvc/llvm-project?rev=96491&view=rev
Log:
--- Merging r96377 into '.':
U    include/llvm/Transforms/Utils/BasicBlockUtils.h
U    lib/Transforms/Utils/BasicBlockUtils.cpp
U    lib/Transforms/Scalar/GVN.cpp
--- Merging r96378 into '.':
U    include/llvm/Analysis/MemoryDependenceAnalysis.h
U    lib/Analysis/MemoryDependenceAnalysis.cpp
G    lib/Transforms/Scalar/GVN.cpp
--- Merging r96385 into '.':
U    test/Transforms/GVN/pre-load.ll
--- Merging r96387 into '.':
G    include/llvm/Transforms/Utils/BasicBlockUtils.h
G    lib/Transforms/Utils/BasicBlockUtils.cpp
G    lib/Transforms/Scalar/GVN.cpp

Modified:
    llvm/branches/Apple/Hermes/include/llvm/Analysis/MemoryDependenceAnalysis.h
    llvm/branches/Apple/Hermes/include/llvm/Transforms/Utils/BasicBlockUtils.h
    llvm/branches/Apple/Hermes/lib/Analysis/MemoryDependenceAnalysis.cpp
    llvm/branches/Apple/Hermes/lib/Transforms/Scalar/GVN.cpp
    llvm/branches/Apple/Hermes/lib/Transforms/Utils/BasicBlockUtils.cpp
    llvm/branches/Apple/Hermes/test/Transforms/GVN/pre-load.ll

Modified: llvm/branches/Apple/Hermes/include/llvm/Analysis/MemoryDependenceAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=96491&r1=96490&r2=96491&view=diff

==============================================================================
--- llvm/branches/Apple/Hermes/include/llvm/Analysis/MemoryDependenceAnalysis.h (original)
+++ llvm/branches/Apple/Hermes/include/llvm/Analysis/MemoryDependenceAnalysis.h Wed Feb 17 12:44:30 2010
@@ -249,7 +249,7 @@
                      SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
     ReverseDepMapType ReverseLocalDeps;
     
-    // A reverse mapping form dependencies to the non-local dependees.
+    // A reverse mapping from dependencies to the non-local dependees.
     ReverseDepMapType ReverseNonLocalDeps;
     
     /// Current AA implementation, just a cache.
@@ -312,6 +312,11 @@
     /// value and replaces the other value with ptr. This can make Ptr available
     /// in more places that cached info does not necessarily keep.
     void invalidateCachedPointerInfo(Value *Ptr);
+
+    /// invalidateCachedPredecessors - Clear the PredIteratorCache info.
+    /// This needs to be done when the CFG changes, e.g., due to splitting
+    /// critical edges.
+    void invalidateCachedPredecessors();
     
   private:
     MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,

Modified: llvm/branches/Apple/Hermes/include/llvm/Transforms/Utils/BasicBlockUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=96491&r1=96490&r2=96491&view=diff

==============================================================================
--- llvm/branches/Apple/Hermes/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/branches/Apple/Hermes/include/llvm/Transforms/Utils/BasicBlockUtils.h Wed Feb 17 12:44:30 2010
@@ -102,6 +102,12 @@
 //
 void RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum);
 
+/// GetSuccessorNumber - Search for the specified successor of basic block BB
+/// and return its position in the terminator instruction's list of
+/// successors.  It is an error to call this with a block that is not a
+/// successor.
+unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
+
 /// isCriticalEdge - Return true if the specified edge is a critical edge.
 /// Critical edges are edges from a block with multiple successors to a block
 /// with multiple predecessors.

Modified: llvm/branches/Apple/Hermes/lib/Analysis/MemoryDependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=96491&r1=96490&r2=96491&view=diff

==============================================================================
--- llvm/branches/Apple/Hermes/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Feb 17 12:44:30 2010
@@ -1016,6 +1016,13 @@
   RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
 }
 
+/// invalidateCachedPredecessors - Clear the PredIteratorCache info.
+/// This needs to be done when the CFG changes, e.g., due to splitting
+/// critical edges.
+void MemoryDependenceAnalysis::invalidateCachedPredecessors() {
+  PredCache->clear();
+}
+
 /// removeInstruction - Remove an instruction from the dependence analysis,
 /// updating the dependence of instructions that previously depended on it.
 /// This method attempts to keep the cache coherent using the reverse map.

Modified: llvm/branches/Apple/Hermes/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Transforms/Scalar/GVN.cpp?rev=96491&r1=96490&r2=96491&view=diff

==============================================================================
--- llvm/branches/Apple/Hermes/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Transforms/Scalar/GVN.cpp Wed Feb 17 12:44:30 2010
@@ -674,6 +674,9 @@
     ValueTable VN;
     DenseMap<BasicBlock*, ValueNumberScope*> localAvail;
 
+    // List of critical edges to be split between iterations.
+    SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit;
+
     // This transformation requires dominator postdominator info
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.addRequired<DominatorTree>();
@@ -701,6 +704,7 @@
     Value *lookupNumber(BasicBlock *BB, uint32_t num);
     void cleanupGlobalSets();
     void verifyRemoved(const Instruction *I) const;
+    bool splitCriticalEdges();
   };
 
   char GVN::ID = 0;
@@ -1583,10 +1587,15 @@
       continue;
     }
     PredLoads[Pred] = 0;
-    // We don't currently handle critical edges :(
+
     if (Pred->getTerminator()->getNumSuccessors() != 1) {
-      DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '"
-            << Pred->getName() << "': " << *LI << '\n');
+      if (isa<IndirectBrInst>(Pred->getTerminator())) {
+        DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
+              << Pred->getName() << "': " << *LI << '\n');
+        return false;
+      }
+      unsigned SuccNum = GetSuccessorNumber(Pred, LoadBB);
+      toSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum));
       return false;
     }
   }
@@ -2004,6 +2013,8 @@
   while (ShouldContinue) {
     DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");
     ShouldContinue = iterateOnFunction(F);
+    if (splitCriticalEdges())
+      ShouldContinue = true;
     Changed |= ShouldContinue;
     ++Iteration;
   }
@@ -2070,7 +2081,6 @@
 /// control flow patterns and attempts to perform simple PRE at the join point.
 bool GVN::performPRE(Function &F) {
   bool Changed = false;
-  SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit;
   DenseMap<BasicBlock*, Value*> predMap;
   for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
        DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) {
@@ -2141,14 +2151,7 @@
       // We can't do PRE safely on a critical edge, so instead we schedule
       // the edge to be split and perform the PRE the next time we iterate
       // on the function.
-      unsigned SuccNum = 0;
-      for (unsigned i = 0, e = PREPred->getTerminator()->getNumSuccessors();
-           i != e; ++i)
-        if (PREPred->getTerminator()->getSuccessor(i) == CurrentBlock) {
-          SuccNum = i;
-          break;
-        }
-
+      unsigned SuccNum = GetSuccessorNumber(PREPred, CurrentBlock);
       if (isCriticalEdge(PREPred->getTerminator(), SuccNum)) {
         toSplit.push_back(std::make_pair(PREPred->getTerminator(), SuccNum));
         continue;
@@ -2216,11 +2219,23 @@
     }
   }
 
-  for (SmallVector<std::pair<TerminatorInst*, unsigned>, 4>::iterator
-       I = toSplit.begin(), E = toSplit.end(); I != E; ++I)
-    SplitCriticalEdge(I->first, I->second, this);
+  if (splitCriticalEdges())
+    Changed = true;
 
-  return Changed || toSplit.size();
+  return Changed;
+}
+
+/// splitCriticalEdges - Split critical edges found during the previous
+/// iteration that may enable further optimization.
+bool GVN::splitCriticalEdges() {
+  if (toSplit.empty())
+    return false;
+  do {
+    std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val();
+    SplitCriticalEdge(Edge.first, Edge.second, this);
+  } while (!toSplit.empty());
+  MD->invalidateCachedPredecessors();
+  return true;
 }
 
 /// iterateOnFunction - Executes one iteration of GVN

Modified: llvm/branches/Apple/Hermes/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=96491&r1=96490&r2=96491&view=diff

==============================================================================
--- llvm/branches/Apple/Hermes/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/branches/Apple/Hermes/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Feb 17 12:44:30 2010
@@ -274,24 +274,31 @@
     ReplaceInstWithInst(TI, NewTI);
 }
 
-/// SplitEdge -  Split the edge connecting specified block. Pass P must 
-/// not be NULL. 
-BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, Pass *P) {
-  TerminatorInst *LatchTerm = BB->getTerminator();
-  unsigned SuccNum = 0;
+/// GetSuccessorNumber - Search for the specified successor of basic block BB
+/// and return its position in the terminator instruction's list of
+/// successors.  It is an error to call this with a block that is not a
+/// successor.
+unsigned llvm::GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ) {
+  TerminatorInst *Term = BB->getTerminator();
 #ifndef NDEBUG
-  unsigned e = LatchTerm->getNumSuccessors();
+  unsigned e = Term->getNumSuccessors();
 #endif
   for (unsigned i = 0; ; ++i) {
     assert(i != e && "Didn't find edge?");
-    if (LatchTerm->getSuccessor(i) == Succ) {
-      SuccNum = i;
-      break;
-    }
+    if (Term->getSuccessor(i) == Succ)
+      return i;
   }
+  return 0;
+}
+
+/// SplitEdge -  Split the edge connecting specified block. Pass P must 
+/// not be NULL. 
+BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, Pass *P) {
+  unsigned SuccNum = GetSuccessorNumber(BB, Succ);
   
   // If this is a critical edge, let SplitCriticalEdge do it.
-  if (SplitCriticalEdge(BB->getTerminator(), SuccNum, P))
+  TerminatorInst *LatchTerm = BB->getTerminator();
+  if (SplitCriticalEdge(LatchTerm, SuccNum, P))
     return LatchTerm->getSuccessor(SuccNum);
 
   // If the edge isn't critical, then BB has a single successor or Succ has a

Modified: llvm/branches/Apple/Hermes/test/Transforms/GVN/pre-load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Hermes/test/Transforms/GVN/pre-load.ll?rev=96491&r1=96490&r2=96491&view=diff

==============================================================================
--- llvm/branches/Apple/Hermes/test/Transforms/GVN/pre-load.ll (original)
+++ llvm/branches/Apple/Hermes/test/Transforms/GVN/pre-load.ll Wed Feb 17 12:44:30 2010
@@ -362,3 +362,30 @@
 return:
   ret void
 }
+
+; Test critical edge splitting.
+define i32 @test11(i32* %p, i1 %C, i32 %N) {
+; CHECK: @test11
+block1:
+        br i1 %C, label %block2, label %block3
+
+block2:
+ %cond = icmp sgt i32 %N, 1
+ br i1 %cond, label %block4, label %block5
+; CHECK: load i32* %p
+; CHECK-NEXT: br label %block4
+
+block3:
+  store i32 0, i32* %p
+  br label %block4
+
+block4:
+  %PRE = load i32* %p
+  br label %block5
+
+block5:
+  %ret = phi i32 [ 0, %block2 ], [ %PRE, %block4 ]
+  ret i32 %ret
+; CHECK: block4:
+; CHECK-NEXT: phi i32
+}





More information about the llvm-branch-commits mailing list