summaryrefslogtreecommitdiff
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)
downloadllvm-016de81177ec5c950f1668be4a48992bc1ee0d75.tar.gz
llvm-016de81177ec5c950f1668be4a48992bc1ee0d75.tar.bz2
llvm-016de81177ec5c950f1668be4a48992bc1ee0d75.tar.xz
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;
}