diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-28 22:51:08 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-28 22:51:08 +0000 |
commit | d3d12ecadd1eb859c4b30b6582e31901a45d6626 (patch) | |
tree | 7cb165beafc0381624551d998b2fee25b6c25c09 | |
parent | 5425f22fa3f8cbbcbc1a76fc7df2fa251cdc132d (diff) |
Fix PR3141 by ensuring that MemoryDependenceAnalysis::removeInstruction
properly updates the reverse dependency map when it installs updated
dependencies for instructions that depend on the removed instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60222 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 40 | ||||
-rw-r--r-- | test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll | 16 |
2 files changed, 44 insertions, 12 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 27c43c735e..9c269053c1 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -545,6 +545,7 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { if (IsConfirmed) { // If we have a confirmed non-local flag, use it. if (LocalDepInst == NonLocal || LocalDepInst == None) { + // The only time this dependency is confirmed is if it is non-local. NewDependency = LocalDepInst; NewDependencyConfirmed = true; } else { @@ -565,18 +566,34 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { if (NewDependency == 0) NewDependency = next(BasicBlock::iterator(RemInst)); - SmallPtrSet<Instruction*, 4>& set = reverseDep[RemInst]; - for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end(); - I != E; ++I) { - // Insert the new dependencies - // Mark it as unconfirmed as long as it is not the non-local flag - depGraphLocal[*I] = std::make_pair(NewDependency, NewDependencyConfirmed); + // Loop over all of the things that depend on the instruction we're removing. + // + reverseDepMapType::iterator ReverseDepIt = reverseDep.find(RemInst); + if (ReverseDepIt != reverseDep.end()) { + SmallPtrSet<Instruction*, 4> &ReverseDeps = ReverseDepIt->second; + for (SmallPtrSet<Instruction*, 4>::iterator I = ReverseDeps.begin(), + E = ReverseDeps.end(); I != E; ++I) { + Instruction *InstDependingOnRemInst = *I; + + // If we thought the instruction depended on itself (possible for + // unconfirmed dependencies) ignore the update. + if (InstDependingOnRemInst == RemInst) continue; + + // Insert the new dependencies. + depGraphLocal[InstDependingOnRemInst] = + std::make_pair(NewDependency, NewDependencyConfirmed); + + // If our NewDependency is an instruction, make sure to remember that new + // things depend on it. + if (NewDependency != NonLocal && NewDependency != None) + reverseDep[NewDependency].insert(InstDependingOnRemInst); + } + reverseDep.erase(RemInst); } - reverseDep.erase(RemInst); - - if (reverseDepNonLocal.count(RemInst)) { - SmallPtrSet<Instruction*, 4>& set = reverseDepNonLocal[RemInst]; + ReverseDepIt = reverseDepNonLocal.find(RemInst); + if (ReverseDepIt != reverseDepNonLocal.end()) { + SmallPtrSet<Instruction*, 4>& set = ReverseDepIt->second; for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end(); I != E; ++I) for (DenseMap<BasicBlock*, Value*>::iterator DI = @@ -584,10 +601,9 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { DI != DE; ++DI) if (DI->second == RemInst) DI->second = Dirty; - + reverseDepNonLocal.erase(RemInst); } - reverseDepNonLocal.erase(RemInst); depGraphNonLocal.erase(RemInst); getAnalysis<AliasAnalysis>().deleteValue(RemInst); diff --git a/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll b/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll new file mode 100644 index 0000000000..0f3350d80c --- /dev/null +++ b/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -dse | llvm-dis +; PR3141 + %struct.ada__tags__dispatch_table = type { [1 x i32] } + %struct.f393a00_1__object = type { %struct.ada__tags__dispatch_table*, i8 } + %struct.f393a00_2__windmill = type { %struct.f393a00_1__object, i16 } + +define void @f393a00_2__swap(%struct.f393a00_2__windmill* %a, %struct.f393a00_2__windmill* %b) { +entry: + %t = alloca %struct.f393a00_2__windmill ; <%struct.f393a00_2__windmill*> [#uses=1] + %0 = getelementptr %struct.f393a00_2__windmill* %t, i32 0, i32 0, i32 0 ; <%struct.ada__tags__dispatch_table**> [#uses=1] + %1 = load %struct.ada__tags__dispatch_table** null, align 4 ; <%struct.ada__tags__dispatch_table*> [#uses=1] + %2 = load %struct.ada__tags__dispatch_table** %0, align 8 ; <%struct.ada__tags__dispatch_table*> [#uses=1] + store %struct.ada__tags__dispatch_table* %2, %struct.ada__tags__dispatch_table** null, align 4 + store %struct.ada__tags__dispatch_table* %1, %struct.ada__tags__dispatch_table** null, align 4 + ret void +} |