- Renamed Type::isIntegral() to Type::isInteger()
[oota-llvm.git] / lib / Transforms / Scalar / SCCP.cpp
index b32481e48bb9cea826822755e7042b7a672ef33a..ff5cdcb74c08524531d11749891a797c109f88c3 100644 (file)
@@ -6,8 +6,7 @@
 //   * Assumes values are constant unless proven otherwise
 //   * Assumes BasicBlocks are dead unless proven otherwise
 //   * Proves values to be constant, and replaces them with constants
-//   * Proves conditional branches constant, and unconditionalizes them
-//   * Folds multiple identical constants in the constant pool together
+//   * Proves conditional branches to be unconditional
 //
 // Notice that:
 //   * This pass has a habit of making definitions be dead.  It is a good idea
@@ -18,7 +17,6 @@
 #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"
@@ -29,7 +27,6 @@
 #include "Support/StatisticReporter.h"
 #include <algorithm>
 #include <set>
-#include <iostream>
 using std::cerr;
 
 static Statistic<> NumInstRemoved("sccp\t\t- Number of instructions removed");
@@ -42,7 +39,6 @@ class InstVal {
   enum { 
     undefined,           // This instruction has no known value
     constant,            // This instruction has a constant value
-    // Range,            // This instruction is known to fall within a range
     overdefined          // This instruction has an unknown value
   } LatticeValue;        // The current lattice position
   Constant *ConstantVal; // If Constant value, the current value
@@ -153,7 +149,10 @@ private:
       ValueState[CPV].markConstant(CPV);
     } else if (isa<Argument>(V)) {                // Arguments are overdefined
       ValueState[V].markOverdefined();
-    } 
+    } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+      // The address of a global is a constant...
+      ValueState[V].markConstant(ConstantPointerRef::get(GV));
+    }
     // All others are underdefined by default...
     return ValueState[V];
   }
@@ -179,14 +178,14 @@ private:
   void visitReturnInst(ReturnInst &I) { /*does not have an effect*/ }
   void visitTerminatorInst(TerminatorInst &TI);
 
-  void visitUnaryOperator(Instruction &I);
-  void visitCastInst(CastInst &I) { visitUnaryOperator(I); }
+  void visitCastInst(CastInst &I);
   void visitBinaryOperator(Instruction &I);
   void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
 
   // Instructions that cannot be folded away...
   void visitStoreInst     (Instruction &I) { /*returns void*/ }
-  void visitMemAccessInst (Instruction &I) { markOverdefined(&I); }
+  void visitLoadInst      (Instruction &I) { markOverdefined(&I); }
+  void visitGetElementPtrInst(GetElementPtrInst &I);
   void visitCallInst      (Instruction &I) { markOverdefined(&I); }
   void visitInvokeInst    (Instruction &I) { markOverdefined(&I); }
   void visitAllocationInst(Instruction &I) { markOverdefined(&I); }
@@ -220,7 +219,7 @@ private:
   }
 };
 
-  RegisterPass<SCCP> X("sccp", "Sparse Conditional Constant Propogation");
+  RegisterOpt<SCCP> X("sccp", "Sparse Conditional Constant Propogation");
 } // end anonymous namespace
 
 
@@ -478,15 +477,14 @@ void SCCP::visitTerminatorInst(TerminatorInst &TI) {
     }
 }
 
-void SCCP::visitUnaryOperator(Instruction &I) {
+void SCCP::visitCastInst(CastInst &I) {
   Value *V = I.getOperand(0);
   InstVal &VState = getValueState(V);
   if (VState.isOverdefined()) {        // Inherit overdefinedness of operand
     markOverdefined(&I);
   } else if (VState.isConstant()) {    // Propogate constant value
-    Constant *Result = isa<CastInst>(I)
-      ? ConstantFoldCastInstruction(VState.getConstant(), I.getType())
-      : ConstantFoldUnaryInstruction(I.getOpcode(), VState.getConstant());
+    Constant *Result =
+      ConstantFoldCastInstruction(VState.getConstant(), I.getType());
 
     if (Result) {
       // This instruction constant folds!
@@ -519,3 +517,28 @@ void SCCP::visitBinaryOperator(Instruction &I) {
       markOverdefined(&I);   // Don't know how to fold this instruction.  :(
   }
 }
+
+// Handle getelementptr instructions... if all operands are constants then we
+// can turn this into a getelementptr ConstantExpr.
+//
+void SCCP::visitGetElementPtrInst(GetElementPtrInst &I) {
+  std::vector<Constant*> Operands;
+  Operands.reserve(I.getNumOperands());
+
+  for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
+    InstVal &State = getValueState(I.getOperand(i));
+    if (State.isUndefined())
+      return;  // Operands are not resolved yet...
+    else if (State.isOverdefined()) {
+      markOverdefined(&I);
+      return;
+    }
+    assert(State.isConstant() && "Unknown state!");
+    Operands.push_back(State.getConstant());
+  }
+
+  Constant *Ptr = Operands[0];
+  Operands.erase(Operands.begin());  // Erase the pointer from idx list...
+
+  markConstant(&I, ConstantExpr::getGetElementPtr(Ptr, Operands));  
+}