diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-21 07:34:32 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-21 07:34:32 +0000 |
commit | e48c31ce33d5d033aa9a79f092057d92173a676d (patch) | |
tree | c640c676b0ab95a69b4cfd2be27f8228b8d557bb /llvm | |
parent | 6e22221b377b660e63b617950ca6c4bb04f222e8 (diff) | |
download | bcm5719-llvm-e48c31ce33d5d033aa9a79f092057d92173a676d.tar.gz bcm5719-llvm-e48c31ce33d5d033aa9a79f092057d92173a676d.zip |
implement PR8576, deleting dead stores with intervening may-alias stores.
llvm-svn: 119927
Diffstat (limited to 'llvm')
4 files changed, 42 insertions, 6 deletions
diff --git a/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h b/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h index cc34992b456..c9c8116dc51 100644 --- a/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -335,11 +335,19 @@ namespace llvm { /// critical edges. void invalidateCachedPredecessors(); - private: + /// getPointerDependencyFrom - Return the instruction on which a memory + /// location depends. If isLoad is true, this routine ignores may-aliases + /// with read-only operations. If isLoad is false, this routine ignores + /// may-aliases with reads from read-only locations. + /// + /// Note that this is an uncached query, and thus may be inefficient. + /// MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB); + + private: MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, BasicBlock::iterator ScanIt, BasicBlock *BB); diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index a16e334e020..5fdf9a9c1a7 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -409,9 +409,9 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { if (MemLoc.Ptr) { // If we can do a pointer scan, make it happen. bool isLoad = !(MR & AliasAnalysis::Mod); - if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) { + if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end; - } + LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos, QueryParent); } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) { diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 1ea0b15e4c9..02df1031e60 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -217,9 +217,28 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { continue; } - // If not a definite must-alias dependency, ignore it. - if (!InstDep.isDef()) - continue; + if (!InstDep.isDef()) { + // If this is a may-aliased store that is clobbering the store value, we + // can keep searching past it for another must-aliased pointer that stores + // to the same location. For example, in: + // store -> P + // store -> Q + // store -> P + // we can remove the first store to P even though we don't know if P and Q + // alias. + if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { + AliasAnalysis::Location Loc = + getAnalysis<AliasAnalysis>().getLocation(SI); + while (InstDep.isClobber() && isa<StoreInst>(InstDep.getInst()) && + InstDep.getInst() != &BB.front()) + InstDep = MD.getPointerDependencyFrom(Loc, false, InstDep.getInst(), + &BB); + } + + // If not a definite must-alias dependency, ignore it. + if (!InstDep.isDef()) + continue; + } // If this is a store-store dependence, then the previous store is dead so // long as this store is at least as big as it. diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index f0c140d50a3..0a16603f55d 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -11,3 +11,12 @@ define void @test1(i32* %Q, i32* %P) { ; CHECK-NEXT: ret void } +; PR8576 - Should delete store of 10 even though p/q are may aliases. +define void @test2(i32 *%p, i32 *%q) { + store i32 10, i32* %p, align 4 + store i32 20, i32* %q, align 4 + store i32 30, i32* %p, align 4 + ret void +; CHECK: @test2 +; CHECK-NEXT: store i32 20 +} |