[llvm] 6a2af60 - Revert "[NFCI] Lazily evaluate SCEVs of PHIs"
Max Kazantsev via llvm-commits
llvm-commits at lists.llvm.org
Thu May 27 21:05:52 PDT 2021
Author: Max Kazantsev
Date: 2021-05-28T11:05:30+07:00
New Revision: 6a2af607ad3523ddc3778b0efb7bb1d5d42a1edb
URL: https://github.com/llvm/llvm-project/commit/6a2af607ad3523ddc3778b0efb7bb1d5d42a1edb
DIFF: https://github.com/llvm/llvm-project/commit/6a2af607ad3523ddc3778b0efb7bb1d5d42a1edb.diff
LOG: Revert "[NFCI] Lazily evaluate SCEVs of PHIs"
This reverts commit 51d334a845a082338735b0fdfc620a4b15fa26fe.
Reported failures, need to analyze.
Added:
Modified:
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
index 058f66640c793..da9a767d6feaa 100644
--- a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -136,88 +136,30 @@ static bool isLoopNeverExecuted(Loop *L) {
return true;
}
-BasicBlock *
-getSolePredecessorOnFirstIteration(BasicBlock *BB, Loop *L,
- const DenseSet<BasicBlockEdge> &LiveEdges) {
- if (BB == L->getHeader())
- return L->getLoopPredecessor();
- BasicBlock *OnlyPred = nullptr;
- for (auto *Pred : predecessors(BB))
- if (OnlyPred != Pred && LiveEdges.count({ Pred, BB })) {
- // 2 live preds.
- if (OnlyPred)
- return nullptr;
- OnlyPred = Pred;
- }
-
- assert(OnlyPred && "No live predecessors?");
- return OnlyPred;
-}
-
-// Forward declaration.
-static const SCEV *
-getSCEVOnFirstIteration(Value *V, Loop *L, DominatorTree &DT,
- ScalarEvolution &SE,
- DenseMap<Value *, const SCEV *> &FirstIterSCEV,
- const DenseSet<BasicBlockEdge> &LiveEdges);
-
static const SCEV *
-getPHISCEVOnFirstIteration(PHINode *PN, Loop *L, DominatorTree &DT,
- ScalarEvolution &SE,
- DenseMap<Value *, const SCEV *> &FirstIterSCEV,
- const DenseSet<BasicBlockEdge> &LiveEdges) {
- auto *BB = PN->getParent();
- if (!L->contains(PN))
- return SE.getSCEV(PN);
- // If this block has only one live pred, map its phis onto their SCEVs.
- // Check if there is only one predecessor on 1st iteration. Note that because
- // we iterate in RPOT, we have already visited all its (non-latch)
- // predecessors.
- auto *OnlyPred = getSolePredecessorOnFirstIteration(BB, L, LiveEdges);
- if (!OnlyPred)
- return SE.getSCEV(PN);
- auto *Incoming = PN->getIncomingValueForBlock(OnlyPred);
- if (DT.dominates(Incoming, BB->getTerminator()))
- return getSCEVOnFirstIteration(Incoming, L, DT, SE, FirstIterSCEV,
- LiveEdges);
- return SE.getSCEV(PN);
-}
-
-static const SCEV *
-getSCEVOnFirstIteration(Value *V, Loop *L, DominatorTree &DT,
- ScalarEvolution &SE,
- DenseMap<Value *, const SCEV *> &FirstIterSCEV,
- const DenseSet<BasicBlockEdge> &LiveEdges) {
+getSCEVOnFirstIteration(Value *V, Loop *L, ScalarEvolution &SE,
+ DenseMap<Value *, const SCEV *> &FirstIterSCEV) {
// Fist, check in cache.
auto Existing = FirstIterSCEV.find(V);
if (Existing != FirstIterSCEV.end())
return Existing->second;
-
const SCEV *S = nullptr;
// TODO: Once ScalarEvolution supports getValueOnNthIteration for anything
// else but AddRecs, it's a good use case for it. So far, just consider some
// simple cases, like arithmetic operations.
Value *LHS, *RHS;
using namespace PatternMatch;
- if (auto *PN = dyn_cast<PHINode>(V)) {
- S = getPHISCEVOnFirstIteration(PN, L, DT, SE, FirstIterSCEV, LiveEdges);
- } else if (match(V, m_Add(m_Value(LHS), m_Value(RHS)))) {
- const SCEV *LHSS =
- getSCEVOnFirstIteration(LHS, L, DT, SE, FirstIterSCEV, LiveEdges);
- const SCEV *RHSS =
- getSCEVOnFirstIteration(RHS, L, DT, SE, FirstIterSCEV, LiveEdges);
+ if (match(V, m_Add(m_Value(LHS), m_Value(RHS)))) {
+ const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
+ const SCEV *RHSS = getSCEVOnFirstIteration(RHS, L, SE, FirstIterSCEV);
S = SE.getAddExpr(LHSS, RHSS);
} else if (match(V, m_Sub(m_Value(LHS), m_Value(RHS)))) {
- const SCEV *LHSS =
- getSCEVOnFirstIteration(LHS, L, DT, SE, FirstIterSCEV, LiveEdges);
- const SCEV *RHSS =
- getSCEVOnFirstIteration(RHS, L, DT, SE, FirstIterSCEV, LiveEdges);
+ const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
+ const SCEV *RHSS = getSCEVOnFirstIteration(RHS, L, SE, FirstIterSCEV);
S = SE.getMinusSCEV(LHSS, RHSS);
} else if (match(V, m_Mul(m_Value(LHS), m_Value(RHS)))) {
- const SCEV *LHSS =
- getSCEVOnFirstIteration(LHS, L, DT, SE, FirstIterSCEV, LiveEdges);
- const SCEV *RHSS =
- getSCEVOnFirstIteration(RHS, L, DT, SE, FirstIterSCEV, LiveEdges);
+ const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
+ const SCEV *RHSS = getSCEVOnFirstIteration(RHS, L, SE, FirstIterSCEV);
S = SE.getMulExpr(LHSS, RHSS);
} else
S = SE.getSCEV(V);
@@ -243,7 +185,7 @@ static bool canProveExitOnFirstIteration(Loop *L, DominatorTree &DT,
SmallPtrSet<BasicBlock *, 4> LiveBlocks;
// Edges that are reachable on the 1st iteration.
DenseSet<BasicBlockEdge> LiveEdges;
- LiveBlocks.insert(Header);
+ LiveBlocks.insert(L->getHeader());
auto MarkLiveEdge = [&](BasicBlock *From, BasicBlock *To) {
assert(LiveBlocks.count(From) && "Must be live!");
@@ -256,6 +198,24 @@ static bool canProveExitOnFirstIteration(Loop *L, DominatorTree &DT,
MarkLiveEdge(BB, Succ);
};
+ // Check if there is only one predecessor on 1st iteration. Note that because
+ // we iterate in RPOT, we have already visited all its (non-latch)
+ // predecessors.
+ auto GetSolePredecessorOnFirstIteration = [&](BasicBlock * BB)->BasicBlock * {
+ if (BB == Header)
+ return L->getLoopPredecessor();
+ BasicBlock *OnlyPred = nullptr;
+ for (auto *Pred : predecessors(BB))
+ if (OnlyPred != Pred && LiveEdges.count({ Pred, BB })) {
+ // 2 live preds.
+ if (OnlyPred)
+ return nullptr;
+ OnlyPred = Pred;
+ }
+
+ assert(OnlyPred && "No live predecessors?");
+ return OnlyPred;
+ };
DenseMap<Value *, const SCEV *> FirstIterSCEV;
SmallPtrSet<BasicBlock *, 4> Visited;
@@ -290,6 +250,19 @@ static bool canProveExitOnFirstIteration(Loop *L, DominatorTree &DT,
if (!Visited.count(Pred))
return false;
+ // If this block has only one live pred, map its phis onto their SCEVs.
+ if (auto *OnlyPred = GetSolePredecessorOnFirstIteration(BB))
+ for (auto &PN : BB->phis()) {
+ if (!SE.isSCEVable(PN.getType()))
+ continue;
+ auto *Incoming = PN.getIncomingValueForBlock(OnlyPred);
+ if (DT.dominates(Incoming, BB->getTerminator())) {
+ const SCEV *IncSCEV =
+ getSCEVOnFirstIteration(Incoming, L, SE, FirstIterSCEV);
+ FirstIterSCEV[&PN] = IncSCEV;
+ }
+ }
+
using namespace PatternMatch;
ICmpInst::Predicate Pred;
Value *LHS, *RHS;
@@ -308,10 +281,8 @@ static bool canProveExitOnFirstIteration(Loop *L, DominatorTree &DT,
}
// Can we prove constant true or false for this condition?
- const SCEV *LHSS =
- getSCEVOnFirstIteration(LHS, L, DT, SE, FirstIterSCEV, LiveEdges);
- const SCEV *RHSS =
- getSCEVOnFirstIteration(RHS, L, DT, SE, FirstIterSCEV, LiveEdges);
+ const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
+ const SCEV *RHSS = getSCEVOnFirstIteration(RHS, L, SE, FirstIterSCEV);
// Only query for liveness of in-loop edge if another successor is also
// in-loop.
// TODO: isKnownPredicateAt is more powerful, but it's too compile time
More information about the llvm-commits
mailing list