Implement CFGSimplify/PhiBlockMerge*.ll
authorChris Lattner <sabre@nondot.org>
Wed, 5 Mar 2003 21:36:33 +0000 (21:36 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 5 Mar 2003 21:36:33 +0000 (21:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5702 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/SimplifyCFG.cpp

index b1a1bdee0575fec979250706cebd881f79dc907a..3b658aacb4007fd31541dbacf3e6a0e750e87c19 100644 (file)
@@ -39,8 +39,8 @@ static bool PropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
     if (find(BBPreds.begin(), BBPreds.end(), *PI) != BBPreds.end()) {
       // Loop over all of the PHI nodes checking to see if there are
       // incompatible values coming in.
-      BasicBlock::iterator BBI = Succ->begin();
-      while (PHINode *PN = dyn_cast<PHINode>(&*BBI++)) {
+      for (BasicBlock::iterator I = Succ->begin();
+           PHINode *PN = dyn_cast<PHINode>(&*I); ++I) {
         // Loop up the entries in the PHI node for BB and for *PI if the values
         // coming in are non-equal, we cannot merge these two blocks (instead we
         // should insert a conditional move or something, then merge the
@@ -60,10 +60,19 @@ static bool PropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
     Value *OldVal = PN->removeIncomingValue(BB, false);
     assert(OldVal && "No entry in PHI for Pred BB!");
 
-    for (std::vector<BasicBlock*>::const_iterator PredI = BBPreds.begin(), 
-          End = BBPreds.end(); PredI != End; ++PredI) {
-      // Add an incoming value for each of the new incoming values...
-      PN->addIncoming(OldVal, *PredI);
+    // If this incoming value is one of the PHI nodes in BB...
+    if (isa<PHINode>(OldVal) && cast<PHINode>(OldVal)->getParent() == BB) {
+      PHINode *OldValPN = cast<PHINode>(OldVal);
+      for (std::vector<BasicBlock*>::const_iterator PredI = BBPreds.begin(), 
+             End = BBPreds.end(); PredI != End; ++PredI) {
+        PN->addIncoming(OldValPN->getIncomingValueForBlock(*PredI), *PredI);
+      }
+    } else {
+      for (std::vector<BasicBlock*>::const_iterator PredI = BBPreds.begin(), 
+             End = BBPreds.end(); PredI != End; ++PredI) {
+        // Add an incoming value for each of the new incoming values...
+        PN->addIncoming(OldVal, *PredI);
+      }
     }
   }
   return false;
@@ -84,7 +93,6 @@ bool SimplifyCFG(BasicBlock *BB) {
   assert(BB->getTerminator() && "Degenerate basic block encountered!");
   assert(&BB->getParent()->front() != BB && "Can't Simplify entry block!");
 
-
   // Remove basic blocks that have no predecessors... which are unreachable.
   if (pred_begin(BB) == pred_end(BB) &&
       !BB->hasConstantReferences()) {
@@ -113,11 +121,16 @@ bool SimplifyCFG(BasicBlock *BB) {
     return true;
   }
 
-  // Check to see if this block has no instructions and only a single 
-  // successor.  If so, replace block references with successor.
+  // Check to see if this block has no non-phi instructions and only a single
+  // successor.  If so, replace references to this basic block with references
+  // to the successor.
   succ_iterator SI(succ_begin(BB));
   if (SI != succ_end(BB) && ++SI == succ_end(BB)) {  // One succ?
-    if (BB->front().isTerminator()) {   // Terminator is the only instruction!
+
+    BasicBlock::iterator BBI = BB->begin();  // Skip over phi nodes...
+    while (isa<PHINode>(*BBI)) ++BBI;
+
+    if (BBI->isTerminator()) {   // Terminator is the only non-phi instruction!
       BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor
      
       if (Succ != BB) {   // Arg, don't hurt infinite loops!
@@ -131,6 +144,19 @@ bool SimplifyCFG(BasicBlock *BB) {
           BB->replaceAllUsesWith(Succ);
           std::string OldName = BB->getName();
 
+          // Move all PHI nodes in BB to Succ if they are alive, otherwise
+          // delete them.
+          while (PHINode *PN = dyn_cast<PHINode>(&BB->front()))
+            if (PN->use_empty())
+              BB->getInstList().erase(BB->begin());  // Nuke instruction...
+            else {
+              // The instruction is alive, so this means that Succ must have
+              // *ONLY* had BB as a predecessor, and the PHI node is still valid
+              // now.  Simply move it into Succ.
+              BB->getInstList().remove(BB->begin());
+              Succ->getInstList().push_front(PN);
+            }
+
           // Delete the old basic block...
           M->getBasicBlockList().erase(BB);