Rename MallocHelper as MallocFreeHelper, since it now also identifies calls to free()
[oota-llvm.git] / lib / Transforms / Scalar / DeadStoreElimination.cpp
index 1b6d85086280321dc65bf11c6762ad83de162f27..39689a05b5a33ed547bf0ce84106c4559805b296 100644 (file)
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/MallocFreeHelper.h"
 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Support/Compiler.h"
 using namespace llvm;
 
 STATISTIC(NumFastStores, "Number of stores deleted");
 STATISTIC(NumFastOther , "Number of other instrs removed");
 
 namespace {
-  struct VISIBILITY_HIDDEN DSE : public FunctionPass {
+  struct DSE : public FunctionPass {
+    TargetData *TD;
+
     static char ID; // Pass identification, replacement for typeid
     DSE() : FunctionPass(&ID) {}
 
@@ -48,9 +50,9 @@ namespace {
     }
     
     bool runOnBasicBlock(BasicBlock &BB);
-    bool handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep);
+    bool handleFreeWithNonTrivialDependency(Instruction *F, MemDepResult Dep);
     bool handleEndBlock(BasicBlock &BB);
-    bool RemoveUndeadPointers(Value* pointer, uint64_t killPointerSize,
+    bool RemoveUndeadPointers(Value* Ptr, uint64_t killPointerSize,
                               BasicBlock::iterator& BBI,
                               SmallPtrSet<Value*, 64>& deadPointers);
     void DeleteDeadInstruction(Instruction *I,
@@ -62,7 +64,6 @@ namespace {
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesCFG();
       AU.addRequired<DominatorTree>();
-      AU.addRequired<TargetData>();
       AU.addRequired<AliasAnalysis>();
       AU.addRequired<MemoryDependenceAnalysis>();
       AU.addPreserved<DominatorTree>();
@@ -79,94 +80,79 @@ FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); }
 
 bool DSE::runOnBasicBlock(BasicBlock &BB) {
   MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
-  TargetData &TD = getAnalysis<TargetData>();  
+  TD = getAnalysisIfAvailable<TargetData>();
 
-  // Record the last-seen store to this pointer
-  DenseMap<Value*, StoreInst*> lastStore;
-  
   bool MadeChange = false;
   
-  // Do a top-down walk on the BB
+  // Do a top-down walk on the BB.
   for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ) {
     Instruction *Inst = BBI++;
     
-    // If we find a store or a free...
-    if (!isa<StoreInst>(Inst) && !isa<FreeInst>(Inst))
+    // If we find a store or a free, get its memory dependence.
+    if (!isa<StoreInst>(Inst) && !isFreeCall(Inst))
       continue;
-
-    Value* pointer = 0;
-    if (StoreInst* S = dyn_cast<StoreInst>(Inst)) {
-      if (S->isVolatile())
+    
+    // Don't molest volatile stores or do queries that will return "clobber".
+    if (StoreInst *SI = dyn_cast<StoreInst>(Inst))
+      if (SI->isVolatile())
         continue;
-      pointer = S->getPointerOperand();
-    } else {
-      pointer = cast<FreeInst>(Inst)->getPointerOperand();
-    }
 
-    pointer = pointer->stripPointerCasts();
-    StoreInst *&last = lastStore[pointer];
-    // ... to a pointer that has been stored to before...
-    if (last) {
-      MemDepResult dep = MD.getDependency(Inst);
-      bool deletedStore = false;
+    MemDepResult InstDep = MD.getDependency(Inst);
     
-      // ... and no other memory dependencies are between them....
-      while (StoreInst *DepStore = dyn_cast_or_null<StoreInst>(dep.getInst())) {
-        if (DepStore != last ||
-            TD.getTypeStoreSize(last->getOperand(0)->getType()) >
-            TD.getTypeStoreSize(Inst->getOperand(0)->getType())) {
-          dep = MD.getDependencyFrom(Inst, DepStore, DepStore->getParent());
-          continue;
-        }
-        
+    // Ignore non-local stores.
+    // FIXME: cross-block DSE would be fun. :)
+    if (InstDep.isNonLocal()) continue;
+  
+    // Handle frees whose dependencies are non-trivial.
+    if (isFreeCall(Inst)) {
+      MadeChange |= handleFreeWithNonTrivialDependency(Inst, InstDep);
+      continue;
+    }
+    
+    StoreInst *SI = cast<StoreInst>(Inst);
+    
+    // If not a definite must-alias dependency, ignore it.
+    if (!InstDep.isDef())
+      continue;
+    
+    // If this is a store-store dependence, then the previous store is dead so
+    // long as this store is at least as big as it.
+    if (StoreInst *DepStore = dyn_cast<StoreInst>(InstDep.getInst()))
+      if (TD &&
+          TD->getTypeStoreSize(DepStore->getOperand(0)->getType()) <=
+          TD->getTypeStoreSize(SI->getOperand(0)->getType())) {
         // Delete the store and now-dead instructions that feed it.
-        DeleteDeadInstruction(last);
+        DeleteDeadInstruction(DepStore);
         NumFastStores++;
-        deletedStore = true;
         MadeChange = true;
-        break;
-      }
-      
-      // If we deleted a store, reinvestigate this instruction.
-      if (deletedStore) {
-        if (!isa<TerminatorInst>(BB.begin()))
+
+        // DeleteDeadInstruction can delete the current instruction in loop
+        // cases, reset BBI.
+        BBI = Inst;
+        if (BBI != BB.begin())
           --BBI;
         continue;
       }
-    }
     
-    // Handle frees whose dependencies are non-trivial.
-    if (FreeInst* F = dyn_cast<FreeInst>(Inst)) {
-      MadeChange |= handleFreeWithNonTrivialDependency(F, MD.getDependency(F));
-      
-      // No known stores after the free.
-      last = 0;
-    } else {
-      StoreInst* S = cast<StoreInst>(Inst);
-      
-      // 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))) {
-        // FIXME: Don't do dep query if Parents don't match and other stuff!
-        MemDepResult dep = MD.getDependency(S);
-        DominatorTree& DT = getAnalysis<DominatorTree>();
+    // If we're storing the same value back to a pointer that we just
+    // loaded from, then the store can be removed.
+    if (LoadInst *DepLoad = dyn_cast<LoadInst>(InstDep.getInst())) {
+      if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
+          SI->getOperand(0) == DepLoad) {
+        // DeleteDeadInstruction can delete the current instruction.  Save BBI
+        // in case we need it.
+        WeakVH NextInst(BBI);
         
-        if (!S->isVolatile() && S->getParent() == L->getParent() &&
-            S->getPointerOperand() == L->getPointerOperand() &&
-            (!dep.isNormal() || DT.dominates(dep.getInst(), L))) {
-          
-          DeleteDeadInstruction(S);
-          if (!isa<TerminatorInst>(BB.begin()))
-            --BBI;
-          NumFastStores++;
-          MadeChange = true;
-        } else
-          // Update our most-recent-store map.
-          last = S;
-      } else
-        // Update our most-recent-store map.
-        last = S;
+        DeleteDeadInstruction(SI);
+        
+        if (NextInst == 0)  // Next instruction deleted.
+          BBI = BB.begin();
+        else if (BBI != BB.begin())  // Revisit this instruction if possible.
+          --BBI;
+        NumFastStores++;
+        MadeChange = true;
+        continue;
+      }
     }
   }
   
@@ -180,29 +166,22 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
 
 /// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose
 /// dependency is a store to a field of that structure.
-bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, MemDepResult dep) {
-  TargetData &TD = getAnalysis<TargetData>();
+bool DSE::handleFreeWithNonTrivialDependency(Instruction *F, MemDepResult Dep) {
   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
   
-  StoreInst* dependency = dyn_cast_or_null<StoreInst>(dep.getInst());
-  if (!dependency)
-    return false;
-  else if (dependency->isVolatile())
+  StoreInst *Dependency = dyn_cast_or_null<StoreInst>(Dep.getInst());
+  if (!Dependency || Dependency->isVolatile())
     return false;
   
-  Value* depPointer = dependency->getPointerOperand();
-  const Type* depType = dependency->getOperand(0)->getType();
-  unsigned depPointerSize = TD.getTypeStoreSize(depType);
+  Value *DepPointer = Dependency->getPointerOperand()->getUnderlyingObject();
 
-  // Check for aliasing
-  AliasAnalysis::AliasResult A = AA.alias(F->getPointerOperand(), ~0U,
-                                          depPointer, depPointerSize);
-
-  if (A != AliasAnalysis::MustAlias)
+  // Check for aliasing.
+  if (AA.alias(F->getOperand(1), 1, DepPointer, 1) !=
+         AliasAnalysis::MustAlias)
     return false;
   
   // DCE instructions only used to calculate that store
-  DeleteDeadInstruction(dependency);
+  DeleteDeadInstruction(Dependency);
   NumFastStores++;
   return true;
 }
@@ -214,7 +193,6 @@ bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, MemDepResult dep) {
 /// store i32 1, i32* %A
 /// ret void
 bool DSE::handleEndBlock(BasicBlock &BB) {
-  TargetData &TD = getAnalysis<TargetData>();
   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
   
   bool MadeChange = false;
@@ -335,14 +313,16 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
 
         // Get size information for the alloca
         unsigned pointerSize = ~0U;
-        if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) {
-          if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize()))
-            pointerSize = C->getZExtValue() *
-                          TD.getABITypeSize(A->getAllocatedType());
-        } else {
-          const PointerType* PT = cast<PointerType>(
-                                                 cast<Argument>(*I)->getType());
-          pointerSize = TD.getABITypeSize(PT->getElementType());
+        if (TD) {
+          if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) {
+            if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize()))
+              pointerSize = C->getZExtValue() *
+                            TD->getTypeAllocSize(A->getAllocatedType());
+          } else {
+            const PointerType* PT = cast<PointerType>(
+                                                   cast<Argument>(*I)->getType());
+            pointerSize = TD->getTypeAllocSize(PT->getElementType());
+          }
         }
 
         // See if the call site touches it
