xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/LoopNestAnalysis.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
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 
53*349cc55cSDimitry Andric static CmpInst *getOuterLoopLatchCmp(const Loop &OuterLoop) {
54*349cc55cSDimitry Andric 
55*349cc55cSDimitry Andric   const BasicBlock *Latch = OuterLoop.getLoopLatch();
56*349cc55cSDimitry Andric   assert(Latch && "Expecting a valid loop latch");
57*349cc55cSDimitry Andric 
58*349cc55cSDimitry Andric   const BranchInst *BI = dyn_cast<BranchInst>(Latch->getTerminator());
59*349cc55cSDimitry Andric   assert(BI && BI->isConditional() &&
60*349cc55cSDimitry Andric          "Expecting loop latch terminator to be a branch instruction");
61*349cc55cSDimitry Andric 
62*349cc55cSDimitry Andric   CmpInst *OuterLoopLatchCmp = dyn_cast<CmpInst>(BI->getCondition());
63*349cc55cSDimitry Andric   DEBUG_WITH_TYPE(
64*349cc55cSDimitry Andric       VerboseDebug, if (OuterLoopLatchCmp) {
65*349cc55cSDimitry Andric         dbgs() << "Outer loop latch compare instruction: " << *OuterLoopLatchCmp
66*349cc55cSDimitry Andric                << "\n";
67*349cc55cSDimitry Andric       });
68*349cc55cSDimitry Andric   return OuterLoopLatchCmp;
69*349cc55cSDimitry Andric }
70*349cc55cSDimitry Andric 
71*349cc55cSDimitry Andric static CmpInst *getInnerLoopGuardCmp(const Loop &InnerLoop) {
72*349cc55cSDimitry Andric 
73*349cc55cSDimitry Andric   BranchInst *InnerGuard = InnerLoop.getLoopGuardBranch();
74*349cc55cSDimitry Andric   CmpInst *InnerLoopGuardCmp =
75*349cc55cSDimitry Andric       (InnerGuard) ? dyn_cast<CmpInst>(InnerGuard->getCondition()) : nullptr;
76*349cc55cSDimitry Andric 
77*349cc55cSDimitry Andric   DEBUG_WITH_TYPE(
78*349cc55cSDimitry Andric       VerboseDebug, if (InnerLoopGuardCmp) {
79*349cc55cSDimitry Andric         dbgs() << "Inner loop guard compare instruction: " << *InnerLoopGuardCmp
80*349cc55cSDimitry Andric                << "\n";
81*349cc55cSDimitry Andric       });
82*349cc55cSDimitry Andric   return InnerLoopGuardCmp;
83*349cc55cSDimitry Andric }
84*349cc55cSDimitry Andric 
85*349cc55cSDimitry Andric static bool checkSafeInstruction(const Instruction &I,
86*349cc55cSDimitry Andric                                  const CmpInst *InnerLoopGuardCmp,
87*349cc55cSDimitry Andric                                  const CmpInst *OuterLoopLatchCmp,
88*349cc55cSDimitry Andric                                  Optional<Loop::LoopBounds> OuterLoopLB) {
89*349cc55cSDimitry Andric 
90*349cc55cSDimitry Andric   bool IsAllowed =
91*349cc55cSDimitry Andric       isSafeToSpeculativelyExecute(&I) || isa<PHINode>(I) || isa<BranchInst>(I);
92*349cc55cSDimitry Andric   if (!IsAllowed)
93*349cc55cSDimitry Andric     return false;
94*349cc55cSDimitry Andric   // The only binary instruction allowed is the outer loop step instruction,
95*349cc55cSDimitry Andric   // the only comparison instructions allowed are the inner loop guard
96*349cc55cSDimitry Andric   // compare instruction and the outer loop latch compare instruction.
97*349cc55cSDimitry Andric   if ((isa<BinaryOperator>(I) && &I != &OuterLoopLB->getStepInst()) ||
98*349cc55cSDimitry Andric       (isa<CmpInst>(I) && &I != OuterLoopLatchCmp && &I != InnerLoopGuardCmp)) {
99*349cc55cSDimitry Andric     return false;
100*349cc55cSDimitry Andric   }
101*349cc55cSDimitry Andric   return true;
102*349cc55cSDimitry Andric }
103*349cc55cSDimitry Andric 
1045ffd83dbSDimitry Andric bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
1055ffd83dbSDimitry Andric                                   ScalarEvolution &SE) {
106*349cc55cSDimitry Andric   return (analyzeLoopNestForPerfectNest(OuterLoop, InnerLoop, SE) ==
107*349cc55cSDimitry Andric           PerfectLoopNest);
108*349cc55cSDimitry Andric }
109*349cc55cSDimitry Andric 
110*349cc55cSDimitry Andric LoopNest::LoopNestEnum LoopNest::analyzeLoopNestForPerfectNest(
111*349cc55cSDimitry Andric     const Loop &OuterLoop, const Loop &InnerLoop, ScalarEvolution &SE) {
112*349cc55cSDimitry Andric 
113e8d8bef9SDimitry Andric   assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
114e8d8bef9SDimitry Andric   assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
1155ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName()
1165ffd83dbSDimitry Andric                     << "' and '" << InnerLoop.getName()
1175ffd83dbSDimitry Andric                     << "' are perfectly nested.\n");
1185ffd83dbSDimitry Andric 
1195ffd83dbSDimitry Andric   // Determine whether the loops structure satisfies the following requirements:
1205ffd83dbSDimitry Andric   //  - the inner loop should be the outer loop's only child
1215ffd83dbSDimitry Andric   //  - the outer loop header should 'flow' into the inner loop preheader
1225ffd83dbSDimitry Andric   //    or jump around the inner loop to the outer loop latch
1235ffd83dbSDimitry Andric   //  - if the inner loop latch exits the inner loop, it should 'flow' into
1245ffd83dbSDimitry Andric   //    the outer loop latch.
1255ffd83dbSDimitry Andric   if (!checkLoopsStructure(OuterLoop, InnerLoop, SE)) {
1265ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure.\n");
127*349cc55cSDimitry Andric     return InvalidLoopStructure;
1285ffd83dbSDimitry Andric   }
1295ffd83dbSDimitry Andric 
1305ffd83dbSDimitry Andric   // Bail out if we cannot retrieve the outer loop bounds.
1315ffd83dbSDimitry Andric   auto OuterLoopLB = OuterLoop.getBounds(SE);
1325ffd83dbSDimitry Andric   if (OuterLoopLB == None) {
1335ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: "
1345ffd83dbSDimitry Andric                       << OuterLoop << "\n";);
135*349cc55cSDimitry Andric     return OuterLoopLowerBoundUnknown;
1365ffd83dbSDimitry Andric   }
1375ffd83dbSDimitry Andric 
138*349cc55cSDimitry Andric   CmpInst *OuterLoopLatchCmp = getOuterLoopLatchCmp(OuterLoop);
139*349cc55cSDimitry Andric   CmpInst *InnerLoopGuardCmp = getInnerLoopGuardCmp(InnerLoop);
1405ffd83dbSDimitry Andric 
1415ffd83dbSDimitry Andric   // Determine whether instructions in a basic block are one of:
1425ffd83dbSDimitry Andric   //  - the inner loop guard comparison
1435ffd83dbSDimitry Andric   //  - the outer loop latch comparison
1445ffd83dbSDimitry Andric   //  - the outer loop induction variable increment
1455ffd83dbSDimitry Andric   //  - a phi node, a cast or a branch
1465ffd83dbSDimitry Andric   auto containsOnlySafeInstructions = [&](const BasicBlock &BB) {
1475ffd83dbSDimitry Andric     return llvm::all_of(BB, [&](const Instruction &I) {
148*349cc55cSDimitry Andric       bool IsSafeInstr = checkSafeInstruction(I, InnerLoopGuardCmp,
149*349cc55cSDimitry Andric                                               OuterLoopLatchCmp, OuterLoopLB);
150*349cc55cSDimitry Andric       if (IsSafeInstr) {
1515ffd83dbSDimitry Andric         DEBUG_WITH_TYPE(VerboseDebug, {
1525ffd83dbSDimitry Andric           dbgs() << "Instruction: " << I << "\nin basic block:" << BB
1535ffd83dbSDimitry Andric                  << "is unsafe.\n";
1545ffd83dbSDimitry Andric         });
1555ffd83dbSDimitry Andric       }
156*349cc55cSDimitry Andric       return IsSafeInstr;
1575ffd83dbSDimitry Andric     });
1585ffd83dbSDimitry Andric   };
1595ffd83dbSDimitry Andric 
1605ffd83dbSDimitry Andric   // Check the code surrounding the inner loop for instructions that are deemed
1615ffd83dbSDimitry Andric   // unsafe.
1625ffd83dbSDimitry Andric   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
1635ffd83dbSDimitry Andric   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
1645ffd83dbSDimitry Andric   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
1655ffd83dbSDimitry Andric 
1665ffd83dbSDimitry Andric   if (!containsOnlySafeInstructions(*OuterLoopHeader) ||
1675ffd83dbSDimitry Andric       !containsOnlySafeInstructions(*OuterLoopLatch) ||
1685ffd83dbSDimitry Andric       (InnerLoopPreHeader != OuterLoopHeader &&
1695ffd83dbSDimitry Andric        !containsOnlySafeInstructions(*InnerLoopPreHeader)) ||
1705ffd83dbSDimitry Andric       !containsOnlySafeInstructions(*InnerLoop.getExitBlock())) {
1715ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Not perfectly nested: code surrounding inner loop is "
1725ffd83dbSDimitry Andric                          "unsafe\n";);
173*349cc55cSDimitry Andric     return ImperfectLoopNest;
1745ffd83dbSDimitry Andric   }
1755ffd83dbSDimitry Andric 
1765ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Loop '" << OuterLoop.getName() << "' and '"
1775ffd83dbSDimitry Andric                     << InnerLoop.getName() << "' are perfectly nested.\n");
1785ffd83dbSDimitry Andric 
179*349cc55cSDimitry Andric   return PerfectLoopNest;
180*349cc55cSDimitry Andric }
181*349cc55cSDimitry Andric 
182*349cc55cSDimitry Andric LoopNest::InstrVectorTy LoopNest::getInterveningInstructions(
183*349cc55cSDimitry Andric     const Loop &OuterLoop, const Loop &InnerLoop, ScalarEvolution &SE) {
184*349cc55cSDimitry Andric   InstrVectorTy Instr;
185*349cc55cSDimitry Andric   switch (analyzeLoopNestForPerfectNest(OuterLoop, InnerLoop, SE)) {
186*349cc55cSDimitry Andric   case PerfectLoopNest:
187*349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "The loop Nest is Perfect, returning empty "
188*349cc55cSDimitry Andric                          "instruction vector. \n";);
189*349cc55cSDimitry Andric     return Instr;
190*349cc55cSDimitry Andric 
191*349cc55cSDimitry Andric   case InvalidLoopStructure:
192*349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure. "
193*349cc55cSDimitry Andric                          "Instruction vector is empty.\n";);
194*349cc55cSDimitry Andric     return Instr;
195*349cc55cSDimitry Andric 
196*349cc55cSDimitry Andric   case OuterLoopLowerBoundUnknown:
197*349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: "
198*349cc55cSDimitry Andric                       << OuterLoop << "\nInstruction vector is empty.\n";);
199*349cc55cSDimitry Andric     return Instr;
200*349cc55cSDimitry Andric 
201*349cc55cSDimitry Andric   case ImperfectLoopNest:
202*349cc55cSDimitry Andric     break;
203*349cc55cSDimitry Andric   }
204*349cc55cSDimitry Andric 
205*349cc55cSDimitry Andric   // Identify the outer loop latch comparison instruction.
206*349cc55cSDimitry Andric   auto OuterLoopLB = OuterLoop.getBounds(SE);
207*349cc55cSDimitry Andric 
208*349cc55cSDimitry Andric   CmpInst *OuterLoopLatchCmp = getOuterLoopLatchCmp(OuterLoop);
209*349cc55cSDimitry Andric   CmpInst *InnerLoopGuardCmp = getInnerLoopGuardCmp(InnerLoop);
210*349cc55cSDimitry Andric 
211*349cc55cSDimitry Andric   auto GetUnsafeInstructions = [&](const BasicBlock &BB) {
212*349cc55cSDimitry Andric     for (const Instruction &I : BB) {
213*349cc55cSDimitry Andric       if (!checkSafeInstruction(I, InnerLoopGuardCmp, OuterLoopLatchCmp,
214*349cc55cSDimitry Andric                                 OuterLoopLB)) {
215*349cc55cSDimitry Andric         Instr.push_back(&I);
216*349cc55cSDimitry Andric         DEBUG_WITH_TYPE(VerboseDebug, {
217*349cc55cSDimitry Andric           dbgs() << "Instruction: " << I << "\nin basic block:" << BB
218*349cc55cSDimitry Andric                  << "is unsafe.\n";
219*349cc55cSDimitry Andric         });
220*349cc55cSDimitry Andric       }
221*349cc55cSDimitry Andric     }
222*349cc55cSDimitry Andric   };
223*349cc55cSDimitry Andric 
224*349cc55cSDimitry Andric   // Check the code surrounding the inner loop for instructions that are deemed
225*349cc55cSDimitry Andric   // unsafe.
226*349cc55cSDimitry Andric   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
227*349cc55cSDimitry Andric   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
228*349cc55cSDimitry Andric   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
229*349cc55cSDimitry Andric   const BasicBlock *InnerLoopExitBlock = InnerLoop.getExitBlock();
230*349cc55cSDimitry Andric 
231*349cc55cSDimitry Andric   GetUnsafeInstructions(*OuterLoopHeader);
232*349cc55cSDimitry Andric   GetUnsafeInstructions(*OuterLoopLatch);
233*349cc55cSDimitry Andric   GetUnsafeInstructions(*InnerLoopExitBlock);
234*349cc55cSDimitry Andric 
235*349cc55cSDimitry Andric   if (InnerLoopPreHeader != OuterLoopHeader) {
236*349cc55cSDimitry Andric     GetUnsafeInstructions(*InnerLoopPreHeader);
237*349cc55cSDimitry Andric   }
238*349cc55cSDimitry Andric   return Instr;
2395ffd83dbSDimitry Andric }
2405ffd83dbSDimitry Andric 
2415ffd83dbSDimitry Andric SmallVector<LoopVectorTy, 4>
2425ffd83dbSDimitry Andric LoopNest::getPerfectLoops(ScalarEvolution &SE) const {
2435ffd83dbSDimitry Andric   SmallVector<LoopVectorTy, 4> LV;
2445ffd83dbSDimitry Andric   LoopVectorTy PerfectNest;
2455ffd83dbSDimitry Andric 
2465ffd83dbSDimitry Andric   for (Loop *L : depth_first(const_cast<Loop *>(Loops.front()))) {
2475ffd83dbSDimitry Andric     if (PerfectNest.empty())
2485ffd83dbSDimitry Andric       PerfectNest.push_back(L);
2495ffd83dbSDimitry Andric 
2505ffd83dbSDimitry Andric     auto &SubLoops = L->getSubLoops();
2515ffd83dbSDimitry Andric     if (SubLoops.size() == 1 && arePerfectlyNested(*L, *SubLoops.front(), SE)) {
2525ffd83dbSDimitry Andric       PerfectNest.push_back(SubLoops.front());
2535ffd83dbSDimitry Andric     } else {
2545ffd83dbSDimitry Andric       LV.push_back(PerfectNest);
2555ffd83dbSDimitry Andric       PerfectNest.clear();
2565ffd83dbSDimitry Andric     }
2575ffd83dbSDimitry Andric   }
2585ffd83dbSDimitry Andric 
2595ffd83dbSDimitry Andric   return LV;
2605ffd83dbSDimitry Andric }
2615ffd83dbSDimitry Andric 
2625ffd83dbSDimitry Andric unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) {
2635ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Get maximum perfect depth of loop nest rooted by loop '"
2645ffd83dbSDimitry Andric                     << Root.getName() << "'\n");
2655ffd83dbSDimitry Andric 
2665ffd83dbSDimitry Andric   const Loop *CurrentLoop = &Root;
2675ffd83dbSDimitry Andric   const auto *SubLoops = &CurrentLoop->getSubLoops();
2685ffd83dbSDimitry Andric   unsigned CurrentDepth = 1;
2695ffd83dbSDimitry Andric 
2705ffd83dbSDimitry Andric   while (SubLoops->size() == 1) {
2715ffd83dbSDimitry Andric     const Loop *InnerLoop = SubLoops->front();
2725ffd83dbSDimitry Andric     if (!arePerfectlyNested(*CurrentLoop, *InnerLoop, SE)) {
2735ffd83dbSDimitry Andric       LLVM_DEBUG({
2745ffd83dbSDimitry Andric         dbgs() << "Not a perfect nest: loop '" << CurrentLoop->getName()
2755ffd83dbSDimitry Andric                << "' is not perfectly nested with loop '"
2765ffd83dbSDimitry Andric                << InnerLoop->getName() << "'\n";
2775ffd83dbSDimitry Andric       });
2785ffd83dbSDimitry Andric       break;
2795ffd83dbSDimitry Andric     }
2805ffd83dbSDimitry Andric 
2815ffd83dbSDimitry Andric     CurrentLoop = InnerLoop;
2825ffd83dbSDimitry Andric     SubLoops = &CurrentLoop->getSubLoops();
2835ffd83dbSDimitry Andric     ++CurrentDepth;
2845ffd83dbSDimitry Andric   }
2855ffd83dbSDimitry Andric 
2865ffd83dbSDimitry Andric   return CurrentDepth;
2875ffd83dbSDimitry Andric }
2885ffd83dbSDimitry Andric 
289e8d8bef9SDimitry Andric const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
290fe6060f1SDimitry Andric                                                 const BasicBlock *End,
291fe6060f1SDimitry Andric                                                 bool CheckUniquePred) {
292e8d8bef9SDimitry Andric   assert(From && "Expecting valid From");
293e8d8bef9SDimitry Andric   assert(End && "Expecting valid End");
294e8d8bef9SDimitry Andric 
295fe6060f1SDimitry Andric   if (From == End || !From->getUniqueSuccessor())
296e8d8bef9SDimitry Andric     return *From;
297e8d8bef9SDimitry Andric 
298e8d8bef9SDimitry Andric   auto IsEmpty = [](const BasicBlock *BB) {
299e8d8bef9SDimitry Andric     return (BB->getInstList().size() == 1);
300e8d8bef9SDimitry Andric   };
301e8d8bef9SDimitry Andric 
302e8d8bef9SDimitry Andric   // Visited is used to avoid running into an infinite loop.
303e8d8bef9SDimitry Andric   SmallPtrSet<const BasicBlock *, 4> Visited;
304fe6060f1SDimitry Andric   const BasicBlock *BB = From->getUniqueSuccessor();
305fe6060f1SDimitry Andric   const BasicBlock *PredBB = From;
306fe6060f1SDimitry Andric   while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB) &&
307fe6060f1SDimitry Andric          (!CheckUniquePred || BB->getUniquePredecessor())) {
308e8d8bef9SDimitry Andric     Visited.insert(BB);
309e8d8bef9SDimitry Andric     PredBB = BB;
310fe6060f1SDimitry Andric     BB = BB->getUniqueSuccessor();
311e8d8bef9SDimitry Andric   }
312e8d8bef9SDimitry Andric 
313e8d8bef9SDimitry Andric   return (BB == End) ? *End : *PredBB;
314e8d8bef9SDimitry Andric }
315e8d8bef9SDimitry Andric 
3165ffd83dbSDimitry Andric static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
3175ffd83dbSDimitry Andric                                 ScalarEvolution &SE) {
3185ffd83dbSDimitry Andric   // The inner loop must be the only outer loop's child.
3195ffd83dbSDimitry Andric   if ((OuterLoop.getSubLoops().size() != 1) ||
3205ffd83dbSDimitry Andric       (InnerLoop.getParentLoop() != &OuterLoop))
3215ffd83dbSDimitry Andric     return false;
3225ffd83dbSDimitry Andric 
3235ffd83dbSDimitry Andric   // We expect loops in normal form which have a preheader, header, latch...
3245ffd83dbSDimitry Andric   if (!OuterLoop.isLoopSimplifyForm() || !InnerLoop.isLoopSimplifyForm())
3255ffd83dbSDimitry Andric     return false;
3265ffd83dbSDimitry Andric 
3275ffd83dbSDimitry Andric   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
3285ffd83dbSDimitry Andric   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
3295ffd83dbSDimitry Andric   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
3305ffd83dbSDimitry Andric   const BasicBlock *InnerLoopLatch = InnerLoop.getLoopLatch();
3315ffd83dbSDimitry Andric   const BasicBlock *InnerLoopExit = InnerLoop.getExitBlock();
3325ffd83dbSDimitry Andric 
3335ffd83dbSDimitry Andric   // We expect rotated loops. The inner loop should have a single exit block.
3345ffd83dbSDimitry Andric   if (OuterLoop.getExitingBlock() != OuterLoopLatch ||
3355ffd83dbSDimitry Andric       InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit)
3365ffd83dbSDimitry Andric     return false;
3375ffd83dbSDimitry Andric 
338e8d8bef9SDimitry Andric   // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
339e8d8bef9SDimitry Andric   auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
340e8d8bef9SDimitry Andric     return any_of(ExitBlock.phis(), [](const PHINode &PN) {
341e8d8bef9SDimitry Andric       return PN.getNumIncomingValues() == 1;
342e8d8bef9SDimitry Andric     });
343e8d8bef9SDimitry Andric   };
344e8d8bef9SDimitry Andric 
345e8d8bef9SDimitry Andric   // Returns whether the block `BB` qualifies for being an extra Phi block. The
346e8d8bef9SDimitry Andric   // extra Phi block is the additional block inserted after the exit block of an
347e8d8bef9SDimitry Andric   // "guarded" inner loop which contains "only" Phi nodes corresponding to the
348e8d8bef9SDimitry Andric   // LCSSA Phi nodes in the exit block.
349e8d8bef9SDimitry Andric   auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
350e8d8bef9SDimitry Andric     return BB.getFirstNonPHI() == BB.getTerminator() &&
351e8d8bef9SDimitry Andric            all_of(BB.phis(), [&](const PHINode &PN) {
352e8d8bef9SDimitry Andric              return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
353e8d8bef9SDimitry Andric                return IncomingBlock == InnerLoopExit ||
354e8d8bef9SDimitry Andric                       IncomingBlock == OuterLoopHeader;
355e8d8bef9SDimitry Andric              });
356e8d8bef9SDimitry Andric            });
357e8d8bef9SDimitry Andric   };
358e8d8bef9SDimitry Andric 
359e8d8bef9SDimitry Andric   const BasicBlock *ExtraPhiBlock = nullptr;
3605ffd83dbSDimitry Andric   // Ensure the only branch that may exist between the loops is the inner loop
3615ffd83dbSDimitry Andric   // guard.
3625ffd83dbSDimitry Andric   if (OuterLoopHeader != InnerLoopPreHeader) {
363e8d8bef9SDimitry Andric     const BasicBlock &SingleSucc =
364e8d8bef9SDimitry Andric         LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
365e8d8bef9SDimitry Andric 
366e8d8bef9SDimitry Andric     // no conditional branch present
367e8d8bef9SDimitry Andric     if (&SingleSucc != InnerLoopPreHeader) {
368e8d8bef9SDimitry Andric       const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
3695ffd83dbSDimitry Andric 
3705ffd83dbSDimitry Andric       if (!BI || BI != InnerLoop.getLoopGuardBranch())
3715ffd83dbSDimitry Andric         return false;
3725ffd83dbSDimitry Andric 
373e8d8bef9SDimitry Andric       bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
374e8d8bef9SDimitry Andric 
3755ffd83dbSDimitry Andric       // The successors of the inner loop guard should be the inner loop
376e8d8bef9SDimitry Andric       // preheader or the outer loop latch possibly through empty blocks.
3775ffd83dbSDimitry Andric       for (const BasicBlock *Succ : BI->successors()) {
378e8d8bef9SDimitry Andric         const BasicBlock *PotentialInnerPreHeader = Succ;
379e8d8bef9SDimitry Andric         const BasicBlock *PotentialOuterLatch = Succ;
380e8d8bef9SDimitry Andric 
381e8d8bef9SDimitry Andric         // Ensure the inner loop guard successor is empty before skipping
382e8d8bef9SDimitry Andric         // blocks.
383e8d8bef9SDimitry Andric         if (Succ->getInstList().size() == 1) {
384e8d8bef9SDimitry Andric           PotentialInnerPreHeader =
385e8d8bef9SDimitry Andric               &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
386e8d8bef9SDimitry Andric           PotentialOuterLatch =
387e8d8bef9SDimitry Andric               &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
388e8d8bef9SDimitry Andric         }
389e8d8bef9SDimitry Andric 
390e8d8bef9SDimitry Andric         if (PotentialInnerPreHeader == InnerLoopPreHeader)
3915ffd83dbSDimitry Andric           continue;
392e8d8bef9SDimitry Andric         if (PotentialOuterLatch == OuterLoopLatch)
3935ffd83dbSDimitry Andric           continue;
3945ffd83dbSDimitry Andric 
395e8d8bef9SDimitry Andric         // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
396e8d8bef9SDimitry Andric         // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
397e8d8bef9SDimitry Andric         // loops are still considered perfectly nested if the extra block only
398e8d8bef9SDimitry Andric         // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
399e8d8bef9SDimitry Andric         if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
400e8d8bef9SDimitry Andric             Succ->getSingleSuccessor() == OuterLoopLatch) {
401e8d8bef9SDimitry Andric           // Points to the extra block so that we can reference it later in the
402e8d8bef9SDimitry Andric           // final check. We can also conclude that the inner loop is
403e8d8bef9SDimitry Andric           // guarded and there exists LCSSA Phi node in the exit block later if
404e8d8bef9SDimitry Andric           // we see a non-null `ExtraPhiBlock`.
405e8d8bef9SDimitry Andric           ExtraPhiBlock = Succ;
406e8d8bef9SDimitry Andric           continue;
407e8d8bef9SDimitry Andric         }
408e8d8bef9SDimitry Andric 
4095ffd83dbSDimitry Andric         DEBUG_WITH_TYPE(VerboseDebug, {
4105ffd83dbSDimitry Andric           dbgs() << "Inner loop guard successor " << Succ->getName()
4115ffd83dbSDimitry Andric                  << " doesn't lead to inner loop preheader or "
4125ffd83dbSDimitry Andric                     "outer loop latch.\n";
4135ffd83dbSDimitry Andric         });
4145ffd83dbSDimitry Andric         return false;
4155ffd83dbSDimitry Andric       }
4165ffd83dbSDimitry Andric     }
417e8d8bef9SDimitry Andric   }
4185ffd83dbSDimitry Andric 
419e8d8bef9SDimitry Andric   // Ensure the inner loop exit block lead to the outer loop latch possibly
420e8d8bef9SDimitry Andric   // through empty blocks.
421fe6060f1SDimitry Andric   if ((!ExtraPhiBlock ||
422fe6060f1SDimitry Andric        &LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(),
423fe6060f1SDimitry Andric                                       ExtraPhiBlock) != ExtraPhiBlock) &&
424fe6060f1SDimitry Andric       (&LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(),
425fe6060f1SDimitry Andric                                       OuterLoopLatch) != OuterLoopLatch)) {
4265ffd83dbSDimitry Andric     DEBUG_WITH_TYPE(
4275ffd83dbSDimitry Andric         VerboseDebug,
4285ffd83dbSDimitry Andric         dbgs() << "Inner loop exit block " << *InnerLoopExit
4295ffd83dbSDimitry Andric                << " does not directly lead to the outer loop latch.\n";);
4305ffd83dbSDimitry Andric     return false;
4315ffd83dbSDimitry Andric   }
4325ffd83dbSDimitry Andric 
4335ffd83dbSDimitry Andric   return true;
4345ffd83dbSDimitry Andric }
4355ffd83dbSDimitry Andric 
436e8d8bef9SDimitry Andric AnalysisKey LoopNestAnalysis::Key;
437e8d8bef9SDimitry Andric 
4385ffd83dbSDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) {
4395ffd83dbSDimitry Andric   OS << "IsPerfect=";
4405ffd83dbSDimitry Andric   if (LN.getMaxPerfectDepth() == LN.getNestDepth())
4415ffd83dbSDimitry Andric     OS << "true";
4425ffd83dbSDimitry Andric   else
4435ffd83dbSDimitry Andric     OS << "false";
4445ffd83dbSDimitry Andric   OS << ", Depth=" << LN.getNestDepth();
4455ffd83dbSDimitry Andric   OS << ", OutermostLoop: " << LN.getOutermostLoop().getName();
4465ffd83dbSDimitry Andric   OS << ", Loops: ( ";
4475ffd83dbSDimitry Andric   for (const Loop *L : LN.getLoops())
4485ffd83dbSDimitry Andric     OS << L->getName() << " ";
4495ffd83dbSDimitry Andric   OS << ")";
4505ffd83dbSDimitry Andric 
4515ffd83dbSDimitry Andric   return OS;
4525ffd83dbSDimitry Andric }
4535ffd83dbSDimitry Andric 
4545ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
4555ffd83dbSDimitry Andric // LoopNestPrinterPass implementation
4565ffd83dbSDimitry Andric //
4575ffd83dbSDimitry Andric 
4585ffd83dbSDimitry Andric PreservedAnalyses LoopNestPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
4595ffd83dbSDimitry Andric                                            LoopStandardAnalysisResults &AR,
4605ffd83dbSDimitry Andric                                            LPMUpdater &U) {
4615ffd83dbSDimitry Andric   if (auto LN = LoopNest::getLoopNest(L, AR.SE))
4625ffd83dbSDimitry Andric     OS << *LN << "\n";
4635ffd83dbSDimitry Andric 
4645ffd83dbSDimitry Andric   return PreservedAnalyses::all();
4655ffd83dbSDimitry Andric }
466