summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp34
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)