[PATCH] D111493: [IVUsers] Check for preheader instead of loop simplify form

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 9 08:09:47 PDT 2021


nikic created this revision.
nikic added reviewers: reames, mkazantsev.
Herald added subscribers: javed.absar, hiraditya.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

IVUsers currently makes sure that all loops dominating a user are in loop simplify form, because SCEVExpander needs a preheader to insert into. However, loop simplify form requires much more than that. In particular, it requires dedicated exits, which means that exits need to be found and walked. For large functions with many nested loops, this can result in pathological compile-time explosion.

Fix this by only checking the property we're actually interested in, which is incidentally cheap to check.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111493

Files:
  llvm/lib/Analysis/IVUsers.cpp


Index: llvm/lib/Analysis/IVUsers.cpp
===================================================================
--- llvm/lib/Analysis/IVUsers.cpp
+++ llvm/lib/Analysis/IVUsers.cpp
@@ -90,11 +90,10 @@
   return false;
 }
 
-/// Return true if all loop headers that dominate this block are in simplified
-/// form.
-static bool isSimplifiedLoopNest(BasicBlock *BB, const DominatorTree *DT,
-                                 const LoopInfo *LI,
-                                 SmallPtrSetImpl<Loop*> &SimpleLoopNests) {
+/// Return true if all loop headers that dominate this block have a preheader.
+static bool isPreheaderLoopNest(BasicBlock *BB, const DominatorTree *DT,
+                                const LoopInfo *LI,
+                                SmallPtrSetImpl<Loop*> &PreheaderLoopNests) {
   Loop *NearestLoop = nullptr;
   for (DomTreeNode *Rung = DT->getNode(BB);
        Rung; Rung = Rung->getIDom()) {
@@ -102,10 +101,10 @@
     Loop *DomLoop = LI->getLoopFor(DomBB);
     if (DomLoop && DomLoop->getHeader() == DomBB) {
       // If we have already checked this loop nest, stop checking.
-      if (SimpleLoopNests.count(DomLoop))
+      if (PreheaderLoopNests.count(DomLoop))
         break;
       // If the domtree walk reaches a loop with no preheader, return false.
-      if (!DomLoop->isLoopSimplifyForm())
+      if (!DomLoop->getLoopPreheader())
         return false;
       // If we have not already checked this loop nest, remember the loop
       // header nearest to BB. The nearest loop may not contain BB.
@@ -114,7 +113,7 @@
     }
   }
   if (NearestLoop)
-    SimpleLoopNests.insert(NearestLoop);
+    PreheaderLoopNests.insert(NearestLoop);
   return true;
 }
 
@@ -166,7 +165,7 @@
 /// reducible SCEV, recursively add its users to the IVUsesByStride set and
 /// return true.  Otherwise, return false.
 bool IVUsers::AddUsersImpl(Instruction *I,
-                           SmallPtrSetImpl<Loop*> &SimpleLoopNests) {
+                           SmallPtrSetImpl<Loop*> &PreheaderLoopNests) {
   const DataLayout &DL = I->getModule()->getDataLayout();
 
   // Add this IV user to the Processed set before returning false to ensure that
@@ -222,7 +221,7 @@
       unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
       UseBB = PHI->getIncomingBlock(ValNo);
     }
-    if (!isSimplifiedLoopNest(UseBB, DT, LI, SimpleLoopNests))
+    if (!isPreheaderLoopNest(UseBB, DT, LI, PreheaderLoopNests))
       return false;
 
     // Descend recursively, but not into PHI nodes outside the current loop.
@@ -234,12 +233,13 @@
     bool AddUserToIVUsers = false;
     if (LI->getLoopFor(User->getParent()) != L) {
       if (isa<PHINode>(User) || Processed.count(User) ||
-          !AddUsersImpl(User, SimpleLoopNests)) {
+          !AddUsersImpl(User, PreheaderLoopNests)) {
         LLVM_DEBUG(dbgs() << "FOUND USER in other loop: " << *User << '\n'
                           << "   OF SCEV: " << *ISE << '\n');
         AddUserToIVUsers = true;
       }
-    } else if (Processed.count(User) || !AddUsersImpl(User, SimpleLoopNests)) {
+    } else if (Processed.count(User) ||
+               !AddUsersImpl(User, PreheaderLoopNests)) {
       LLVM_DEBUG(dbgs() << "FOUND USER: " << *User << '\n'
                         << "   OF SCEV: " << *ISE << '\n');
       AddUserToIVUsers = true;
@@ -289,12 +289,12 @@
 }
 
 bool IVUsers::AddUsersIfInteresting(Instruction *I) {
-  // SCEVExpander can only handle users that are dominated by simplified loop
-  // entries. Keep track of all loops that are only dominated by other simple
+  // SCEVExpander can only handle users that are dominated by loops with
+  // preheaders. Keep track of all loops that are only dominated by preheader
   // loops so we don't traverse the domtree for each user.
-  SmallPtrSet<Loop*,16> SimpleLoopNests;
+  SmallPtrSet<Loop*,16> PreheaderLoopNests;
 
-  return AddUsersImpl(I, SimpleLoopNests);
+  return AddUsersImpl(I, PreheaderLoopNests);
 }
 
 IVStrideUse &IVUsers::AddUser(Instruction *User, Value *Operand) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111493.378454.patch
Type: text/x-patch
Size: 4041 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211009/1ba5adb1/attachment.bin>


More information about the llvm-commits mailing list