Convert more code to use Operator instead of explicitly handling both
authorDan Gohman <gohman@apple.com>
Fri, 17 Jul 2009 23:55:56 +0000 (23:55 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 17 Jul 2009 23:55:56 +0000 (23:55 +0000)
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

include/llvm/Operator.h
lib/Transforms/Scalar/InstructionCombining.cpp
lib/VMCore/Value.cpp

index 1413ce3d20ca72579f558e696e44bd83c1e0a8c6..2f9f9ca12ce3f2c05583b2678b0084ca32632c3a 100644 (file)
@@ -129,6 +129,48 @@ public:
 
 class GEPOperator : public Operator {
 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;
   /// 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;
index dbdf449f60f2cd4b18cb62ad5f1cf442ab905ec2..060abc5ad0857b07168c517626874abb661bb1c7 100644 (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) {
 /// 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;
 }
   }
   return 0;
 }
index 3322c681d8efdb1d11c669ffe1c95521be0c1679..66fcaf38fba3cc1b9a0f9ac386f6a1d77990009a 100644 (file)
@@ -343,23 +343,12 @@ Value *Value::stripPointerCasts() {
     return this;
   Value *V = this;
   do {
     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;
       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;
     }
     } else {
       return V;
     }
@@ -373,12 +362,12 @@ Value *Value::getUnderlyingObject() {
   Value *V = this;
   unsigned MaxLookup = 6;
   do {
   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;
         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;
     }
     } else {
       return V;
     }