Handle PHINode with only one incoming value.
[oota-llvm.git] / lib / Transforms / Scalar / CondPropagate.cpp
index 138be522ee1092ceb401913de9c2fa752e42b38b..d7aa7eca26699c58df31017aef125bd26d27eab7 100644 (file)
@@ -1,10 +1,10 @@
 //===-- CondPropagate.cpp - Propagate Conditional Expressions -------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This pass propagates information about conditional expressions through the
@@ -46,7 +46,7 @@ namespace {
     void SimplifyPredecessors(SwitchInst *SI);
     void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB);
   };
-  RegisterOpt<CondProp> X("condprop", "Conditional Propagation");
+  RegisterPass<CondProp> X("condprop", "Conditional Propagation");
 }
 
 FunctionPass *llvm::createCondPropagationPass() {
@@ -73,24 +73,13 @@ void CondProp::SimplifyBlock(BasicBlock *BB) {
     if (BI->isConditional() && isa<PHINode>(BI->getCondition()) &&
         cast<PHINode>(BI->getCondition())->getParent() == BB)
       SimplifyPredecessors(BI);
-    
+
   } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
     if (isa<PHINode>(SI->getCondition()) &&
         cast<PHINode>(SI->getCondition())->getParent() == BB)
       SimplifyPredecessors(SI);
   }
 
-  // See if we can fold any PHI nodes in this block now.
-  // FIXME: This would not be required if removePredecessor did this for us!!
-  PHINode *PN;
-  for (BasicBlock::iterator I = BB->begin(); PN = dyn_cast<PHINode>(I++); )
-    if (Value *PNV = hasConstantValue(PN))
-      if (!isa<Instruction>(PNV)) {
-        PN->replaceAllUsesWith(PNV);
-        PN->eraseFromParent();
-        MadeChange = true;
-      }
-
   // If possible, simplify the terminator of this block.
   if (ConstantFoldTerminator(BB))
     MadeChange = true;
@@ -98,8 +87,18 @@ void CondProp::SimplifyBlock(BasicBlock *BB) {
   // If this block ends with an unconditional branch and the only successor has
   // only this block as a predecessor, merge the two blocks together.
   if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()))
-    if (BI->isUnconditional() && BI->getSuccessor(0)->getSinglePredecessor()) {
+    if (BI->isUnconditional() && BI->getSuccessor(0)->getSinglePredecessor() &&
+        BB != BI->getSuccessor(0)) {
       BasicBlock *Succ = BI->getSuccessor(0);
+      
+      // If Succ has any PHI nodes, they are all single-entry PHI's.
+      while (PHINode *PN = dyn_cast<PHINode>(Succ->begin())) {
+        assert(PN->getNumIncomingValues() == 1 &&
+               "PHI doesn't match parent block");
+        PN->replaceAllUsesWith(PN->getIncomingValue(0));
+        PN->eraseFromParent();
+      }
+      
       // Remove BI.
       BI->eraseFromParent();
 
@@ -197,11 +196,15 @@ void CondProp::RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB) {
   // Get the old block we are threading through.
   BasicBlock *OldSucc = FromBr->getSuccessor(0);
 
-  // ToBB should not have any PHI nodes in it to update, because OldSucc had
-  // multiple successors.  If OldSucc had multiple successor and ToBB had
-  // multiple predecessors, the edge between them would be critical, which we
-  // already took care of.
-  assert(!isa<PHINode>(ToBB->begin()) && "Critical Edge Found!");
+  // OldSucc had multiple successors. If ToBB has multiple predecessors, the
+  // edge between them would be critical, which we already took care of.
+  // If ToBB has single operand PHI node than take care of it here.
+  if (isa<PHINode>(ToBB->begin())) {
+    PHINode *PN = cast<PHINode>(ToBB->begin());
+    assert(PN->getNumIncomingValues() == 1 && "Critical Edge Found!");    
+    PN->replaceAllUsesWith(PN->getIncomingValue(0));
+    PN->eraseFromParent();
+  }
 
   // Update PHI nodes in OldSucc to know that FromBB no longer branches to it.
   OldSucc->removePredecessor(FromBB);