Index: llvm/include/llvm/Analysis/ScalarEvolution.h =================================================================== --- llvm/include/llvm/Analysis/ScalarEvolution.h +++ llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1390,6 +1390,9 @@ /// True iff the backedge is taken either exactly Max or zero times. bool MaxOrZero = false; + /// SCEV expressions used in any of the ExitNotTakenInfo counts. + DenseSet Operands; + bool isComplete() const { return IsComplete; } const SCEV *getConstantMax() const { return ConstantMax; } @@ -1458,7 +1461,7 @@ /// Return true if any backedge taken count expressions refer to the given /// subexpression. - bool hasOperand(const SCEV *S, ScalarEvolution *SE) const; + bool hasOperand(const SCEV *S) const; }; /// Cache the backedge-taken count of the loops for this function as they Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -7392,18 +7392,8 @@ return MaxOrZero && !any_of(ExitNotTaken, PredicateNotAlwaysTrue); } -bool ScalarEvolution::BackedgeTakenInfo::hasOperand(const SCEV *S, - ScalarEvolution *SE) const { - if (getConstantMax() && getConstantMax() != SE->getCouldNotCompute() && - SE->hasOperand(getConstantMax(), S)) - return true; - - for (auto &ENT : ExitNotTaken) - if (ENT.ExactNotTaken != SE->getCouldNotCompute() && - SE->hasOperand(ENT.ExactNotTaken, S)) - return true; - - return false; +bool ScalarEvolution::BackedgeTakenInfo::hasOperand(const SCEV *S) const { + return Operands.contains(S); } ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E) @@ -7445,6 +7435,18 @@ "No point in having a non-constant max backedge taken count!"); } +class SCEVRecordOperands { + DenseSet &Operands; + +public: + SCEVRecordOperands(DenseSet &Operands) : Operands(Operands) {} + bool follow(const SCEV *S) { + Operands.insert(S); + return true; + } + bool isDone() { return false; } +}; + /// Allocate memory for BackedgeTakenInfo and copy the not-taken count of each /// computable exit into a persistent ExitNotTakenInfo array. ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo( @@ -7473,6 +7475,14 @@ assert((isa(ConstantMax) || isa(ConstantMax)) && "No point in having a non-constant max backedge taken count!"); + + SCEVRecordOperands RecordOperands(Operands); + SCEVTraversal ST(RecordOperands); + if (!isa(ConstantMax)) + ST.visitAll(ConstantMax); + for (auto &ENT : ExitNotTaken) + if (!isa(ENT.ExactNotTaken)) + ST.visitAll(ENT.ExactNotTaken); } /// Compute the number of times the backedge of the specified loop will execute. @@ -12630,7 +12640,7 @@ [S, this](DenseMap &Map) { for (auto I = Map.begin(), E = Map.end(); I != E;) { BackedgeTakenInfo &BEInfo = I->second; - if (BEInfo.hasOperand(S, this)) + if (BEInfo.hasOperand(S)) Map.erase(I++); else ++I;