Make MergeBlockIntoPredecessor more aggressive when the same successor appears
authorOwen Anderson <resistor@mac.com>
Thu, 17 Jul 2008 19:42:29 +0000 (19:42 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 17 Jul 2008 19:42:29 +0000 (19:42 +0000)
more than once.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53731 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/BasicBlockUtils.h
lib/Transforms/Utils/BasicBlockUtils.cpp

index f1a7a2641766761906cbf9ccd20c1a2224a5d089..5b367015afa4eee9430c72dd8c00ec0c10231f7d 100644 (file)
@@ -27,7 +27,7 @@ class Pass;
 
 /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
 /// if possible.  The return value indicates success or failure.
 
 /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
 /// if possible.  The return value indicates success or failure.
-bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P);
+bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0);
 
 // ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
 // with a value, then remove and delete the original instruction.
 
 // ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
 // with a value, then remove and delete the original instruction.
index 02eb4d6f60a66607ab60a0a34e3e9dd123c05adc..d889422992b3104a8d302b41210eef33ae7f6162 100644 (file)
@@ -26,15 +26,30 @@ using namespace llvm;
 /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
 /// if possible.  The return value indicates success or failure.
 bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
 /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
 /// if possible.  The return value indicates success or failure.
 bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
+  pred_iterator PI(pred_begin(BB)), PE(pred_end(BB));
   // Can't merge the entry block.
   if (pred_begin(BB) == pred_end(BB)) return false;
   // Can't merge the entry block.
   if (pred_begin(BB) == pred_end(BB)) return false;
-  // Can't merge if there are multiple preds.
-  if (++pred_begin(BB) != pred_end(BB)) return false;
   
   
-  BasicBlock* PredBB = *pred_begin(BB);
+  BasicBlock *PredBB = *PI++;
+  for (; PI != PE; ++PI)  // Search all predecessors, see if they are all same
+    if (*PI != PredBB) {
+      PredBB = 0;       // There are multiple different predecessors...
+      break;
+    }
   
   
-  // Can't merge if the edge is critical.
-  if (PredBB->getTerminator()->getNumSuccessors() != 1) return false;
+  // Can't merge if there are multiple predecessors.
+  if (!PredBB) return false;
+  
+  succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
+  BasicBlock* OnlySucc = BB;
+  for (; SI != SE; ++SI)
+    if (*SI != OnlySucc) {
+      OnlySucc = 0;     // There are multiple distinct successors!
+      break;
+    }
+  
+  // Can't merge if there are multiple successors.
+  if (!OnlySucc) return false;
   
   // Begin by getting rid of unneeded PHIs.
   while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
   
   // Begin by getting rid of unneeded PHIs.
   while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
@@ -52,6 +67,10 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
   // source...
   BB->replaceAllUsesWith(PredBB);
   
   // source...
   BB->replaceAllUsesWith(PredBB);
   
+  // Inherit predecessors name if it exists.
+  if (!PredBB->hasName())
+    PredBB->takeName(BB);
+  
   // Finally, erase the old block and update dominator info.
   if (P) {
     if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {
   // Finally, erase the old block and update dominator info.
   if (P) {
     if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {