Add support for eliminate stores to stack-allocated memory locations at the end
authorOwen Anderson <resistor@mac.com>
Wed, 11 Jul 2007 21:06:56 +0000 (21:06 +0000)
committerOwen Anderson <resistor@mac.com>
Wed, 11 Jul 2007 21:06:56 +0000 (21:06 +0000)
of a function.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@39754 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/FastDSE.cpp

index 82862f7b489734b2253053d9dae83faef366be45..cd85b7caef7da8aa0d6d80ac159c9c81dc917506 100644 (file)
@@ -73,7 +73,7 @@ bool FDSE::runOnBasicBlock(BasicBlock &BB) {
   
   // Do a top-down walk on the BB
   for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ++BBI) {
-    // If we find a store...
+    // If we find a store or a free...
     if (isa<StoreInst>(BBI) || isa<FreeInst>(BBI)) {
       Value* pointer = 0;
       if (StoreInst* S = dyn_cast<StoreInst>(BBI))
@@ -111,6 +111,50 @@ bool FDSE::runOnBasicBlock(BasicBlock &BB) {
     }
   }
   
+  // 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) {
+    // Pointers alloca'd in this function are dead in the end block
+    SmallPtrSet<AllocaInst*, 4> deadPointers;
+    
+    // Find all of the alloca'd pointers in the entry block
+    BasicBlock *Entry = BB.getParent()->begin();
+    for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I)
+      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
+        deadPointers.insert(AI);
+    
+    // Scan the basic block backwards
+    for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){
+      --BBI;
+      
+      if (deadPointers.empty())
+        break;
+      
+      // If we find a store whose pointer is dead...
+      if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
+        if (deadPointers.count(S->getPointerOperand())){
+          // Remove it!
+          MD.removeInstruction(S);
+          
+          // DCE instructions only used to calculate that store
+          if (Instruction* D = dyn_cast<Instruction>(S->getOperand(0)))
+            possiblyDead.insert(D);
+          
+          BBI++;
+          S->eraseFromParent();
+          NumFastStores++;
+          MadeChange = true;
+        }
+      
+      // If we encounter a use of the pointer, it is no longer considered dead
+      } else if (LoadInst* L = dyn_cast<LoadInst>(BBI)) {
+        deadPointers.erase(L->getPointerOperand());
+      } else if (VAArgInst* V = dyn_cast<VAArgInst>(BBI)) {
+        deadPointers.erase(V->getOperand(0));
+    }
+    }
+  }
+  
   // Do a trivial DCE
   while (!possiblyDead.empty()) {
     Instruction *I = possiblyDead.back();