diff options
| author | Owen Anderson <resistor@mac.com> | 2007-07-11 21:06:56 +0000 |
|---|---|---|
| committer | Owen Anderson <resistor@mac.com> | 2007-07-11 21:06:56 +0000 |
| commit | 1441470be846a1fae9f367cedcc05c9ac2d2385b (patch) | |
| tree | b575c08b07ee15d36cc29416f242276b3f237029 /llvm/lib | |
| parent | e72014483730f4940ef1710090d15085276738fc (diff) | |
| download | bcm5719-llvm-1441470be846a1fae9f367cedcc05c9ac2d2385b.tar.gz bcm5719-llvm-1441470be846a1fae9f367cedcc05c9ac2d2385b.zip | |
Add support for eliminate stores to stack-allocated memory locations at the end
of a function.
llvm-svn: 39754
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/FastDSE.cpp | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/FastDSE.cpp b/llvm/lib/Transforms/Scalar/FastDSE.cpp index 82862f7b489..cd85b7caef7 100644 --- a/llvm/lib/Transforms/Scalar/FastDSE.cpp +++ b/llvm/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(); |

