diff options
author | Owen Anderson <resistor@mac.com> | 2008-07-28 16:14:26 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2008-07-28 16:14:26 +0000 |
commit | 8aa895b19a64796a4c1f7cd0cb0750ad34263ea0 (patch) | |
tree | 73966641c6815ec06eb4828f602e77ccc8d8ed3a /lib/Transforms | |
parent | d4310a5d41cc13f109890f5efbb19e084fecb27a (diff) | |
download | external_llvm-8aa895b19a64796a4c1f7cd0cb0750ad34263ea0.zip external_llvm-8aa895b19a64796a4c1f7cd0cb0750ad34263ea0.tar.gz external_llvm-8aa895b19a64796a4c1f7cd0cb0750ad34263ea0.tar.bz2 |
Add support for eliminating stores that store the same value that was just loaded.
This fixes PR2599.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54133 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/DeadStoreElimination.cpp | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index 4662e05..0011d95 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -26,6 +26,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" @@ -85,9 +86,11 @@ namespace { // Dependence Graph) virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired<DominatorTree>(); AU.addRequired<TargetData>(); AU.addRequired<AliasAnalysis>(); AU.addRequired<MemoryDependenceAnalysis>(); + AU.addPreserved<DominatorTree>(); AU.addPreserved<AliasAnalysis>(); AU.addPreserved<MemoryDependenceAnalysis>(); } @@ -172,8 +175,37 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { // No known stores after the free last = 0; } else { - // Update our most-recent-store map. - last = cast<StoreInst>(BBI); + StoreInst* S = cast<StoreInst>(BBI); + + // 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))) { + Instruction* dep = MD.getDependency(S); + DominatorTree& DT = getAnalysis<DominatorTree>(); + + if (S->getParent() == L->getParent() && + S->getPointerOperand() == L->getPointerOperand() && + ( dep == MemoryDependenceAnalysis::None || + dep == MemoryDependenceAnalysis::NonLocal || + DT.dominates(dep, L))) { + if (Instruction* D = dyn_cast<Instruction>(S->getOperand(0))) + possiblyDead.insert(D); + if (Instruction* D = dyn_cast<Instruction>(S->getOperand(1))) + possiblyDead.insert(D); + + // Avoid iterator invalidation. + BBI--; + + MD.removeInstruction(S); + S->eraseFromParent(); + NumFastStores++; + MadeChange = true; + } else + // Update our most-recent-store map. + last = S; + } else + // Update our most-recent-store map. + last = S; } } @@ -287,6 +319,7 @@ bool DSE::handleEndBlock(BasicBlock& BB, possiblyDead.insert(D); BBI++; + MD.removeInstruction(S); S->eraseFromParent(); NumFastStores++; MadeChange = true; |