Factorize code: remove variants of "strip off
pointer bitcasts and GEP's", and centralize the
logic in Value::getUnderlyingObject.  The
difference with stripPointerCasts is that
stripPointerCasts only strips GEPs if all
indices are zero, while getUnderlyingObject
strips GEPs no matter what the indices are.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56922 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 7e5fbcb..c9211c3 100644
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -59,28 +59,7 @@
                               SetVector<Instruction*>& possiblyDead);
     void DeleteDeadInstructionChains(Instruction *I,
                                      SetVector<Instruction*> &DeadInsts);
-    
-    /// Find the base pointer that a pointer came from
-    /// Because this is used to find pointers that originate
-    /// from allocas, it is safe to ignore GEP indices, since
-    /// either the store will be in the alloca, and thus dead,
-    /// or beyond the end of the alloca, and thus undefined.
-    void TranslatePointerBitCasts(Value*& v, bool zeroGepsOnly = false) {
-      assert(isa<PointerType>(v->getType()) &&
-             "Translating a non-pointer type?");
-      while (true) {
-        if (BitCastInst* C = dyn_cast<BitCastInst>(v))
-          v = C->getOperand(0);
-        else if (GetElementPtrInst* G = dyn_cast<GetElementPtrInst>(v))
-          if (!zeroGepsOnly || G->hasAllZeroIndices()) {
-            v = G->getOperand(0);
-          } else {
-            break;
-          }
-        else
-          break;
-      }
-    }
+
 
     // getAnalysisUsage - We require post dominance frontiers (aka Control
     // Dependence Graph)
@@ -119,20 +98,20 @@
     // If we find a store or a free...
     if (!isa<StoreInst>(BBI) && !isa<FreeInst>(BBI))
       continue;
-      
+
     Value* pointer = 0;
     if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
-      if (!S->isVolatile())
-        pointer = S->getPointerOperand();
-      else
+      if (S->isVolatile())
         continue;
-    } else
+      pointer = S->getPointerOperand();
+    } else {
       pointer = cast<FreeInst>(BBI)->getPointerOperand();
-      
-    TranslatePointerBitCasts(pointer, true);
+    }
+
+    pointer = pointer->stripPointerCasts();
     StoreInst*& last = lastStore[pointer];
     bool deletedStore = false;
-      
+
     // ... to a pointer that has been stored to before...
     if (last) {
       Instruction* dep = MD.getDependency(BBI);
@@ -302,10 +281,9 @@
     // If we find a store whose pointer is dead...
     if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
       if (!S->isVolatile()) {
-        Value* pointerOperand = S->getPointerOperand();
         // See through pointer-to-pointer bitcasts
-        TranslatePointerBitCasts(pointerOperand);
-      
+        Value* pointerOperand = S->getPointerOperand()->getUnderlyingObject();
+
         // Alloca'd pointers or byval arguments (which are functionally like
         // alloca's) are valid candidates for removal.
         if (deadPointers.count(pointerOperand)) {
@@ -330,9 +308,8 @@
     
     // We can also remove memcpy's to local variables at the end of a function
     } else if (MemCpyInst* M = dyn_cast<MemCpyInst>(BBI)) {
-      Value* dest = M->getDest();
-      TranslatePointerBitCasts(dest);
-      
+      Value* dest = M->getDest()->getUnderlyingObject();
+
       if (deadPointers.count(dest)) {
         MD.removeInstruction(M);
         
@@ -480,9 +457,9 @@
     
     if (!killPointer)
       continue;
-    
-    TranslatePointerBitCasts(killPointer);
-    
+
+    killPointer = killPointer->getUnderlyingObject();
+
     // Deal with undead pointers
     MadeChange |= RemoveUndeadPointers(killPointer, killPointerSize, BBI,
                                        deadPointers, possiblyDead);
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index 1e5be4a..25b61c1 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -992,16 +992,7 @@
       isa<AllocationInst>(dep)) {
     // Check that this load is actually from the
     // allocation we found
-    Value* v = L->getOperand(0);
-    while (true) {
-      if (BitCastInst *BC = dyn_cast<BitCastInst>(v))
-        v = BC->getOperand(0);
-      else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(v))
-        v = GEP->getOperand(0);
-      else
-        break;
-    }
-    if (v == dep) {
+    if (L->getOperand(0)->getUnderlyingObject() == dep) {
       // If this load depends directly on an allocation, there isn't
       // anything stored there; therefore, we can optimize this load
       // to undef.
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 6cac395..4f48971 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -10367,28 +10367,6 @@
   return false;
 }
 
-/// GetUnderlyingObject - Trace through a series of getelementptrs and bitcasts
-/// until we find the underlying object a pointer is referring to or something
-/// we don't understand.  Note that the returned pointer may be offset from the
-/// input, because we ignore GEP indices.
-static Value *GetUnderlyingObject(Value *Ptr) {
-  while (1) {
-    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) {
-      if (CE->getOpcode() == Instruction::BitCast ||
-          CE->getOpcode() == Instruction::GetElementPtr)
-        Ptr = CE->getOperand(0);
-      else
-        return Ptr;
-    } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(Ptr)) {
-      Ptr = BCI->getOperand(0);
-    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
-      Ptr = GEP->getOperand(0);
-    } else {
-      return Ptr;
-    }
-  }
-}
-
 Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
   Value *Op = LI.getOperand(0);
 
@@ -10479,7 +10457,7 @@
     
   // If this load comes from anywhere in a constant global, and if the global
   // is all undef or zero, we know what it loads.
-  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GetUnderlyingObject(Op))) {
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op->getUnderlyingObject())){
     if (GV->isConstant() && GV->hasInitializer()) {
       if (GV->getInitializer()->isNullValue())
         return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType()));