diff options
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 7dc7f9904c70..0c3f32295ae1 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -8829,11 +8829,10 @@ const SCEV *ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) { for (auto &LS : reverse(ValuesAtScopes[V])) if (LS.first == L) { LS.second = C; + if (!isa<SCEVConstant>(C)) + ValuesAtScopesUsers[C].push_back({L, V}); break; } - - if (!isa<SCEVConstant>(C)) - ValuesAtScopesUsers[C].push_back({L, V}); return C; } @@ -13058,11 +13057,13 @@ void ScalarEvolution::verify() const { Worklist.append(L->begin(), L->end()); } for (auto &KV : ValueExprMap) { +#ifndef NDEBUG // Check for SCEV expressions referencing invalid/deleted loops. if (auto *AR = dyn_cast<SCEVAddRecExpr>(KV.second)) { assert(ValidLoops.contains(AR->getLoop()) && "AddRec references invalid loop"); } +#endif // Check that the value is also part of the reverse map. auto It = ExprValueMap.find(KV.second); @@ -13122,7 +13123,7 @@ void ScalarEvolution::verify() const { is_contained(It->second, std::make_pair(L, Value))) continue; dbgs() << "Value: " << *Value << ", Loop: " << *L << ", ValueAtScope: " - << ValueAtScope << " missing in ValuesAtScopesUsers\n"; + << *ValueAtScope << " missing in ValuesAtScopesUsers\n"; std::abort(); } } @@ -13139,7 +13140,7 @@ void ScalarEvolution::verify() const { is_contained(It->second, std::make_pair(L, ValueAtScope))) continue; dbgs() << "Value: " << *Value << ", Loop: " << *L << ", ValueAtScope: " - << ValueAtScope << " missing in ValuesAtScopes\n"; + << *ValueAtScope << " missing in ValuesAtScopes\n"; std::abort(); } } @@ -13958,11 +13959,12 @@ const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) { ExprsToRewrite.push_back(LHS); } }; - // Starting at the loop predecessor, climb up the predecessor chain, as long - // as there are predecessors that can be found that have unique successors - // leading to the original header. + // First, collect conditions from dominating branches. Starting at the loop + // predecessor, climb up the predecessor chain, as long as there are + // predecessors that can be found that have unique successors leading to the + // original header. // TODO: share this logic with isLoopEntryGuardedByCond. - DenseMap<const SCEV *, const SCEV *> RewriteMap; + SmallVector<std::pair<Value *, bool>> Terms; for (std::pair<const BasicBlock *, const BasicBlock *> Pair( L->getLoopPredecessor(), L->getHeader()); Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) { @@ -13972,10 +13974,20 @@ const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) { if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional()) continue; - bool EnterIfTrue = LoopEntryPredicate->getSuccessor(0) == Pair.second; + Terms.emplace_back(LoopEntryPredicate->getCondition(), + LoopEntryPredicate->getSuccessor(0) == Pair.second); + } + + // Now apply the information from the collected conditions to RewriteMap. + // Conditions are processed in reverse order, so the earliest conditions is + // processed first. This ensures the SCEVs with the shortest dependency chains + // are constructed first. + DenseMap<const SCEV *, const SCEV *> RewriteMap; + for (auto &E : reverse(Terms)) { + bool EnterIfTrue = E.second; SmallVector<Value *, 8> Worklist; SmallPtrSet<Value *, 8> Visited; - Worklist.push_back(LoopEntryPredicate->getCondition()); + Worklist.push_back(E.first); while (!Worklist.empty()) { Value *Cond = Worklist.pop_back_val(); if (!Visited.insert(Cond).second) |