@@ -390,7 +370,6 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
 bool DSE::RemoveUndeadPointers(Value* killPointer, uint64_t killPointerSize,
                                BasicBlock::iterator &BBI,
                                SmallPtrSet<Value*, 64>& deadPointers) {
-  TargetData &TD = getAnalysis<TargetData>();
   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
                                   
   // If the kill pointer can be easily reduced to an alloca,
@@ -412,13 +391,15 @@ bool DSE::RemoveUndeadPointers(Value* killPointer, uint64_t killPointerSize,
       E = deadPointers.end(); I != E; ++I) {
     // Get size information for the alloca.
     unsigned pointerSize = ~0U;
-    if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) {
-      if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize()))
-        pointerSize = C->getZExtValue() *
-                      TD.getABITypeSize(A->getAllocatedType());
-    } else {
-      const PointerType* PT = cast<PointerType>(cast<Argument>(*I)->getType());
-      pointerSize = TD.getABITypeSize(PT->getElementType());
+    if (TD) {
+      if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) {
+        if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize()))
+          pointerSize = C->getZExtValue() *
+                        TD->getTypeAllocSize(A->getAllocatedType());
+      } else {
+        const PointerType* PT = cast<PointerType>(cast<Argument>(*I)->getType());
+        pointerSize = TD->getTypeAllocSize(PT->getElementType());
+      }
     }
 
     // See if this pointer could alias it