aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/FastDSE.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2007-07-11 21:06:56 +0000
committerOwen Anderson <resistor@mac.com>2007-07-11 21:06:56 +0000
commit6f46d65104ab08a75acb3d24056d19bdc2b054c3 (patch)
treed6d06fc9b47ecaf1d3b6cff62f2389a8f7b7bc58 /lib/Transforms/Scalar/FastDSE.cpp
parent2655adb3b26b845193be9802f6f938d836c4a939 (diff)
Add support for eliminate stores to stack-allocated memory locations at the end
of a function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@39754 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/FastDSE.cpp')
-rw-r--r--lib/Transforms/Scalar/FastDSE.cpp46
1 files changed, 45 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/FastDSE.cpp b/lib/Transforms/Scalar/FastDSE.cpp
index 82862f7b48..cd85b7caef 100644
--- a/lib/Transforms/Scalar/FastDSE.cpp
+++ b/lib/Transforms/Scalar/FastDSE.cpp
@@ -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();