From 81f9121cda099f75e50485e79e8fdb423ae82792 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jul 2010 01:09:07 +0000 Subject: [PATCH] Make SCEVCallbackVH::allUsesReplacedWith update the old SCEVUnknown object, as it may still be referenced by SCEVs not cleaned up by the use list traversal. Also, in ScalarEvolution::forgetValue, only check for a SCEVUnknown object for the original value, not for any value in the use list, because other SCEVUnknown values aren't necessary obsolete at that point. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109570 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolution.cpp | 61 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 82f25f27860..7612f43f71c 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -3664,6 +3664,26 @@ void ScalarEvolution::forgetLoop(const Loop *L) { /// changed a value in a way that may effect its value, or which may /// disconnect it from a def-use chain linking it to a loop. void ScalarEvolution::forgetValue(Value *V) { + // If there's a SCEVUnknown tying this value into the SCEV + // space, remove it from the folding set map. The SCEVUnknown + // object and any other SCEV objects which reference it + // (transitively) remain allocated, effectively leaked until + // the underlying BumpPtrAllocator is freed. + // + // This permits SCEV pointers to be used as keys in maps + // such as the ValuesAtScopes map. + FoldingSetNodeID ID; + ID.AddInteger(scUnknown); + ID.AddPointer(V); + void *IP; + if (SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) { + UniqueSCEVs.RemoveNode(S); + + // This isn't necessary, but we might as well remove the + // value from the ValuesAtScopes map too. + ValuesAtScopes.erase(S); + } + Instruction *I = dyn_cast(V); if (!I) return; @@ -3685,26 +3705,6 @@ void ScalarEvolution::forgetValue(Value *V) { ConstantEvolutionLoopExitValue.erase(PN); } - // If there's a SCEVUnknown tying this value into the SCEV - // space, remove it from the folding set map. The SCEVUnknown - // object and any other SCEV objects which reference it - // (transitively) remain allocated, effectively leaked until - // the underlying BumpPtrAllocator is freed. - // - // This permits SCEV pointers to be used as keys in maps - // such as the ValuesAtScopes map. - FoldingSetNodeID ID; - ID.AddInteger(scUnknown); - ID.AddPointer(I); - void *IP; - if (SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) { - UniqueSCEVs.RemoveNode(S); - - // This isn't necessary, but we might as well remove the - // value from the ValuesAtScopes map too. - ValuesAtScopes.erase(S); - } - PushDefUseChildren(I, Worklist); } } @@ -5690,15 +5690,32 @@ void ScalarEvolution::SCEVCallbackVH::deleted() { // this now dangles! } -void ScalarEvolution::SCEVCallbackVH::allUsesReplacedWith(Value *) { +void ScalarEvolution::SCEVCallbackVH::allUsesReplacedWith(Value *V) { assert(SE && "SCEVCallbackVH called with a null ScalarEvolution!"); + Value *Old = getValPtr(); + + // If there's a SCEVUnknown tying this value into the SCEV + // space, replace the SCEVUnknown's value with the new value + // for the benefit of any SCEVs still referencing it, and + // and remove it from the folding set map so that new scevs + // don't reference it. + FoldingSetNodeID ID; + ID.AddInteger(scUnknown); + ID.AddPointer(Old); + void *IP; + if (SCEVUnknown *S = cast_or_null( + SE->UniqueSCEVs.FindNodeOrInsertPos(ID, IP))) { + S->V = V; + SE->UniqueSCEVs.RemoveNode(S); + SE->ValuesAtScopes.erase(S); + } + // Forget all the expressions associated with users of the old value, // so that future queries will recompute the expressions using the new // value. SmallVector Worklist; SmallPtrSet Visited; - Value *Old = getValPtr(); for (Value::use_iterator UI = Old->use_begin(), UE = Old->use_end(); UI != UE; ++UI) Worklist.push_back(*UI);