diff options
author | Dan Gohman <gohman@apple.com> | 2010-11-12 02:19:17 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-11-12 02:19:17 +0000 |
commit | 720a2ed6d99d5665cc1601426353c84cc76fffbb (patch) | |
tree | 42cd254d37d9e3d5fc6e1f5cf5d55416a6155acd /lib/Transforms/Scalar/DeadStoreElimination.cpp | |
parent | 02df7e90cf09e2a1e75fe7a441f0c34d1e76b85c (diff) | |
download | llvm-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.cpp | 36 |
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; } |