Check for volatile loads only once.
[oota-llvm.git] / lib / Transforms / Scalar / DeadStoreElimination.cpp
index c7f3254d4c7728a93799735d8b47b7080b798eb3..07d5c655205cd76afac80c0c0dbf9767d50b794d 100644 (file)
@@ -1,10 +1,10 @@
 //===- DeadStoreElimination.cpp - Dead Store Elimination ------------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file implements a trivial dead store elimination that only considers
@@ -16,6 +16,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
 #include "llvm/Analysis/AliasAnalysis.h"
@@ -38,9 +39,9 @@ namespace {
         Changed |= runOnBasicBlock(*I);
       return Changed;
     }
-    
+
     bool runOnBasicBlock(BasicBlock &BB);
-    
+
     void DeleteDeadInstructionChains(Instruction *I,
                                      SetVector<Instruction*> &DeadInsts);
 
@@ -63,13 +64,18 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
   AliasSetTracker KillLocs(AA);
 
-  // If this block ends in a return, unwind, and eventually tailcall/barrier,
-  // then all allocas are dead at its end.
+  // If this block ends in a return, unwind, unreachable, and eventually
+  // tailcall, then all allocas are dead at its end.
   if (BB.getTerminator()->getNumSuccessors() == 0) {
     BasicBlock *Entry = BB.getParent()->begin();
     for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I)
-      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
-        KillLocs.add(AI, ~0);
+      if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
+        unsigned Size = ~0U;
+        if (!AI->isArrayAllocation() &&
+            AI->getType()->getElementType()->isSized())
+          Size = (unsigned)TD.getTypeSize(AI->getType()->getElementType());
+        KillLocs.add(AI, Size);
+      }
   }
 
   // PotentiallyDeadInsts - Deleting dead stores from the program can make other
@@ -81,7 +87,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
   bool MadeChange = false;
   for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ) {
     Instruction *I = --BBI;   // Keep moving iterator backwards
-    
+
     // If this is a free instruction, it makes the free'd location dead!
     if (FreeInst *FI = dyn_cast<FreeInst>(I)) {
       // Free instructions make any stores to the free'd location dead.
@@ -100,12 +106,13 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
     // the stored location is already in the tracker, then this is a dead
     // store.  We can just delete it here, but while we're at it, we also
     // delete any trivially dead expression chains.
-    unsigned ValSize = TD.getTypeSize(I->getOperand(0)->getType());
+    unsigned ValSize = (unsigned)TD.getTypeSize(I->getOperand(0)->getType());
     Value *Ptr = I->getOperand(1);
 
     if (AliasSet *AS = KillLocs.getAliasSetForPointerIfExists(Ptr, ValSize))
       for (AliasSet::iterator ASI = AS->begin(), E = AS->end(); ASI != E; ++ASI)
-        if (AA.alias(ASI.getPointer(), ASI.getSize(), Ptr, ValSize)
+        if (ASI.getSize() >= ValSize &&  // Overwriting all of this store.
+            AA.alias(ASI.getPointer(), ASI.getSize(), Ptr, ValSize)
                == AliasAnalysis::MustAlias) {
           // If we found a must alias in the killed set, then this store really
           // is dead.  Remember that the various operands of the store now have
@@ -149,13 +156,12 @@ void DSE::DeleteDeadInstructionChains(Instruction *I,
   // See if this made any operands dead.  We do it this way in case the
   // instruction uses the same operand twice.  We don't want to delete a
   // value then reference it.
-  while (unsigned NumOps = I->getNumOperands()) {
-    Instruction *Op = dyn_cast<Instruction>(I->getOperand(NumOps-1));
-    I->op_erase(I->op_end()-1);         // Drop from the operand list.
-    
-    if (Op) DeadInsts.insert(Op);       // Attempt to nuke it later.
+  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+    if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(i)))
+      DeadInsts.insert(Op);      // Attempt to nuke it later.
+    I->setOperand(i, 0);         // Drop from the operand list.
   }
-  
-  I->getParent()->getInstList().erase(I);
+
+  I->eraseFromParent();
   ++NumOther;
 }