- Implement SCCP of getelementptr instructions

- Implement SCCP of globals into ConstantExprs hopefully opening new
   opportunities for more SCCP.

llvm-svn: 3555
This commit is contained in:
Chris Lattner 2002-08-30 23:39:00 +00:00
parent 7495a9b13a
commit dd6522e7a0
1 changed files with 31 additions and 5 deletions

View 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
@ -40,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
@ -151,6 +149,9 @@ 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];
@ -184,7 +185,7 @@ private:
// Instructions that cannot be folded away...
void visitStoreInst (Instruction &I) { /*returns void*/ }
void visitLoadInst (Instruction &I) { markOverdefined(&I); }
void visitGetElementPtrInst(Instruction &I) { markOverdefined(&I); } // FIXME
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitCallInst (Instruction &I) { markOverdefined(&I); }
void visitInvokeInst (Instruction &I) { markOverdefined(&I); }
void visitAllocationInst(Instruction &I) { markOverdefined(&I); }
@ -516,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));
}