summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/DeadStoreElimination.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-11-12 02:19:17 +0000
committerDan Gohman <gohman@apple.com>2010-11-12 02:19:17 +0000
commit720a2ed6d99d5665cc1601426353c84cc76fffbb (patch)
tree42cd254d37d9e3d5fc6e1f5cf5d55416a6155acd /lib/Transforms/Scalar/DeadStoreElimination.cpp
parent02df7e90cf09e2a1e75fe7a441f0c34d1e76b85c (diff)
downloadllvm-720a2ed6d99d5665cc1601426353c84cc76fffbb.tar.gz
llvm-720a2ed6d99d5665cc1601426353c84cc76fffbb.tar.bz2
llvm-720a2ed6d99d5665cc1601426353c84cc76fffbb.tar.xz
Enhance DSE to handle the case where a free call makes more than
one store dead. This is especially noticeable in SingleSource/Benchmarks/Shootout/objinst. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118875 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/DeadStoreElimination.cpp')
-rw-r--r--lib/Transforms/Scalar/DeadStoreElimination.cpp36
1 files changed, 24 insertions, 12 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp
index d81d302eba..1ea0b15e4c 100644
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -59,6 +59,7 @@ namespace {
bool runOnBasicBlock(BasicBlock &BB);
bool handleFreeWithNonTrivialDependency(const CallInst *F,
+ Instruction *Inst,
MemDepResult Dep);
bool handleEndBlock(BasicBlock &BB);
bool RemoveUndeadPointers(Value *Ptr, uint64_t killPointerSize,
@@ -212,7 +213,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
// Handle frees whose dependencies are non-trivial.
if (const CallInst *F = isFreeCall(Inst)) {
- MadeChange |= handleFreeWithNonTrivialDependency(F, InstDep);
+ MadeChange |= handleFreeWithNonTrivialDependency(F, Inst, InstDep);
continue;
}
@@ -298,23 +299,34 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
/// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose
/// dependency is a store to a field of that structure.
bool DSE::handleFreeWithNonTrivialDependency(const CallInst *F,
+ Instruction *Inst,
MemDepResult Dep) {
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+ MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
- Instruction *Dependency = Dep.getInst();
- if (!Dependency || !doesClobberMemory(Dependency) || !isElidable(Dependency))
- return false;
+ do {
+ Instruction *Dependency = Dep.getInst();
+ if (!Dependency || !doesClobberMemory(Dependency) || !isElidable(Dependency))
+ return false;
- Value *DepPointer = getPointerOperand(Dependency)->getUnderlyingObject();
+ Value *DepPointer = getPointerOperand(Dependency)->getUnderlyingObject();
- // Check for aliasing.
- if (AA.alias(F->getArgOperand(0), 1, DepPointer, 1) !=
- AliasAnalysis::MustAlias)
- return false;
+ // Check for aliasing.
+ if (AA.alias(F->getArgOperand(0), 1, DepPointer, 1) !=
+ AliasAnalysis::MustAlias)
+ return false;
- // DCE instructions only used to calculate that store
- DeleteDeadInstruction(Dependency);
- ++NumFastStores;
+ // DCE instructions only used to calculate that store
+ DeleteDeadInstruction(Dependency);
+ ++NumFastStores;
+
+ // Inst's old Dependency is now deleted. Compute the next dependency,
+ // which may also be dead, as in
+ // s[0] = 0;
+ // s[1] = 0; // This has just been deleted.
+ // free(s);
+ Dep = MD.getDependency(Inst);
+ } while (!Dep.isNonLocal());
return true;
}