[llvm-commits] [llvm] r50020 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/LoopSimplify.cpp

Chris Lattner sabre at nondot.org
Sun Apr 20 18:28:02 PDT 2008


Author: lattner
Date: Sun Apr 20 20:28:02 2008
New Revision: 50020

URL: http://llvm.org/viewvc/llvm-project?rev=50020&view=rev
Log:
Move SplitBlockPredecessors out of loopsimplify into BasicBlockUtils.h
as a global helper function.  At the same type, switch it from taking
a vector of predecessors to an arbitrary sequential input.  This allows
us to switch LoopSimplify to use a SmallVector for various temporary
vectors that it passed into SplitBlockPredecessors.

Modified:
    llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
    llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp

Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=50020&r1=50019&r2=50020&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Sun Apr 20 20:28:02 2008
@@ -120,6 +120,19 @@
 /// the loop info is updated.
 ///
 BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P);
+ 
+/// SplitBlockPredecessors - This method transforms BB by introducing a new
+/// basic block into the function, and moving some of the predecessors of BB to
+/// be predecessors of the new block.  The new predecessors are indicated by the
+/// Preds array, which has NumPreds elements in it.  The new block is given a
+/// suffix of 'Suffix'.  This function returns the new block.
+///
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree and
+/// DominanceFrontier, but no other analyses.
+BasicBlock *SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds,
+                                   unsigned NumPreds, const char *Suffix,
+                                   Pass *P = 0);
+  
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=50020&r1=50019&r2=50020&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sun Apr 20 20:28:02 2008
@@ -17,6 +17,7 @@
 #include "llvm/Instructions.h"
 #include "llvm/Constant.h"
 #include "llvm/Type.h"
+#include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/Dominators.h"
 #include <algorithm>
@@ -187,3 +188,103 @@
     
   return New;
 }
+
+
+/// SplitBlockPredecessors - This method transforms BB by introducing a new
+/// basic block into the function, and moving some of the predecessors of BB to
+/// be predecessors of the new block.  The new predecessors are indicated by the
+/// Preds array, which has NumPreds elements in it.  The new block is given a
+/// suffix of 'Suffix'.
+///
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree and
+/// DominanceFrontier, but no other analyses.
+BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB, 
+                                         BasicBlock *const *Preds,
+                                         unsigned NumPreds, const char *Suffix,
+                                         Pass *P) {
+  // Create new basic block, insert right before the original block.
+  BasicBlock *NewBB =
+    BasicBlock::Create(BB->getName()+Suffix, BB->getParent(), BB);
+  
+  // The new block unconditionally branches to the old block.
+  BranchInst *BI = BranchInst::Create(BB, NewBB);
+  
+  // Move the edges from Preds to point to NewBB instead of BB.
+  for (unsigned i = 0; i != NumPreds; ++i) {
+    Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB);
+    
+    if (Preds[i]->getUnwindDest() == BB)
+      Preds[i]->setUnwindDest(NewBB);
+  }
+  
+  // Update dominator tree and dominator frontier if available.
+  DominatorTree *DT = P ? P->getAnalysisToUpdate<DominatorTree>() : 0;
+  if (DT)
+    DT->splitBlock(NewBB);
+  if (DominanceFrontier *DF = P ? P->getAnalysisToUpdate<DominanceFrontier>():0)
+    DF->splitBlock(NewBB);
+  AliasAnalysis *AA = P ? P->getAnalysisToUpdate<AliasAnalysis>() : 0;
+  
+  
+  // Insert a new PHI node into NewBB for every PHI node in BB and that new PHI
+  // node becomes an incoming value for BB's phi node.  However, if the Preds
+  // list is empty, we need to insert dummy entries into the PHI nodes in BB to
+  // account for the newly created predecessor.
+  if (NumPreds == 0) {
+    // Insert dummy values as the incoming value.
+    for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ++I)
+      cast<PHINode>(I)->addIncoming(UndefValue::get(I->getType()), NewBB);
+    return NewBB;
+  }
+  
+  // Otherwise, create a new PHI node in NewBB for each PHI node in BB.
+  for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ) {
+    PHINode *PN = cast<PHINode>(I++);
+    
+    // Check to see if all of the values coming in are the same.  If so, we
+    // don't need to create a new PHI node.
+    Value *InVal = PN->getIncomingValueForBlock(Preds[0]);
+    for (unsigned i = 1; i != NumPreds; ++i)
+      if (InVal != PN->getIncomingValueForBlock(Preds[i])) {
+        InVal = 0;
+        break;
+      }
+    
+    if (InVal) {
+      // If all incoming values for the new PHI would be the same, just don't
+      // make a new PHI.  Instead, just remove the incoming values from the old
+      // PHI.
+      for (unsigned i = 0; i != NumPreds; ++i)
+        PN->removeIncomingValue(Preds[i], false);
+    } else {
+      // If the values coming into the block are not the same, we need a PHI.
+      // Create the new PHI node, insert it into NewBB at the end of the block
+      PHINode *NewPHI =
+        PHINode::Create(PN->getType(), PN->getName()+".ph", BI);
+      if (AA) AA->copyValue(PN, NewPHI);
+      
+      // Move all of the PHI values for 'Preds' to the new PHI.
+      for (unsigned i = 0; i != NumPreds; ++i) {
+        Value *V = PN->removeIncomingValue(Preds[i], false);
+        NewPHI->addIncoming(V, Preds[i]);
+      }
+      InVal = NewPHI;
+    }
+    
+    // Add an incoming value to the PHI node in the loop for the preheader
+    // edge.
+    PN->addIncoming(InVal, NewBB);
+    
+    // Check to see if we can eliminate this phi node.
+    if (Value *V = PN->hasConstantValue(DT != 0)) {
+      Instruction *I = dyn_cast<Instruction>(V);
+      if (!I || DT == 0 || DT->dominates(I, PN)) {
+        PN->replaceAllUsesWith(V);
+        if (AA) AA->deleteValue(PN);
+        PN->eraseFromParent();
+      }
+    }
+  }
+  
+  return NewBB;
+}

Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=50020&r1=50019&r2=50020&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Sun Apr 20 20:28:02 2008
@@ -41,6 +41,7 @@
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/SetOperations.h"
@@ -86,14 +87,12 @@
 
   private:
     bool ProcessLoop(Loop *L);
