- Change getelementptr instruction to use long indexes instead of uint
[oota-llvm.git] / lib / Transforms / Scalar / SCCP.cpp
index c284b0d042994581ed49fbab68db1fb45f536661..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];
   }
@@ -185,7 +184,8 @@ private:
 
   // 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); }
@@ -517,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));  
+}