- Somehow I forgot about one / une.
[oota-llvm.git] / lib / Transforms / Scalar / DeadStoreElimination.cpp
index bbb3a8a34472b6d792c07a11db14ede57cb0dc60..c9211c3252344f427a93e983334f1ae7947bde57 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Transforms/Utils/Local.h"
@@ -38,7 +39,7 @@ STATISTIC(NumFastOther , "Number of other instrs removed");
 namespace {
   struct VISIBILITY_HIDDEN DSE : public FunctionPass {
     static char ID; // Pass identification, replacement for typeid
-    DSE() : FunctionPass((intptr_t)&ID) {}
+    DSE() : FunctionPass(&ID) {}
 
     virtual bool runOnFunction(Function &F) {
       bool Changed = false;
@@ -58,36 +59,17 @@ namespace {
                               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)
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesCFG();
+      AU.addRequired<DominatorTree>();
       AU.addRequired<TargetData>();
       AU.addRequired<AliasAnalysis>();
       AU.addRequired<MemoryDependenceAnalysis>();
+      AU.addPreserved<DominatorTree>();
       AU.addPreserved<AliasAnalysis>();
       AU.addPreserved<MemoryDependenceAnalysis>();
     }
@@ -116,20 +98,20 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
     // 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);
@@ -172,8 +154,37 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
       // No known stores after the free
       last = 0;
     } else {
-      // Update our most-recent-store map.
-      last = cast<StoreInst>(BBI);
+      StoreInst* S = cast<StoreInst>(BBI);
+      
+      // If we're storing the same value back to a pointer that we just
+      // loaded from, then the store can be removed;
+      if (LoadInst* L = dyn_cast<LoadInst>(S->getOperand(0))) {
+        Instruction* dep = MD.getDependency(S);
+        DominatorTree& DT = getAnalysis<DominatorTree>();
+        
+        if (!S->isVolatile() && S->getParent() == L->getParent() &&
+            S->getPointerOperand() == L->getPointerOperand() &&
+            ( dep == MemoryDependenceAnalysis::None ||
+              dep == MemoryDependenceAnalysis::NonLocal ||
+              DT.dominates(dep, L))) {
+          if (Instruction* D = dyn_cast<Instruction>(S->getOperand(0)))
+            possiblyDead.insert(D);
+          if (Instruction* D = dyn_cast<Instruction>(S->getOperand(1)))
+            possiblyDead.insert(D);
+          
+          // Avoid iterator invalidation.
+          BBI--;
+          
+          MD.removeInstruction(S);
+          S->eraseFromParent();
+          NumFastStores++;
+          MadeChange = true;
+        } else
+          // Update our most-recent-store map.
+          last = S;
+      } else
+        // Update our most-recent-store map.
+        last = S;
     }
   }
   
@@ -270,10 +281,9 @@ bool DSE::handleEndBlock(BasicBlock& BB,
     // 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)) {
@@ -287,6 +297,7 @@ bool DSE::handleEndBlock(BasicBlock& BB,
             possiblyDead.insert(D);
         
           BBI++;
+          MD.removeInstruction(S);
           S->eraseFromParent();
           NumFastStores++;
           MadeChange = true;
@@ -297,9 +308,8 @@ bool DSE::handleEndBlock(BasicBlock& BB,
     
     // 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);
         
@@ -327,8 +337,8 @@ bool DSE::handleEndBlock(BasicBlock& BB,
     
     // If we encounter a use of the pointer, it is no longer considered dead
     if (LoadInst* L = dyn_cast<LoadInst>(BBI)) {
-      // However, if this load is unused and not volatile, we can go ahead and remove it,
-      // and not have to worry about it making our pointer undead!
+      // However, if this load is unused and not volatile, we can go ahead and
+      // remove it, and not have to worry about it making our pointer undead!
       if (L->use_empty() && !L->isVolatile()) {
         MD.removeInstruction(L);
         
@@ -447,9 +457,9 @@ bool DSE::handleEndBlock(BasicBlock& BB,
     
     if (!killPointer)
       continue;
-    
-    TranslatePointerBitCasts(killPointer);
-    
+
+    killPointer = killPointer->getUnderlyingObject();
+
     // Deal with undead pointers
     MadeChange |= RemoveUndeadPointers(killPointer, killPointerSize, BBI,
                                        deadPointers, possiblyDead);