aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-07-17 23:55:56 +0000
committerDan Gohman <gohman@apple.com>2009-07-17 23:55:56 +0000
commit016de81177ec5c950f1668be4a48992bc1ee0d75 (patch)
treed851a88d72bc9c18dd42143f0fdbef05a31bd405
parent5918304c4cd0354c995a610e790162cff0ba78ba (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76265 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Operator.h42
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp29
-rw-r--r--lib/VMCore/Value.cpp29
3 files changed, 57 insertions, 43 deletions
diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h
index 1413ce3d20..2f9f9ca12c 100644
--- a/include/llvm/Operator.h
+++ b/include/llvm/Operator.h
@@ -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;
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index dbdf449f60..060abc5ad0 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -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;
}
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 3322c681d8..66fcaf38fb 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -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;
}