Revert "[NFCI] Lazily evaluate SCEVs of PHIs"
authorMax Kazantsev <mkazantsev@azul.com>
Fri, 28 May 2021 04:05:30 +0000 (11:05 +0700)
committerMax Kazantsev <mkazantsev@azul.com>
Fri, 28 May 2021 04:05:30 +0000 (11:05 +0700)
This reverts commit 51d334a845a082338735b0fdfc620a4b15fa26fe.

Reported failures, need to analyze.

llvm/lib/Transforms/Scalar/LoopDeletion.cpp

index 058f666..da9a767 100644 (file)
@@ -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