-    BasicBlock *SplitBlockPredecessors(BasicBlock *BB, const char *Suffix,
-                                       const std::vector<BasicBlock*> &Preds);
     BasicBlock *RewriteLoopExitBlock(Loop *L, BasicBlock *Exit);
     void InsertPreheaderForLoop(Loop *L);
     Loop *SeparateNestedLoop(Loop *L);
     void InsertUniqueBackedgeBlock(Loop *L);
     void PlaceSplitBlockCarefully(BasicBlock *NewBB,
-                                  std::vector<BasicBlock*> &SplitPreds,
+                                  SmallVectorImpl<BasicBlock*> &SplitPreds,
                                   Loop *L);
   };
 
@@ -260,103 +259,6 @@
   return Changed;
 }
 
-/// SplitBlockPredecessors - Split the specified block into two blocks.  We want
-/// to move the predecessors specified in the Preds list to point to the new
-/// block, leaving the remaining predecessors pointing to BB.  This method
-/// updates the SSA PHINode's, AliasAnalysis, DominatorTree and
-/// DominanceFrontier, but no other analyses.
-///
-BasicBlock *LoopSimplify::SplitBlockPredecessors(BasicBlock *BB,
-                                                 const char *Suffix,
-                                       const std::vector<BasicBlock*> &Preds) {
-
-  // Create new basic block, insert right before the original block.
-  BasicBlock *NewBB =
-    BasicBlock::Create(BB->getName()+Suffix, BB->getParent(), BB);
-
-  // The preheader first gets an unconditional branch to the loop header.
-  BranchInst *BI = BranchInst::Create(BB, NewBB);
-
-  // Move the edges from Preds to point to NewBB instead of BB.
-  for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
-    Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB);
-    
-    if (Preds[i]->getUnwindDest() == BB)
-      Preds[i]->setUnwindDest(NewBB);
-  }
-  
-  // Update dominator tree and dominator frontier if available.
-  DT->splitBlock(NewBB);
-  if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>())
-    DF->splitBlock(NewBB);
-  
-  // For every PHI node in the block, insert a PHI node into NewBB where the
-  // incoming values from the out of loop edges are moved to NewBB.  We have two
-  // possible cases here.  If the loop is dead, we just insert dummy entries
-  // into the PHI nodes for the new edge.  If the loop is not dead, we move the
-  // incoming edges in BB into new PHI nodes in NewBB.
-  //
-  if (Preds.empty()) {  // Is the loop obviously dead?
-    // Insert dummy values as the incoming value.
-    for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ++I)
-      cast<PHINode>(I)->addIncoming(UndefValue::get(I->getType()), NewBB);
-    
-    return NewBB;
-  }
-  
-  // Check to see if the values being merged into the new block need PHI
-  // nodes.  If so, insert them.
-  for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ) {
-    PHINode *PN = cast<PHINode>(I);
-    ++I;
-
-    // Check to see if all of the values coming in are the same.  If so, we
-    // don't need to create a new PHI node.
-    Value *InVal = PN->getIncomingValueForBlock(Preds[0]);
-    for (unsigned i = 1, e = Preds.size(); i != e; ++i)
-      if (InVal != PN->getIncomingValueForBlock(Preds[i])) {
-        InVal = 0;
-        break;
-      }
-
-    // If the values coming into the block are not the same, we need a PHI.
-    if (InVal == 0) {
-      // Create the new PHI node, insert it into NewBB at the end of the block
-      PHINode *NewPHI =
-        PHINode::Create(PN->getType(), PN->getName()+".ph", BI);
-      if (AA) AA->copyValue(PN, NewPHI);
-
-      // Move all of the edges from blocks outside the loop to the new PHI
-      for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
-        Value *V = PN->removeIncomingValue(Preds[i], false);
-        NewPHI->addIncoming(V, Preds[i]);
-      }
-      InVal = NewPHI;
-    } else {
-      // Remove all of the edges coming into the PHI nodes from outside of the
-      // block.
-      for (unsigned i = 0, e = Preds.size(); i != e; ++i)
-        PN->removeIncomingValue(Preds[i], false);
-    }
-
-    // Add an incoming value to the PHI node in the loop for the preheader
-    // edge.
-    PN->addIncoming(InVal, NewBB);
-
-    // Can we eliminate this phi node now?
-    if (Value *V = PN->hasConstantValue(true)) {
-      Instruction *I = dyn_cast<Instruction>(V);
-      if (!I || DT->dominates(I, PN)) {
-        PN->replaceAllUsesWith(V);
-        if (AA) AA->deleteValue(PN);
-        PN->eraseFromParent();
-      }
-    }
-  }
-
-  return NewBB;
-}
-
 /// InsertPreheaderForLoop - Once we discover that a loop doesn't have a
 /// preheader, this method is called to insert one.  This method has two phases:
 /// preheader insertion and analysis updating.
