Fix an iterator invalidation bug.

llvm-svn: 130166
This commit is contained in:
Dan Gohman 2011-04-25 22:48:29 +00:00
parent 238a21f2d5
commit 6acd95b3c1
1 changed files with 16 additions and 9 deletions

View File

@ -3788,19 +3788,20 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
if (!Pair.second)
return Pair.first->second;
BackedgeTakenInfo BECount = ComputeBackedgeTakenCount(L);
if (BECount.Exact != getCouldNotCompute()) {
assert(isLoopInvariant(BECount.Exact, L) &&
isLoopInvariant(BECount.Max, L) &&
BackedgeTakenInfo Result = getCouldNotCompute();
BackedgeTakenInfo Computed = ComputeBackedgeTakenCount(L);
if (Computed.Exact != getCouldNotCompute()) {
assert(isLoopInvariant(Computed.Exact, L) &&
isLoopInvariant(Computed.Max, L) &&
"Computed backedge-taken count isn't loop invariant for loop!");
++NumTripCountsComputed;
// Update the value in the map.
Pair.first->second = BECount;
Result = Computed;
} else {
if (BECount.Max != getCouldNotCompute())
if (Computed.Max != getCouldNotCompute())
// Update the value in the map.
Pair.first->second = BECount;
Result = Computed;
if (isa<PHINode>(L->getHeader()->begin()))
// Only count loops that have phi nodes as not being computable.
++NumTripCountsNotComputed;
@ -3811,7 +3812,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
// conservative estimates made without the benefit of trip count
// information. This is similar to the code in forgetLoop, except that
// it handles SCEVUnknown PHI nodes specially.
if (BECount.hasAnyInfo()) {
if (Computed.hasAnyInfo()) {
SmallVector<Instruction *, 16> Worklist;
PushLoopPHIs(L, Worklist);
@ -3842,7 +3843,13 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
PushDefUseChildren(I, Worklist);
}
}
return Pair.first->second;
// Re-lookup the insert position, since the call to
// ComputeBackedgeTakenCount above could result in a
// recusive call to getBackedgeTakenInfo (on a different
// loop), which would invalidate the iterator computed
// earlier.
return BackedgeTakenCounts.find(L)->second = Result;
}
/// forgetLoop - This method should be called by the client when it has