diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 40 | ||||
| -rw-r--r-- | llvm/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll | 16 | 
2 files changed, 44 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 27c43c735e9..9c269053c12 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/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/llvm/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll b/llvm/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll new file mode 100644 index 00000000000..0f3350d80c7 --- /dev/null +++ b/llvm/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 +}  | 