@@ -365,7 +267,7 @@
   BasicBlock *Header = L->getHeader();
 
   // Compute the set of predecessors of the loop that are not in the loop.
-  std::vector<BasicBlock*> OutsideBlocks;
+  SmallVector<BasicBlock*, 8> OutsideBlocks;
   for (pred_iterator PI = pred_begin(Header), PE = pred_end(Header);
        PI != PE; ++PI)
     if (!L->contains(*PI))           // Coming in from outside the loop?
@@ -373,7 +275,8 @@
 
   // Split out the loop pre-header.
   BasicBlock *NewBB =
-    SplitBlockPredecessors(Header, ".preheader", OutsideBlocks);
+    SplitBlockPredecessors(Header, &OutsideBlocks[0], OutsideBlocks.size(),
+                           ".preheader", this);
   
 
   //===--------------------------------------------------------------------===//
@@ -393,13 +296,15 @@
 /// blocks.  This method is used to split exit blocks that have predecessors
 /// outside of the loop.
 BasicBlock *LoopSimplify::RewriteLoopExitBlock(Loop *L, BasicBlock *Exit) {
-  std::vector<BasicBlock*> LoopBlocks;
+  SmallVector<BasicBlock*, 8> LoopBlocks;
   for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I)
     if (L->contains(*I))
       LoopBlocks.push_back(*I);
 
   assert(!LoopBlocks.empty() && "No edges coming in from outside the loop?");
-  BasicBlock *NewBB = SplitBlockPredecessors(Exit, ".loopexit", LoopBlocks);
+  BasicBlock *NewBB = SplitBlockPredecessors(Exit, &LoopBlocks[0], 
+                                             LoopBlocks.size(), ".loopexit",
+                                             this);
 
   // Update Loop Information - we know that the new block will be in whichever
   // loop the Exit block is in.  Note that it may not be in that immediate loop,
@@ -464,7 +369,7 @@
 // right after some 'outside block' block.  This prevents the preheader from
 // being placed inside the loop body, e.g. when the loop hasn't been rotated.
 void LoopSimplify::PlaceSplitBlockCarefully(BasicBlock *NewBB,
-                                            std::vector<BasicBlock*>&SplitPreds,
+                                       SmallVectorImpl<BasicBlock*> &SplitPreds,
                                             Loop *L) {
   // Check to see if NewBB is already well placed.
   Function::iterator BBI = NewBB; --BBI;
@@ -522,14 +427,16 @@
   // Pull out all predecessors that have varying values in the loop.  This
   // handles the case when a PHI node has multiple instances of itself as
   // arguments.
-  std::vector<BasicBlock*> OuterLoopPreds;
+  SmallVector<BasicBlock*, 8> OuterLoopPreds;
   for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
     if (PN->getIncomingValue(i) != PN ||
         !L->contains(PN->getIncomingBlock(i)))
       OuterLoopPreds.push_back(PN->getIncomingBlock(i));
 
   BasicBlock *Header = L->getHeader();
-  BasicBlock *NewBB = SplitBlockPredecessors(Header, ".outer", OuterLoopPreds);
+  BasicBlock *NewBB = SplitBlockPredecessors(Header, &OuterLoopPreds[0],
+                                             OuterLoopPreds.size(),
+                                             ".outer", this);
 
   // Make sure that NewBB is put someplace intelligent, which doesn't mess up
   // code layout too horribly.





More information about the llvm-commits mailing list