[llvm-commits] [llvm] r56922 - in /llvm/trunk: include/llvm/Value.h lib/Analysis/BasicAliasAnalysis.cpp lib/Analysis/IPA/GlobalsModRef.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/InstructionCombining.cpp lib/VMCore/Value.cpp

Duncan Sands baldrick at free.fr
Wed Oct 1 08:25:41 PDT 2008


Author: baldrick
Date: Wed Oct  1 10:25:41 2008
New Revision: 56922

URL: http://llvm.org/viewvc/llvm-project?rev=56922&view=rev
Log:
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.

Modified:
    llvm/trunk/include/llvm/Value.h
    llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp
    llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
    llvm/trunk/lib/Transforms/Scalar/GVN.cpp
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/lib/VMCore/Value.cpp

Modified: llvm/trunk/include/llvm/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Value.h (original)
+++ llvm/trunk/include/llvm/Value.h Wed Oct  1 10:25:41 2008
@@ -228,11 +228,20 @@
 
   /// stripPointerCasts - This method strips off any unneeded pointer
   /// casts from the specified value, returning the original uncasted value.
-  /// Note that the returned value is guaranteed to have pointer type.
+  /// Note that the returned value has pointer type if the specified value does.
   Value *stripPointerCasts();
   const Value *stripPointerCasts() const {
     return const_cast<Value*>(this)->stripPointerCasts();
   }
+
+  /// getUnderlyingObject - This method strips off any GEP address adjustments
+  /// and pointer casts from the specified value, returning the original object
+  /// being addressed.  Note that the returned value has pointer type if the
+  /// specified value does.
+  Value *getUnderlyingObject();
+  const Value *getUnderlyingObject() const {
+    return const_cast<Value*>(this)->getUnderlyingObject();
+  }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const Value &V) {

Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Wed Oct  1 10:25:41 2008
@@ -76,30 +76,6 @@
   return false;
 }
 
-/// getUnderlyingObject - This traverses the use chain to figure out what object
-/// the specified value points to.  If the value points to, or is derived from,
-/// a unique object or an argument, return it.  This returns:
-///    Arguments, GlobalVariables, Functions, Allocas, Mallocs.
-static const Value *getUnderlyingObject(const Value *V) {
-  if (!isa<PointerType>(V->getType())) return V;
-
-  // If we are at some type of object, return it. GlobalValues and Allocations
-  // have unique addresses. 
-  if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isa<Argument>(V))
-    return V;
-
-  // Traverse through different addressing mechanisms...
-  if (const Instruction *I = dyn_cast<Instruction>(V)) {
-    if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
-      return getUnderlyingObject(I->getOperand(0));
-  } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
-    if (CE->getOpcode() == Instruction::BitCast || 
-        CE->getOpcode() == Instruction::GetElementPtr)
-      return getUnderlyingObject(CE->getOperand(0));
-  }
-  return V;
-}
-
 static const User *isGEP(const Value *V) {
   if (isa<GetElementPtrInst>(V) ||
       (isa<ConstantExpr>(V) &&
@@ -314,7 +290,7 @@
 /// global) or not.
 bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) {
   if (const GlobalVariable *GV = 
-        dyn_cast<GlobalVariable>(getUnderlyingObject(P)))
+        dyn_cast<GlobalVariable>(P->getUnderlyingObject()))
     return GV->isConstant();
   return false;
 }
@@ -327,7 +303,7 @@
 AliasAnalysis::ModRefResult
 BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
   if (!isa<Constant>(P)) {
-    const Value *Object = getUnderlyingObject(P);
+    const Value *Object = P->getUnderlyingObject();
     
     // If this is a tail call and P points to a stack location, we know that
     // the tail call cannot access or modify the local stack.
@@ -390,8 +366,8 @@
     return alias(V1, V1Size, I->getOperand(0), V2Size);
 
   // Figure out what objects these things are pointing to if we can...
-  const Value *O1 = getUnderlyingObject(V1);
-  const Value *O2 = getUnderlyingObject(V2);
+  const Value *O1 = V1->getUnderlyingObject();
+  const Value *O2 = V2->getUnderlyingObject();
 
   if (O1 != O2) {
     // If V1/V2 point to two different objects we know that we have no alias.

Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original)
+++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Wed Oct  1 10:25:41 2008
@@ -157,29 +157,6 @@
 
 Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
 
-/// getUnderlyingObject - This traverses the use chain to figure out what object
-/// the specified value points to.  If the value points to, or is derived from,
-/// a global object, return it.
-static Value *getUnderlyingObject(Value *V) {
-  if (!isa<PointerType>(V->getType())) return V;
-
-  // If we are at some type of object... return it.
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV;
-
-  // Traverse through different addressing mechanisms.
-  if (Instruction *I = dyn_cast<Instruction>(V)) {
-    if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
-      return getUnderlyingObject(I->getOperand(0));
-  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
-    if (CE->getOpcode() == Instruction::BitCast ||
-        CE->getOpcode() == Instruction::GetElementPtr)
-      return getUnderlyingObject(CE->getOperand(0));
-  }
-
-  // Otherwise, we don't know what this is, return it as the base pointer.
-  return V;
-}
-
 /// AnalyzeGlobals - Scan through the users of all of the internal
 /// GlobalValue's in the program.  If none of them have their "address taken"
 /// (really, their address passed to something nontrivial), record this fact,
@@ -304,7 +281,7 @@
         continue;
 
       // Check the value being stored.
-      Value *Ptr = getUnderlyingObject(SI->getOperand(0));
+      Value *Ptr = SI->getOperand(0)->getUnderlyingObject();
 
       if (isa<MallocInst>(Ptr)) {
         // Okay, easy case.
@@ -468,8 +445,8 @@
 GlobalsModRef::alias(const Value *V1, unsigned V1Size,
                      const Value *V2, unsigned V2Size) {
   // Get the base object these pointers point to.
-  Value *UV1 = getUnderlyingObject(const_cast<Value*>(V1));
-  Value *UV2 = getUnderlyingObject(const_cast<Value*>(V2));
+  Value *UV1 = const_cast<Value*>(V1->getUnderlyingObject());
+  Value *UV2 = const_cast<Value*>(V2->getUnderlyingObject());
 
   // If either of the underlying values is a global, they may be non-addr-taken
   // globals, which we can answer queries about.
@@ -526,7 +503,7 @@
 
   // If we are asking for mod/ref info of a direct call with a pointer to a
   // global we are tracking, return information if we have it.
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(getUnderlyingObject(P)))
+  if (GlobalValue *GV = dyn_cast<GlobalValue>(P->getUnderlyingObject()))
     if (GV->hasInternalLinkage())
       if (Function *F = CS.getCalledFunction())
         if (NonAddressTakenGlobals.count(GV))

Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Wed Oct  1 10:25:41 2008
@@ -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);

Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Oct  1 10:25:41 2008
@@ -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.

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Oct  1 10:25:41 2008
@@ -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()));

