Don't insert nearly as many redundant phi nodes.
[oota-llvm.git] / lib / Transforms / Scalar / CondPropagate.cpp
index 49a849625b39949980f24f619b33b3ae9af7a6a7..6fc27d4aa642be6cf6af90751d9ac0bb5a72db0b 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/Type.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Streams.h"
 using namespace llvm;
 
@@ -29,7 +30,10 @@ STATISTIC(NumBrThread, "Number of CFG edges threaded through branches");
 STATISTIC(NumSwThread, "Number of CFG edges threaded through switches");
 
 namespace {
-  struct CondProp : public FunctionPass {
+  struct VISIBILITY_HIDDEN CondProp : public FunctionPass {
+    static char ID; // Pass identification, replacement for typeid
+    CondProp() : FunctionPass((intptr_t)&ID) {}
+
     virtual bool runOnFunction(Function &F);
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -44,6 +48,8 @@ namespace {
     void SimplifyPredecessors(SwitchInst *SI);
     void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB);
   };
+  
+  char CondProp::ID = 0;
   RegisterPass<CondProp> X("condprop", "Conditional Propagation");
 }
 
@@ -59,7 +65,7 @@ bool CondProp::runOnFunction(Function &F) {
     MadeChange = false;
     for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
       SimplifyBlock(BB);
-    EverMadeChange = MadeChange;
+    EverMadeChange = EverMadeChange || MadeChange;
   } while (MadeChange);
   return EverMadeChange;
 }
@@ -133,17 +139,18 @@ void CondProp::SimplifyPredecessors(BranchInst *BI) {
   // constants.  Walk from the end to remove operands from the end when
   // possible, and to avoid invalidating "i".
   for (unsigned i = PN->getNumIncomingValues(); i != 0; --i)
-    if (ConstantBool *CB = dyn_cast<ConstantBool>(PN->getIncomingValue(i-1))) {
+    if (ConstantInt *CB = dyn_cast<ConstantInt>(PN->getIncomingValue(i-1))) {
       // If we have a constant, forward the edge from its current to its
       // ultimate destination.
-      bool PHIGone = PN->getNumIncomingValues() == 2;
       RevectorBlockTo(PN->getIncomingBlock(i-1),
-                      BI->getSuccessor(CB->getValue() == 0));
+                      BI->getSuccessor(CB->isZero()));
       ++NumBrThread;
 
-      // If there were two predecessors before this simplification, the PHI node
-      // will be deleted.  Don't iterate through it the last time.
-      if (PHIGone) return;
+      // If there were two predecessors before this simplification, or if the
+      // PHI node contained all the same value except for the one we just
+      // substituted, the PHI node may be deleted.  Don't iterate through it the
+      // last time.
+      if (BI->getCondition() != PN) return;
     }
 }
 
@@ -171,16 +178,17 @@ void CondProp::SimplifyPredecessors(SwitchInst *SI) {
     if (ConstantInt *CI = dyn_cast<ConstantInt>(PN->getIncomingValue(i-1))) {
       // If we have a constant, forward the edge from its current to its
       // ultimate destination.
-      bool PHIGone = PN->getNumIncomingValues() == 2;
       unsigned DestCase = SI->findCaseValue(CI);
       RevectorBlockTo(PN->getIncomingBlock(i-1),
                       SI->getSuccessor(DestCase));
       ++NumSwThread;
       RemovedPreds = true;
 
-      // If there were two predecessors before this simplification, the PHI node
-      // will be deleted.  Don't iterate through it the last time.
-      if (PHIGone) return;
+      // If there were two predecessors before this simplification, or if the
+      // PHI node contained all the same value except for the one we just
+      // substituted, the PHI node may be deleted.  Don't iterate through it the
+      // last time.
+      if (SI->getCondition() != PN) return;
     }
 }