Convert more code to use Operator instead of explicitly handling both

ConstantExpr and Instruction. This involves duplicating some code
between GetElementPtrInst and GEPOperator, but it's not a lot.

llvm-svn: 76265
This commit is contained in:
Dan Gohman 2009-07-17 23:55:56 +00:00
parent ce3842ae4f
commit e45061eefe
3 changed files with 57 additions and 43 deletions

View File

@ -129,6 +129,48 @@ public:
class GEPOperator : public Operator {
public:
inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; }
inline op_iterator idx_end() { return op_end(); }
inline const_op_iterator idx_end() const { return op_end(); }
Value *getPointerOperand() {
return getOperand(0);
}
const Value *getPointerOperand() const {
return getOperand(0);
}
static unsigned getPointerOperandIndex() {
return 0U; // get index for modifying correct operand
}
/// getPointerOperandType - Method to return the pointer operand as a
/// PointerType.
const PointerType *getPointerOperandType() const {
return reinterpret_cast<const PointerType*>(getPointerOperand()->getType());
}
unsigned getNumIndices() const { // Note: always non-negative
return getNumOperands() - 1;
}
bool hasIndices() const {
return getNumOperands() > 1;
}
/// hasAllZeroIndices - Return true if all of the indices of this GEP are
/// zeros. If so, the result pointer and the first operand have the same
/// value, just potentially different types.
bool hasAllZeroIndices() const {
for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
if (Constant *C = dyn_cast<Constant>(I))
if (C->isNullValue())
continue;
return false;
}
return true;
}
/// hasNoPointerOverflow - Return true if this GetElementPtr is known to
/// never have overflow in the pointer addition portions of its effective
/// computation. GetElementPtr computation involves several phases;

View File

@ -441,29 +441,12 @@ static const Type *getPromotedType(const Type *Ty) {
/// expression bitcast, or a GetElementPtrInst with all zero indices, return the
/// operand value, otherwise return null.
static Value *getBitCastOperand(Value *V) {
if (BitCastInst *I = dyn_cast<BitCastInst>(V))
// BitCastInst?
return I->getOperand(0);
else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
// GetElementPtrInst?
if (GEP->hasAllZeroIndices())
return GEP->getOperand(0);
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() == Instruction::BitCast)
// BitCast ConstantExp?
return CE->getOperand(0);
else if (CE->getOpcode() == Instruction::GetElementPtr) {
// GetElementPtr ConstantExp?
for (User::op_iterator I = CE->op_begin() + 1, E = CE->op_end();
I != E; ++I) {
ConstantInt *CI = dyn_cast<ConstantInt>(I);
if (!CI || !CI->isZero())
// Any non-zero indices? Not cast-like.
return 0;
}
// All-zero indices? This is just like casting.
return CE->getOperand(0);
}
if (Operator *O = dyn_cast<Operator>(V)) {
if (O->getOpcode() == Instruction::BitCast)
return O->getOperand(0);
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
if (GEP->hasAllZeroIndices())
return GEP->getPointerOperand();
}
return 0;
}

View File

@ -343,23 +343,12 @@ Value *Value::stripPointerCasts() {
return this;
Value *V = this;
do {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() == Instruction::GetElementPtr) {
for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
if (!CE->getOperand(i)->isNullValue())
return V;
V = CE->getOperand(0);
} else if (CE->getOpcode() == Instruction::BitCast) {
V = CE->getOperand(0);
} else {
return V;
}
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
if (!GEP->hasAllZeroIndices())
return V;
V = GEP->getOperand(0);
} else if (BitCastInst *CI = dyn_cast<BitCastInst>(V)) {
V = CI->getOperand(0);
V = GEP->getPointerOperand();
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
V = cast<Operator>(V)->getOperand(0);
} else {
return V;
}
@ -373,12 +362,12 @@ Value *Value::getUnderlyingObject() {
Value *V = this;
unsigned MaxLookup = 6;
do {
if (Operator *O = dyn_cast<Operator>(V)) {
if (O->getOpcode() != Instruction::BitCast &&
(O->getOpcode() != Instruction::GetElementPtr ||
!cast<GEPOperator>(V)->hasNoPointerOverflow()))
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
if (GEP->hasNoPointerOverflow())
return V;
V = O->getOperand(0);
V = GEP->getPointerOperand();
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
V = cast<Operator>(V)->getOperand(0);
} else {
return V;
}