xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/LoopNestAnalysis.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
15ffd83dbSDimitry Andric //===- LoopNestAnalysis.cpp - Loop Nest Analysis --------------------------==//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric ///
95ffd83dbSDimitry Andric /// \file
105ffd83dbSDimitry Andric /// The implementation for the loop nest analysis.
115ffd83dbSDimitry Andric ///
125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
135ffd83dbSDimitry Andric 
145ffd83dbSDimitry Andric #include "llvm/Analysis/LoopNestAnalysis.h"
155ffd83dbSDimitry Andric #include "llvm/ADT/BreadthFirstIterator.h"
165ffd83dbSDimitry Andric #include "llvm/ADT/Statistic.h"
175ffd83dbSDimitry Andric #include "llvm/Analysis/PostDominators.h"
185ffd83dbSDimitry Andric #include "llvm/Analysis/ValueTracking.h"
195ffd83dbSDimitry Andric 
205ffd83dbSDimitry Andric using namespace llvm;
215ffd83dbSDimitry Andric 
225ffd83dbSDimitry Andric #define DEBUG_TYPE "loopnest"
235ffd83dbSDimitry Andric #ifndef NDEBUG
245ffd83dbSDimitry Andric static const char *VerboseDebug = DEBUG_TYPE "-verbose";
255ffd83dbSDimitry Andric #endif
265ffd83dbSDimitry Andric 
275ffd83dbSDimitry Andric /// Determine whether the loops structure violates basic requirements for
285ffd83dbSDimitry Andric /// perfect nesting:
295ffd83dbSDimitry Andric ///  - the inner loop should be the outer loop's only child
305ffd83dbSDimitry Andric ///  - the outer loop header should 'flow' into the inner loop preheader
315ffd83dbSDimitry Andric ///    or jump around the inner loop to the outer loop latch
325ffd83dbSDimitry Andric ///  - if the inner loop latch exits the inner loop, it should 'flow' into
335ffd83dbSDimitry Andric ///    the outer loop latch.
345ffd83dbSDimitry Andric /// Returns true if the loop structure satisfies the basic requirements and
355ffd83dbSDimitry Andric /// false otherwise.
365ffd83dbSDimitry Andric static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
375ffd83dbSDimitry Andric                                 ScalarEvolution &SE);
385ffd83dbSDimitry Andric 
395ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
405ffd83dbSDimitry Andric // LoopNest implementation
415ffd83dbSDimitry Andric //
425ffd83dbSDimitry Andric 
435ffd83dbSDimitry Andric LoopNest::LoopNest(Loop &Root, ScalarEvolution &SE)
445ffd83dbSDimitry Andric     : MaxPerfectDepth(getMaxPerfectDepth(Root, SE)) {
45e8d8bef9SDimitry Andric   append_range(Loops, breadth_first(&Root));
465ffd83dbSDimitry Andric }
475ffd83dbSDimitry Andric 
485ffd83dbSDimitry Andric std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
495ffd83dbSDimitry Andric                                                 ScalarEvolution &SE) {
505ffd83dbSDimitry Andric   return std::make_unique<LoopNest>(Root, SE);
515ffd83dbSDimitry Andric }
525ffd83dbSDimitry Andric 
535ffd83dbSDimitry Andric bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
545ffd83dbSDimitry Andric                                   ScalarEvolution &SE) {
55e8d8bef9SDimitry Andric   assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
56e8d8bef9SDimitry Andric   assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
575ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName()
585ffd83dbSDimitry Andric                     << "' and '" << InnerLoop.getName()
595ffd83dbSDimitry Andric                     << "' are perfectly nested.\n");
605ffd83dbSDimitry Andric 
615ffd83dbSDimitry Andric   // Determine whether the loops structure satisfies the following requirements:
625ffd83dbSDimitry Andric   //  - the inner loop should be the outer loop's only child
635ffd83dbSDimitry Andric   //  - the outer loop header should 'flow' into the inner loop preheader
645ffd83dbSDimitry Andric   //    or jump around the inner loop to the outer loop latch
655ffd83dbSDimitry Andric   //  - if the inner loop latch exits the inner loop, it should 'flow' into
665ffd83dbSDimitry Andric   //    the outer loop latch.
675ffd83dbSDimitry Andric   if (!checkLoopsStructure(OuterLoop, InnerLoop, SE)) {
685ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure.\n");
695ffd83dbSDimitry Andric     return false;
705ffd83dbSDimitry Andric   }
715ffd83dbSDimitry Andric 
725ffd83dbSDimitry Andric   // Bail out if we cannot retrieve the outer loop bounds.
735ffd83dbSDimitry Andric   auto OuterLoopLB = OuterLoop.getBounds(SE);
745ffd83dbSDimitry Andric   if (OuterLoopLB == None) {
755ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: "
765ffd83dbSDimitry Andric                       << OuterLoop << "\n";);
775ffd83dbSDimitry Andric     return false;
785ffd83dbSDimitry Andric   }
795ffd83dbSDimitry Andric 
805ffd83dbSDimitry Andric   // Identify the outer loop latch comparison instruction.
815ffd83dbSDimitry Andric   const BasicBlock *Latch = OuterLoop.getLoopLatch();
825ffd83dbSDimitry Andric   assert(Latch && "Expecting a valid loop latch");
835ffd83dbSDimitry Andric   const BranchInst *BI = dyn_cast<BranchInst>(Latch->getTerminator());
845ffd83dbSDimitry Andric   assert(BI && BI->isConditional() &&
855ffd83dbSDimitry Andric          "Expecting loop latch terminator to be a branch instruction");
865ffd83dbSDimitry Andric 
875ffd83dbSDimitry Andric   const CmpInst *OuterLoopLatchCmp = dyn_cast<CmpInst>(BI->getCondition());
885ffd83dbSDimitry Andric   DEBUG_WITH_TYPE(
895ffd83dbSDimitry Andric       VerboseDebug, if (OuterLoopLatchCmp) {
905ffd83dbSDimitry Andric         dbgs() << "Outer loop latch compare instruction: " << *OuterLoopLatchCmp
915ffd83dbSDimitry Andric                << "\n";
925ffd83dbSDimitry Andric       });
935ffd83dbSDimitry Andric 
945ffd83dbSDimitry Andric   // Identify the inner loop guard instruction.
955ffd83dbSDimitry Andric   BranchInst *InnerGuard = InnerLoop.getLoopGuardBranch();
965ffd83dbSDimitry Andric   const CmpInst *InnerLoopGuardCmp =
975ffd83dbSDimitry Andric       (InnerGuard) ? dyn_cast<CmpInst>(InnerGuard->getCondition()) : nullptr;
985ffd83dbSDimitry Andric 
995ffd83dbSDimitry Andric   DEBUG_WITH_TYPE(
1005ffd83dbSDimitry Andric       VerboseDebug, if (InnerLoopGuardCmp) {
1015ffd83dbSDimitry Andric         dbgs() << "Inner loop guard compare instruction: " << *InnerLoopGuardCmp
1025ffd83dbSDimitry Andric                << "\n";
1035ffd83dbSDimitry Andric       });
1045ffd83dbSDimitry Andric 
1055ffd83dbSDimitry Andric   // Determine whether instructions in a basic block are one of:
1065ffd83dbSDimitry Andric   //  - the inner loop guard comparison
1075ffd83dbSDimitry Andric   //  - the outer loop latch comparison
1085ffd83dbSDimitry Andric   //  - the outer loop induction variable increment
1095ffd83dbSDimitry Andric   //  - a phi node, a cast or a branch
1105ffd83dbSDimitry Andric   auto containsOnlySafeInstructions = [&](const BasicBlock &BB) {
1115ffd83dbSDimitry Andric     return llvm::all_of(BB, [&](const Instruction &I) {
1125ffd83dbSDimitry Andric       bool isAllowed = isSafeToSpeculativelyExecute(&I) || isa<PHINode>(I) ||
1135ffd83dbSDimitry Andric                        isa<BranchInst>(I);
1145ffd83dbSDimitry Andric       if (!isAllowed) {
1155ffd83dbSDimitry Andric         DEBUG_WITH_TYPE(VerboseDebug, {
1165ffd83dbSDimitry Andric           dbgs() << "Instruction: " << I << "\nin basic block: " << BB
1175ffd83dbSDimitry Andric                  << " is considered unsafe.\n";
1185ffd83dbSDimitry Andric         });
1195ffd83dbSDimitry Andric         return false;
1205ffd83dbSDimitry Andric       }
1215ffd83dbSDimitry Andric 
1225ffd83dbSDimitry Andric       // The only binary instruction allowed is the outer loop step instruction,
1235ffd83dbSDimitry Andric       // the only comparison instructions allowed are the inner loop guard
1245ffd83dbSDimitry Andric       // compare instruction and the outer loop latch compare instruction.
1255ffd83dbSDimitry Andric       if ((isa<BinaryOperator>(I) && &I != &OuterLoopLB->getStepInst()) ||
1265ffd83dbSDimitry Andric           (isa<CmpInst>(I) && &I != OuterLoopLatchCmp &&
1275ffd83dbSDimitry Andric            &I != InnerLoopGuardCmp)) {
1285ffd83dbSDimitry Andric         DEBUG_WITH_TYPE(VerboseDebug, {
1295ffd83dbSDimitry Andric           dbgs() << "Instruction: " << I << "\nin basic block:" << BB
1305ffd83dbSDimitry Andric                  << "is unsafe.\n";
1315ffd83dbSDimitry Andric         });
1325ffd83dbSDimitry Andric         return false;
1335ffd83dbSDimitry Andric       }
1345ffd83dbSDimitry Andric       return true;
1355ffd83dbSDimitry Andric     });
1365ffd83dbSDimitry Andric   };
1375ffd83dbSDimitry Andric 
1385ffd83dbSDimitry Andric   // Check the code surrounding the inner loop for instructions that are deemed
1395ffd83dbSDimitry Andric   // unsafe.
1405ffd83dbSDimitry Andric   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
1415ffd83dbSDimitry Andric   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
1425ffd83dbSDimitry Andric   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
1435ffd83dbSDimitry Andric 
1445ffd83dbSDimitry Andric   if (!containsOnlySafeInstructions(*OuterLoopHeader) ||
1455ffd83dbSDimitry Andric       !containsOnlySafeInstructions(*OuterLoopLatch) ||
1465ffd83dbSDimitry Andric       (InnerLoopPreHeader != OuterLoopHeader &&
1475ffd83dbSDimitry Andric        !containsOnlySafeInstructions(*InnerLoopPreHeader)) ||
1485ffd83dbSDimitry Andric       !containsOnlySafeInstructions(*InnerLoop.getExitBlock())) {
1495ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Not perfectly nested: code surrounding inner loop is "
1505ffd83dbSDimitry Andric                          "unsafe\n";);
1515ffd83dbSDimitry Andric     return false;
1525ffd83dbSDimitry Andric   }
1535ffd83dbSDimitry Andric 
1545ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Loop '" << OuterLoop.getName() << "' and '"
1555ffd83dbSDimitry Andric                     << InnerLoop.getName() << "' are perfectly nested.\n");
1565ffd83dbSDimitry Andric 
1575ffd83dbSDimitry Andric   return true;
1585ffd83dbSDimitry Andric }
1595ffd83dbSDimitry Andric 
1605ffd83dbSDimitry Andric SmallVector<LoopVectorTy, 4>
1615ffd83dbSDimitry Andric LoopNest::getPerfectLoops(ScalarEvolution &SE) const {
1625ffd83dbSDimitry Andric   SmallVector<LoopVectorTy, 4> LV;
1635ffd83dbSDimitry Andric   LoopVectorTy PerfectNest;
1645ffd83dbSDimitry Andric 
1655ffd83dbSDimitry Andric   for (Loop *L : depth_first(const_cast<Loop *>(Loops.front()))) {
1665ffd83dbSDimitry Andric     if (PerfectNest.empty())
1675ffd83dbSDimitry Andric       PerfectNest.push_back(L);
1685ffd83dbSDimitry Andric 
1695ffd83dbSDimitry Andric     auto &SubLoops = L->getSubLoops();
1705ffd83dbSDimitry Andric     if (SubLoops.size() == 1 && arePerfectlyNested(*L, *SubLoops.front(), SE)) {
1715ffd83dbSDimitry Andric       PerfectNest.push_back(SubLoops.front());
1725ffd83dbSDimitry Andric     } else {
1735ffd83dbSDimitry Andric       LV.push_back(PerfectNest);
1745ffd83dbSDimitry Andric       PerfectNest.clear();
1755ffd83dbSDimitry Andric     }
1765ffd83dbSDimitry Andric   }
1775ffd83dbSDimitry Andric 
1785ffd83dbSDimitry Andric   return LV;
1795ffd83dbSDimitry Andric }
1805ffd83dbSDimitry Andric 
1815ffd83dbSDimitry Andric unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) {
1825ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Get maximum perfect depth of loop nest rooted by loop '"
1835ffd83dbSDimitry Andric                     << Root.getName() << "'\n");
1845ffd83dbSDimitry Andric 
1855ffd83dbSDimitry Andric   const Loop *CurrentLoop = &Root;
1865ffd83dbSDimitry Andric   const auto *SubLoops = &CurrentLoop->getSubLoops();
1875ffd83dbSDimitry Andric   unsigned CurrentDepth = 1;
1885ffd83dbSDimitry Andric 
1895ffd83dbSDimitry Andric   while (SubLoops->size() == 1) {
1905ffd83dbSDimitry Andric     const Loop *InnerLoop = SubLoops->front();
1915ffd83dbSDimitry Andric     if (!arePerfectlyNested(*CurrentLoop, *InnerLoop, SE)) {
1925ffd83dbSDimitry Andric       LLVM_DEBUG({
1935ffd83dbSDimitry Andric         dbgs() << "Not a perfect nest: loop '" << CurrentLoop->getName()
1945ffd83dbSDimitry Andric                << "' is not perfectly nested with loop '"
1955ffd83dbSDimitry Andric                << InnerLoop->getName() << "'\n";
1965ffd83dbSDimitry Andric       });
1975ffd83dbSDimitry Andric       break;
1985ffd83dbSDimitry Andric     }
1995ffd83dbSDimitry Andric 
2005ffd83dbSDimitry Andric     CurrentLoop = InnerLoop;
2015ffd83dbSDimitry Andric     SubLoops = &CurrentLoop->getSubLoops();
2025ffd83dbSDimitry Andric     ++CurrentDepth;
2035ffd83dbSDimitry Andric   }
2045ffd83dbSDimitry Andric 
2055ffd83dbSDimitry Andric   return CurrentDepth;
2065ffd83dbSDimitry Andric }
2075ffd83dbSDimitry Andric 
208e8d8bef9SDimitry Andric const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
209*fe6060f1SDimitry Andric                                                 const BasicBlock *End,
210*fe6060f1SDimitry Andric                                                 bool CheckUniquePred) {
211e8d8bef9SDimitry Andric   assert(From && "Expecting valid From");
212e8d8bef9SDimitry Andric   assert(End && "Expecting valid End");
213e8d8bef9SDimitry Andric 
214*fe6060f1SDimitry Andric   if (From == End || !From->getUniqueSuccessor())
215e8d8bef9SDimitry Andric     return *From;
216e8d8bef9SDimitry Andric 
217e8d8bef9SDimitry Andric   auto IsEmpty = [](const BasicBlock *BB) {
218e8d8bef9SDimitry Andric     return (BB->getInstList().size() == 1);
219e8d8bef9SDimitry Andric   };
220e8d8bef9SDimitry Andric 
221e8d8bef9SDimitry Andric   // Visited is used to avoid running into an infinite loop.
222e8d8bef9SDimitry Andric   SmallPtrSet<const BasicBlock *, 4> Visited;
223*fe6060f1SDimitry Andric   const BasicBlock *BB = From->getUniqueSuccessor();
224*fe6060f1SDimitry Andric   const BasicBlock *PredBB = From;
225*fe6060f1SDimitry Andric   while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB) &&
226*fe6060f1SDimitry Andric          (!CheckUniquePred || BB->getUniquePredecessor())) {
227e8d8bef9SDimitry Andric     Visited.insert(BB);
228e8d8bef9SDimitry Andric     PredBB = BB;
229*fe6060f1SDimitry Andric     BB = BB->getUniqueSuccessor();
230e8d8bef9SDimitry Andric   }
231e8d8bef9SDimitry Andric 
232e8d8bef9SDimitry Andric   return (BB == End) ? *End : *PredBB;
233e8d8bef9SDimitry Andric }
234e8d8bef9SDimitry Andric 
2355ffd83dbSDimitry Andric static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
2365ffd83dbSDimitry Andric                                 ScalarEvolution &SE) {
2375ffd83dbSDimitry Andric   // The inner loop must be the only outer loop's child.
2385ffd83dbSDimitry Andric   if ((OuterLoop.getSubLoops().size() != 1) ||
2395ffd83dbSDimitry Andric       (InnerLoop.getParentLoop() != &OuterLoop))
2405ffd83dbSDimitry Andric     return false;
2415ffd83dbSDimitry Andric 
2425ffd83dbSDimitry Andric   // We expect loops in normal form which have a preheader, header, latch...
2435ffd83dbSDimitry Andric   if (!OuterLoop.isLoopSimplifyForm() || !InnerLoop.isLoopSimplifyForm())
2445ffd83dbSDimitry Andric     return false;
2455ffd83dbSDimitry Andric 
2465ffd83dbSDimitry Andric   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
2475ffd83dbSDimitry Andric   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
2485ffd83dbSDimitry Andric   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
2495ffd83dbSDimitry Andric   const BasicBlock *InnerLoopLatch = InnerLoop.getLoopLatch();
2505ffd83dbSDimitry Andric   const BasicBlock *InnerLoopExit = InnerLoop.getExitBlock();
2515ffd83dbSDimitry Andric 
2525ffd83dbSDimitry Andric   // We expect rotated loops. The inner loop should have a single exit block.
2535ffd83dbSDimitry Andric   if (OuterLoop.getExitingBlock() != OuterLoopLatch ||
2545ffd83dbSDimitry Andric       InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit)
2555ffd83dbSDimitry Andric     return false;
2565ffd83dbSDimitry Andric 
257e8d8bef9SDimitry Andric   // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
258e8d8bef9SDimitry Andric   auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
259e8d8bef9SDimitry Andric     return any_of(ExitBlock.phis(), [](const PHINode &PN) {
260e8d8bef9SDimitry Andric       return PN.getNumIncomingValues() == 1;
261e8d8bef9SDimitry Andric     });
262e8d8bef9SDimitry Andric   };
263e8d8bef9SDimitry Andric 
264e8d8bef9SDimitry Andric   // Returns whether the block `BB` qualifies for being an extra Phi block. The
265e8d8bef9SDimitry Andric   // extra Phi block is the additional block inserted after the exit block of an
266e8d8bef9SDimitry Andric   // "guarded" inner loop which contains "only" Phi nodes corresponding to the
267e8d8bef9SDimitry Andric   // LCSSA Phi nodes in the exit block.
268e8d8bef9SDimitry Andric   auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
269e8d8bef9SDimitry Andric     return BB.getFirstNonPHI() == BB.getTerminator() &&
270e8d8bef9SDimitry Andric            all_of(BB.phis(), [&](const PHINode &PN) {
271e8d8bef9SDimitry Andric              return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
272e8d8bef9SDimitry Andric                return IncomingBlock == InnerLoopExit ||
273e8d8bef9SDimitry Andric                       IncomingBlock == OuterLoopHeader;
274e8d8bef9SDimitry Andric              });
275e8d8bef9SDimitry Andric            });
276e8d8bef9SDimitry Andric   };
277e8d8bef9SDimitry Andric 
278e8d8bef9SDimitry Andric   const BasicBlock *ExtraPhiBlock = nullptr;
2795ffd83dbSDimitry Andric   // Ensure the only branch that may exist between the loops is the inner loop
2805ffd83dbSDimitry Andric   // guard.
2815ffd83dbSDimitry Andric   if (OuterLoopHeader != InnerLoopPreHeader) {
282e8d8bef9SDimitry Andric     const BasicBlock &SingleSucc =
283e8d8bef9SDimitry Andric         LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
284e8d8bef9SDimitry Andric 
285e8d8bef9SDimitry Andric     // no conditional branch present
286e8d8bef9SDimitry Andric     if (&SingleSucc != InnerLoopPreHeader) {
287e8d8bef9SDimitry Andric       const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
2885ffd83dbSDimitry Andric 
2895ffd83dbSDimitry Andric       if (!BI || BI != InnerLoop.getLoopGuardBranch())
2905ffd83dbSDimitry Andric         return false;
2915ffd83dbSDimitry Andric 
292e8d8bef9SDimitry Andric       bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
293e8d8bef9SDimitry Andric 
2945ffd83dbSDimitry Andric       // The successors of the inner loop guard should be the inner loop
295e8d8bef9SDimitry Andric       // preheader or the outer loop latch possibly through empty blocks.
2965ffd83dbSDimitry Andric       for (const BasicBlock *Succ : BI->successors()) {
297e8d8bef9SDimitry Andric         const BasicBlock *PotentialInnerPreHeader = Succ;
298e8d8bef9SDimitry Andric         const BasicBlock *PotentialOuterLatch = Succ;
299e8d8bef9SDimitry Andric 
300e8d8bef9SDimitry Andric         // Ensure the inner loop guard successor is empty before skipping
301e8d8bef9SDimitry Andric         // blocks.
302e8d8bef9SDimitry Andric         if (Succ->getInstList().size() == 1) {
303e8d8bef9SDimitry Andric           PotentialInnerPreHeader =
304e8d8bef9SDimitry Andric               &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
305e8d8bef9SDimitry Andric           PotentialOuterLatch =
306e8d8bef9SDimitry Andric               &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
307e8d8bef9SDimitry Andric         }
308e8d8bef9SDimitry Andric 
309e8d8bef9SDimitry Andric         if (PotentialInnerPreHeader == InnerLoopPreHeader)
3105ffd83dbSDimitry Andric           continue;
311e8d8bef9SDimitry Andric         if (PotentialOuterLatch == OuterLoopLatch)
3125ffd83dbSDimitry Andric           continue;
3135ffd83dbSDimitry Andric 
314e8d8bef9SDimitry Andric         // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
315e8d8bef9SDimitry Andric         // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
316e8d8bef9SDimitry Andric         // loops are still considered perfectly nested if the extra block only
317e8d8bef9SDimitry Andric         // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
318e8d8bef9SDimitry Andric         if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
319e8d8bef9SDimitry Andric             Succ->getSingleSuccessor() == OuterLoopLatch) {
320e8d8bef9SDimitry Andric           // Points to the extra block so that we can reference it later in the
321e8d8bef9SDimitry Andric           // final check. We can also conclude that the inner loop is
322e8d8bef9SDimitry Andric           // guarded and there exists LCSSA Phi node in the exit block later if
323e8d8bef9SDimitry Andric           // we see a non-null `ExtraPhiBlock`.
324e8d8bef9SDimitry Andric           ExtraPhiBlock = Succ;
325e8d8bef9SDimitry Andric           continue;
326e8d8bef9SDimitry Andric         }
327e8d8bef9SDimitry Andric 
3285ffd83dbSDimitry Andric         DEBUG_WITH_TYPE(VerboseDebug, {
3295ffd83dbSDimitry Andric           dbgs() << "Inner loop guard successor " << Succ->getName()
3305ffd83dbSDimitry Andric                  << " doesn't lead to inner loop preheader or "
3315ffd83dbSDimitry Andric                     "outer loop latch.\n";
3325ffd83dbSDimitry Andric         });
3335ffd83dbSDimitry Andric         return false;
3345ffd83dbSDimitry Andric       }
3355ffd83dbSDimitry Andric     }
336e8d8bef9SDimitry Andric   }
3375ffd83dbSDimitry Andric 
338e8d8bef9SDimitry Andric   // Ensure the inner loop exit block lead to the outer loop latch possibly
339e8d8bef9SDimitry Andric   // through empty blocks.
340*fe6060f1SDimitry Andric   if ((!ExtraPhiBlock ||
341*fe6060f1SDimitry Andric        &LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(),
342*fe6060f1SDimitry Andric                                       ExtraPhiBlock) != ExtraPhiBlock) &&
343*fe6060f1SDimitry Andric       (&LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(),
344*fe6060f1SDimitry Andric                                       OuterLoopLatch) != OuterLoopLatch)) {
3455ffd83dbSDimitry Andric     DEBUG_WITH_TYPE(
3465ffd83dbSDimitry Andric         VerboseDebug,
3475ffd83dbSDimitry Andric         dbgs() << "Inner loop exit block " << *InnerLoopExit
3485ffd83dbSDimitry Andric                << " does not directly lead to the outer loop latch.\n";);
3495ffd83dbSDimitry Andric     return false;
3505ffd83dbSDimitry Andric   }
3515ffd83dbSDimitry Andric 
3525ffd83dbSDimitry Andric   return true;
3535ffd83dbSDimitry Andric }
3545ffd83dbSDimitry Andric 
355e8d8bef9SDimitry Andric AnalysisKey LoopNestAnalysis::Key;
356e8d8bef9SDimitry Andric 
3575ffd83dbSDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) {
3585ffd83dbSDimitry Andric   OS << "IsPerfect=";
3595ffd83dbSDimitry Andric   if (LN.getMaxPerfectDepth() == LN.getNestDepth())
3605ffd83dbSDimitry Andric     OS << "true";
3615ffd83dbSDimitry Andric   else
3625ffd83dbSDimitry Andric     OS << "false";
3635ffd83dbSDimitry Andric   OS << ", Depth=" << LN.getNestDepth();
3645ffd83dbSDimitry Andric   OS << ", OutermostLoop: " << LN.getOutermostLoop().getName();
3655ffd83dbSDimitry Andric   OS << ", Loops: ( ";
3665ffd83dbSDimitry Andric   for (const Loop *L : LN.getLoops())
3675ffd83dbSDimitry Andric     OS << L->getName() << " ";
3685ffd83dbSDimitry Andric   OS << ")";
3695ffd83dbSDimitry Andric 
3705ffd83dbSDimitry Andric   return OS;
3715ffd83dbSDimitry Andric }
3725ffd83dbSDimitry Andric 
3735ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
3745ffd83dbSDimitry Andric // LoopNestPrinterPass implementation
3755ffd83dbSDimitry Andric //
3765ffd83dbSDimitry Andric 
3775ffd83dbSDimitry Andric PreservedAnalyses LoopNestPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
3785ffd83dbSDimitry Andric                                            LoopStandardAnalysisResults &AR,
3795ffd83dbSDimitry Andric                                            LPMUpdater &U) {
3805ffd83dbSDimitry Andric   if (auto LN = LoopNest::getLoopNest(L, AR.SE))
3815ffd83dbSDimitry Andric     OS << *LN << "\n";
3825ffd83dbSDimitry Andric 
3835ffd83dbSDimitry Andric   return PreservedAnalyses::all();
3845ffd83dbSDimitry Andric }
385