Index: include/llvm/Analysis/ScalarEvolution.h =================================================================== --- include/llvm/Analysis/ScalarEvolution.h +++ include/llvm/Analysis/ScalarEvolution.h @@ -1272,9 +1272,6 @@ /// function as they are computed. DenseMap PredicatedBackedgeTakenCounts; - // Cache the calculated exit limits for the loops. - DenseMap ExitLimits; - /// This map contains entries for all of the PHI instructions that we /// attempt to compute constant evolutions for. This allows us to avoid /// potentially expensive recomputation of these properties. An instruction @@ -1426,9 +1423,6 @@ ExitLimit computeExitLimit(const Loop *L, BasicBlock *ExitingBlock, bool AllowPredicates = false); - ExitLimit computeExitLimitImpl(const Loop *L, BasicBlock *ExitingBlock, - bool AllowPredicates = false); - /// Compute the number of times the backedge of the specified loop will /// execute if its exit condition were a conditional branch of ExitCond, /// TBB, and FBB. @@ -1668,9 +1662,8 @@ /// to be a constant. Optional computeConstantDifference(const SCEV *LHS, const SCEV *RHS); - /// Drop memoized information computed for S. Only erase Exit Limits info if - /// we expect that the operation we have made is going to change it. - void forgetMemoizedResults(const SCEV *S, bool EraseExitLimit = true); + /// Drop memoized information computed for S. + void forgetMemoizedResults(const SCEV *S); /// Return an existing SCEV for V if there is one, otherwise return nullptr. const SCEV *getExistingSCEV(Value *V); Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -6353,13 +6353,36 @@ // own when it gets to that point. if (!isa(I) || !isa(Old)) { eraseValueFromMap(It->first); - forgetMemoizedResults(Old, false); + forgetMemoizedResults(Old); } if (PHINode *PN = dyn_cast(I)) ConstantEvolutionLoopExitValue.erase(PN); } - PushDefUseChildren(I, Worklist); + // Since we don't need to invalidate anything for correctness and we're + // only invalidating to make SCEV's results more precise, we get to stop + // early to avoid invalidating too much. This is especially important in + // cases like: + // + // %v = f(pn0, pn1) // pn0 and pn1 used through some other phi node + // loop0: + // %pn0 = phi + // ... + // loop1: + // %pn1 = phi + // ... + // + // where both loop0 and loop1's backedge taken count uses the SCEV + // expression for %v. If we don't have the early stop below then in cases + // like the above, getBackedgeTakenInfo(loop1) will clear out the trip + // count for loop0 and getBackedgeTakenInfo(loop0) will clear out the trip + // count for loop1, effectively nullifying SCEV's trip count cache. + for (auto *U : I->users()) + if (auto *I = dyn_cast(U)) { + auto *LoopForUser = LI.getLoopFor(I->getParent()); + if (LoopForUser && L->contains(LoopForUser)) + Worklist.push_back(I); + } } } @@ -6430,12 +6453,6 @@ PushDefUseChildren(I, Worklist); } - for (auto I = ExitLimits.begin(); I != ExitLimits.end(); ++I) { - auto &Query = I->first; - if (Query.L == CurrL) - ExitLimits.erase(I); - } - LoopPropertiesCache.erase(CurrL); // Forget all contained loops too, to avoid dangling entries in the // ValuesAtScopes map. @@ -6697,18 +6714,6 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock, - bool AllowPredicates) { - ExitLimitQuery Query(L, ExitingBlock, AllowPredicates); - auto MaybeEL = ExitLimits.find(Query); - if (MaybeEL != ExitLimits.end()) - return MaybeEL->second; - ExitLimit EL = computeExitLimitImpl(L, ExitingBlock, AllowPredicates); - ExitLimits.insert({Query, EL}); - return EL; -} - -ScalarEvolution::ExitLimit -ScalarEvolution::computeExitLimitImpl(const Loop *L, BasicBlock *ExitingBlock, bool AllowPredicates) { // Okay, we've chosen an exiting block. See what condition causes us to exit // at this block and remember the exit block and whether all other targets @@ -10602,7 +10607,6 @@ BackedgeTakenCounts(std::move(Arg.BackedgeTakenCounts)), PredicatedBackedgeTakenCounts( std::move(Arg.PredicatedBackedgeTakenCounts)), - ExitLimits(std::move(Arg.ExitLimits)), ConstantEvolutionLoopExitValue( std::move(Arg.ConstantEvolutionLoopExitValue)), ValuesAtScopes(std::move(Arg.ValuesAtScopes)), @@ -11015,7 +11019,7 @@ } void -ScalarEvolution::forgetMemoizedResults(const SCEV *S, bool EraseExitLimit) { +ScalarEvolution::forgetMemoizedResults(const SCEV *S) { ValuesAtScopes.erase(S); LoopDispositions.erase(S); BlockDispositions.erase(S); @@ -11048,13 +11052,6 @@ RemoveSCEVFromBackedgeMap(BackedgeTakenCounts); RemoveSCEVFromBackedgeMap(PredicatedBackedgeTakenCounts); - - // TODO: There is a suspicion that we only need to do it when there is a - // SCEVUnknown somewhere inside S. Need to check this. - if (EraseExitLimit) - for (auto I = ExitLimits.begin(), E = ExitLimits.end(); I != E; ++I) - if (I->second.hasOperand(S)) - ExitLimits.erase(I); } void ScalarEvolution::addToLoopUseLists(const SCEV *S) {