Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -6607,22 +6607,29 @@ return nullptr; } +/// Fills \p Ops with unique operands of \p S, if it has operands. If not, +/// \p Ops remains unmodified. +static void collectUniqueOps(const SCEV *S, + SmallPtrSetImpl &Ops) { + if (auto *S2 = dyn_cast(S)) + for (auto *Op : S2->operands()) + Ops.insert(Op); + else if (auto *S2 = dyn_cast(S)) + for (auto *Op : S2->operands()) + Ops.insert(Op); + else if (auto *S2 = dyn_cast(S)) + for (auto *Op : S2->operands()) + Ops.insert(Op); +} + const Instruction * ScalarEvolution::getDefiningScopeBound(ArrayRef Ops) { // Do a bounded search of the def relation of the requested SCEVs. - SmallSet Visited; + SmallPtrSet Visited; SmallVector Worklist; - auto pushOp = [&](const SCEV *S) { - if (!Visited.insert(S).second) - return; - // Threshold of 30 here is arbitrary. - if (Visited.size() > 30) - return; - Worklist.push_back(S); - }; - for (auto *S : Ops) - pushOp(S); + if (Visited.insert(S).second) + Worklist.push_back(S); const Instruction *Bound = nullptr; while (!Worklist.empty()) { @@ -6630,15 +6637,14 @@ if (auto *DefI = getNonTrivialDefiningScopeBound(S)) { if (!Bound || DT.dominates(Bound, DefI)) Bound = DefI; - } else if (auto *S2 = dyn_cast(S)) - for (auto *Op : S2->operands()) - pushOp(Op); - else if (auto *S2 = dyn_cast(S)) - for (auto *Op : S2->operands()) - pushOp(Op); - else if (auto *S2 = dyn_cast(S)) - for (auto *Op : S2->operands()) - pushOp(Op); + } else { + SmallPtrSet Ops; + collectUniqueOps(S, Ops); + for (auto *Op : Ops) + // Threshold of 30 here is arbitrary. + if (Visited.size() <= 30 && Visited.insert(Op).second) + Worklist.push_back(Op); + } } return Bound ? Bound : &*F.getEntryBlock().begin(); } @@ -12915,14 +12921,7 @@ // Verify intergity of SCEV users. for (const auto &S : UniqueSCEVs) { SmallPtrSet Ops; - if (const auto *NS = dyn_cast(&S)) - Ops.insert(NS->op_begin(), NS->op_end()); - else if (const auto *CS = dyn_cast(&S)) - Ops.insert(CS->getOperand()); - else if (const auto *DS = dyn_cast(&S)) { - Ops.insert(DS->getLHS()); - Ops.insert(DS->getRHS()); - } + collectUniqueOps(&S, Ops); for (const auto *Op : Ops) { // We do not store dependencies of constants. if (isa(Op))