Fix bug: test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll
[oota-llvm.git] / lib / Transforms / Scalar / SCCP.cpp
index e42baacfbfd848c23b55392ba39fbccedadd1d2b..05945458cb6df65f7afd7e904614404b14705110 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/Scalar/ConstantProp.h"
+#include "llvm/Transforms/Scalar.h"
 #include "llvm/ConstantHandling.h"
 #include "llvm/Function.h"
+#include "llvm/BasicBlock.h"
 #include "llvm/iPHINode.h"
 #include "llvm/iMemory.h"
 #include "llvm/iTerminators.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/InstVisitor.h"
 #include "Support/STLExtras.h"
+#include "Support/StatisticReporter.h"
 #include <algorithm>
 #include <set>
 #include <iostream>
 using std::cerr;
 
+static Statistic<> NumInstRemoved("sccp\t\t- Number of instructions removed");
+
 #if 0    // Enable this to get SCCP debug output
 #define DEBUG_SCCP(X) X
 #else
@@ -92,7 +96,7 @@ class SCCP : public FunctionPass, public InstVisitor<SCCP> {
   std::set<BasicBlock*>     BBExecutable;// The basic blocks that are executable
   std::map<Value*, InstVal> ValueState;  // The state each value is in...
 
-  std::set<Instruction*>    InstWorkList;// The instruction work list
+  std::vector<Instruction*> InstWorkList;// The instruction work list
   std::vector<BasicBlock*>  BBWorkList;  // The BasicBlock work list
 public:
 
@@ -124,7 +128,7 @@ private:
     DEBUG_SCCP(cerr << "markConstant: " << V << " = " << I);
 
     if (ValueState[I].markConstant(V)) {
-      InstWorkList.insert(I);
+      InstWorkList.push_back(I);
       return true;
     }
     return false;
@@ -138,7 +142,7 @@ private:
     if (ValueState[V].markOverdefined()) {
       if (Instruction *I = dyn_cast<Instruction>(V)) {
        DEBUG_SCCP(cerr << "markOverdefined: " << V);
-       InstWorkList.insert(I);  // Only instructions go on the work list
+       InstWorkList.push_back(I);  // Only instructions go on the work list
       }
       return true;
     }
@@ -251,8 +255,8 @@ bool SCCP::runOnFunction(Function *F) {
   while (!BBWorkList.empty() || !InstWorkList.empty()) {
     // Process the instruction work list...
     while (!InstWorkList.empty()) {
-      Instruction *I = *InstWorkList.begin();
-      InstWorkList.erase(InstWorkList.begin());
+      Instruction *I = InstWorkList.back();
+      InstWorkList.pop_back();
 
       DEBUG_SCCP(cerr << "\nPopped off I-WL: " << I);
 
@@ -285,7 +289,7 @@ bool SCCP::runOnFunction(Function *F) {
     }
   }
 
-#ifdef DEBUG_SCCP
+#if 0
   for (Function::iterator BBI = F->begin(), BBEnd = F->end();
        BBI != BBEnd; ++BBI)
     if (!BBExecutable.count(*BBI))
@@ -314,6 +318,7 @@ bool SCCP::runOnFunction(Function *F) {
 
         // Hey, we just changed something!
         MadeChanges = true;
+        ++NumInstRemoved;
       } else {
         ++BI;
       }
@@ -502,9 +507,15 @@ void SCCP::visitBinaryOperator(Instruction *I) {
   if (V1State.isOverdefined() || V2State.isOverdefined()) {
     markOverdefined(I);
   } else if (V1State.isConstant() && V2State.isConstant()) {
-    Constant *Result = ConstantFoldBinaryInstruction(I->getOpcode(),
-                                                     V1State.getConstant(),
-                                                     V2State.getConstant());
+    Constant *Result = 0;
+    if (isa<BinaryOperator>(I))
+      Result = ConstantFoldBinaryInstruction(I->getOpcode(),
+                                             V1State.getConstant(),
+                                             V2State.getConstant());
+    else if (isa<ShiftInst>(I))
+      Result = ConstantFoldShiftInstruction(I->getOpcode(),
+                                            V1State.getConstant(),
+                                            V2State.getConstant());
     if (Result)
       markConstant(I, Result);      // This instruction constant folds!
     else