Modified: llvm/trunk/lib/VMCore/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=56922&r1=56921&r2=56922&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Value.cpp (original)
+++ llvm/trunk/lib/VMCore/Value.cpp Wed Oct  1 10:25:41 2008
@@ -322,22 +322,20 @@
 }
 
 Value *Value::stripPointerCasts() {
+  if (!isa<PointerType>(getType()))
+    return this;
+
   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
     if (CE->getOpcode() == Instruction::BitCast) {
-      if (isa<PointerType>(CE->getOperand(0)->getType()))
-        return CE->getOperand(0)->stripPointerCasts();
+      return CE->getOperand(0)->stripPointerCasts();
     } else if (CE->getOpcode() == Instruction::GetElementPtr) {
       for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
         if (!CE->getOperand(i)->isNullValue())
           return this;
       return CE->getOperand(0)->stripPointerCasts();
     }
-    return this;
-  }
-
-  if (BitCastInst *CI = dyn_cast<BitCastInst>(this)) {
-    if (isa<PointerType>(CI->getOperand(0)->getType()))
-      return CI->getOperand(0)->stripPointerCasts();
+  } else if (BitCastInst *CI = dyn_cast<BitCastInst>(this)) {
+    return CI->getOperand(0)->stripPointerCasts();
   } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(this)) {
     if (GEP->hasAllZeroIndices())
       return GEP->getOperand(0)->stripPointerCasts();
@@ -345,6 +343,21 @@
   return this;
 }
 
+Value *Value::getUnderlyingObject() {
+  if (!isa<PointerType>(getType()))
+    return this;
+
+  if (Instruction *I = dyn_cast<Instruction>(this)) {
+    if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
+      return I->getOperand(0)->getUnderlyingObject();
+  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
+    if (CE->getOpcode() == Instruction::BitCast ||
+        CE->getOpcode() == Instruction::GetElementPtr)
+      return CE->getOperand(0)->getUnderlyingObject();
+  }
+  return this;
+}
+
 //===----------------------------------------------------------------------===//
 //                                 User Class
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list