[PATCH] D92066: [LAA] Relax restrictions on early exits in loop structure

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 24 18:23:31 PST 2020


reames created this revision.
reames added reviewers: fhahn, Ayal.
Herald added subscribers: dantrushin, bollu, hiraditya, mcrosier.
Herald added a project: LLVM.
reames requested review of this revision.

This is a preparation patch for supporting multiple exits in the loop vectorizer, by itself it should be purely NFC.  This patch moves the loop structure checks from LAA to their respective consumers (where duplicates don't already exist).

Why do this?  Well, after auditing the code, I can't actually find anything in LAA itself which relies on having all instructions within a loop execute an equal number of times.  This patch simply makes this explicit so that if one consumer - say LV in the near future (hopefully) - wants to handle a broader class of loops, it can do so.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D92066

Files:
  llvm/lib/Analysis/LoopAccessAnalysis.cpp
  llvm/lib/Transforms/Scalar/LoopDistribute.cpp
  llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
  llvm/lib/Transforms/Utils/LoopVersioning.cpp


Index: llvm/lib/Transforms/Utils/LoopVersioning.cpp
===================================================================
--- llvm/lib/Transforms/Utils/LoopVersioning.cpp
+++ llvm/lib/Transforms/Utils/LoopVersioning.cpp
@@ -269,8 +269,11 @@
   // Now walk the identified inner loops.
   bool Changed = false;
   for (Loop *L : Worklist) {
+    if (!L->isLoopSimplifyForm() || !L->isRotatedForm() ||
+	!L->getExitingBlock())
+      continue;
     const LoopAccessInfo &LAI = GetLAA(*L);
-    if (L->isLoopSimplifyForm() && !LAI.hasConvergentOp() &&
+    if (!LAI.hasConvergentOp() &&
         (LAI.getNumRuntimePointerChecks() ||
          !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) {
       LoopVersioning LVer(LAI, LAI.getRuntimePointerChecking()->getChecks(), L,
Index: llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
+++ llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
@@ -627,6 +627,9 @@
   // Now walk the identified inner loops.
   bool Changed = false;
   for (Loop *L : Worklist) {
+    // Match historical behavior
+    if (!L->isRotatedForm() || !L->getExitingBlock())
+      continue;
     // The actual work is performed by LoadEliminationForLoop.
     LoadEliminationForLoop LEL(L, &LI, GetLAI(*L), &DT, BFI, PSI);
     Changed |= LEL.processLoop();
Index: llvm/lib/Transforms/Scalar/LoopDistribute.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDistribute.cpp
+++ llvm/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -675,6 +675,9 @@
     if (!L->isLoopSimplifyForm())
       return fail("NotLoopSimplifyForm",
                   "loop is not in loop-simplify form");
+    if (!L->isRotatedForm())
+      return fail("NotBottomTested",
+                  "loop is not bottom tested");
 
     BasicBlock *PH = L->getLoopPreheader();
 
Index: llvm/lib/Analysis/LoopAccessAnalysis.cpp
===================================================================
--- llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -1781,26 +1781,6 @@
     return false;
   }
 
-  // We must have a single exiting block.
-  if (!TheLoop->getExitingBlock()) {
-    LLVM_DEBUG(
-        dbgs() << "LAA: loop control flow is not understood by analyzer\n");
-    recordAnalysis("CFGNotUnderstood")
-        << "loop control flow is not understood by analyzer";
-    return false;
-  }
-
-  // We only handle bottom-tested loops, i.e. loop in which the condition is
-  // checked at the end of each iteration. With that we can assume that all
-  // instructions in the loop are executed the same number of times.
-  if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
-    LLVM_DEBUG(
-        dbgs() << "LAA: loop control flow is not understood by analyzer\n");
-    recordAnalysis("CFGNotUnderstood")
-        << "loop control flow is not understood by analyzer";
-    return false;
-  }
-
   // ScalarEvolution needs to be able to find the exit count.
   const SCEV *ExitCount = PSE->getBackedgeTakenCount();
   if (ExitCount == PSE->getSE()->getCouldNotCompute()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92066.307490.patch
Type: text/x-patch
Size: 3190 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201125/6305ff45/attachment.bin>


More information about the llvm-commits mailing list