1c84532a7SWhitney Tsang //===- LoopNestAnalysis.cpp - Loop Nest Analysis --------------------------==//
2c84532a7SWhitney Tsang //
3c84532a7SWhitney Tsang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c84532a7SWhitney Tsang // See https://llvm.org/LICENSE.txt for license information.
5c84532a7SWhitney Tsang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c84532a7SWhitney Tsang //
7c84532a7SWhitney Tsang //===----------------------------------------------------------------------===//
8c84532a7SWhitney Tsang ///
9c84532a7SWhitney Tsang /// \file
10c84532a7SWhitney Tsang /// The implementation for the loop nest analysis.
11c84532a7SWhitney Tsang ///
12c84532a7SWhitney Tsang //===----------------------------------------------------------------------===//
13c84532a7SWhitney Tsang 
14c84532a7SWhitney Tsang #include "llvm/Analysis/LoopNestAnalysis.h"
15c84532a7SWhitney Tsang #include "llvm/ADT/BreadthFirstIterator.h"
16*71c3a551Sserge-sans-paille #include "llvm/ADT/DepthFirstIterator.h"
17c84532a7SWhitney Tsang #include "llvm/Analysis/ValueTracking.h"
18c84532a7SWhitney Tsang 
19c84532a7SWhitney Tsang using namespace llvm;
20c84532a7SWhitney Tsang 
21c84532a7SWhitney Tsang #define DEBUG_TYPE "loopnest"
22c84532a7SWhitney Tsang #ifndef NDEBUG
23c84532a7SWhitney Tsang static const char *VerboseDebug = DEBUG_TYPE "-verbose";
24c84532a7SWhitney Tsang #endif
25c84532a7SWhitney Tsang 
267ff2768bSTa-Wei Tu /// Determine whether the loops structure violates basic requirements for
277ff2768bSTa-Wei Tu /// perfect nesting:
287ff2768bSTa-Wei Tu ///  - the inner loop should be the outer loop's only child
297ff2768bSTa-Wei Tu ///  - the outer loop header should 'flow' into the inner loop preheader
307ff2768bSTa-Wei Tu ///    or jump around the inner loop to the outer loop latch
317ff2768bSTa-Wei Tu ///  - if the inner loop latch exits the inner loop, it should 'flow' into
327ff2768bSTa-Wei Tu ///    the outer loop latch.
337ff2768bSTa-Wei Tu /// Returns true if the loop structure satisfies the basic requirements and
347ff2768bSTa-Wei Tu /// false otherwise.
357ff2768bSTa-Wei Tu static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
367ff2768bSTa-Wei Tu                                 ScalarEvolution &SE);
377ff2768bSTa-Wei Tu 
38c84532a7SWhitney Tsang //===----------------------------------------------------------------------===//
39c84532a7SWhitney Tsang // LoopNest implementation
40c84532a7SWhitney Tsang //
41c84532a7SWhitney Tsang 
LoopNest(Loop & Root,ScalarEvolution & SE)42c84532a7SWhitney Tsang LoopNest::LoopNest(Loop &Root, ScalarEvolution &SE)
43c84532a7SWhitney Tsang     : MaxPerfectDepth(getMaxPerfectDepth(Root, SE)) {
44a3254904SKazu Hirata   append_range(Loops, breadth_first(&Root));
45c84532a7SWhitney Tsang }
46c84532a7SWhitney Tsang 
getLoopNest(Loop & Root,ScalarEvolution & SE)47c84532a7SWhitney Tsang std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
48c84532a7SWhitney Tsang                                                 ScalarEvolution &SE) {
49c84532a7SWhitney Tsang   return std::make_unique<LoopNest>(Root, SE);
50c84532a7SWhitney Tsang }
51c84532a7SWhitney Tsang 
getOuterLoopLatchCmp(const Loop & OuterLoop)524018d25dSMark Danial static CmpInst *getOuterLoopLatchCmp(const Loop &OuterLoop) {
534018d25dSMark Danial 
544018d25dSMark Danial   const BasicBlock *Latch = OuterLoop.getLoopLatch();
554018d25dSMark Danial   assert(Latch && "Expecting a valid loop latch");
564018d25dSMark Danial 
574018d25dSMark Danial   const BranchInst *BI = dyn_cast<BranchInst>(Latch->getTerminator());
584018d25dSMark Danial   assert(BI && BI->isConditional() &&
594018d25dSMark Danial          "Expecting loop latch terminator to be a branch instruction");
604018d25dSMark Danial 
614018d25dSMark Danial   CmpInst *OuterLoopLatchCmp = dyn_cast<CmpInst>(BI->getCondition());
624018d25dSMark Danial   DEBUG_WITH_TYPE(
634018d25dSMark Danial       VerboseDebug, if (OuterLoopLatchCmp) {
644018d25dSMark Danial         dbgs() << "Outer loop latch compare instruction: " << *OuterLoopLatchCmp
654018d25dSMark Danial                << "\n";
664018d25dSMark Danial       });
674018d25dSMark Danial   return OuterLoopLatchCmp;
684018d25dSMark Danial }
694018d25dSMark Danial 
getInnerLoopGuardCmp(const Loop & InnerLoop)704018d25dSMark Danial static CmpInst *getInnerLoopGuardCmp(const Loop &InnerLoop) {
714018d25dSMark Danial 
724018d25dSMark Danial   BranchInst *InnerGuard = InnerLoop.getLoopGuardBranch();
734018d25dSMark Danial   CmpInst *InnerLoopGuardCmp =
744018d25dSMark Danial       (InnerGuard) ? dyn_cast<CmpInst>(InnerGuard->getCondition()) : nullptr;
754018d25dSMark Danial 
764018d25dSMark Danial   DEBUG_WITH_TYPE(
774018d25dSMark Danial       VerboseDebug, if (InnerLoopGuardCmp) {
784018d25dSMark Danial         dbgs() << "Inner loop guard compare instruction: " << *InnerLoopGuardCmp
794018d25dSMark Danial                << "\n";
804018d25dSMark Danial       });
814018d25dSMark Danial   return InnerLoopGuardCmp;
824018d25dSMark Danial }
834018d25dSMark Danial 
checkSafeInstruction(const Instruction & I,const CmpInst * InnerLoopGuardCmp,const CmpInst * OuterLoopLatchCmp,Optional<Loop::LoopBounds> OuterLoopLB)844018d25dSMark Danial static bool checkSafeInstruction(const Instruction &I,
854018d25dSMark Danial                                  const CmpInst *InnerLoopGuardCmp,
864018d25dSMark Danial                                  const CmpInst *OuterLoopLatchCmp,
874018d25dSMark Danial                                  Optional<Loop::LoopBounds> OuterLoopLB) {
884018d25dSMark Danial 
894018d25dSMark Danial   bool IsAllowed =
904018d25dSMark Danial       isSafeToSpeculativelyExecute(&I) || isa<PHINode>(I) || isa<BranchInst>(I);
914018d25dSMark Danial   if (!IsAllowed)
924018d25dSMark Danial     return false;
934018d25dSMark Danial   // The only binary instruction allowed is the outer loop step instruction,
944018d25dSMark Danial   // the only comparison instructions allowed are the inner loop guard
954018d25dSMark Danial   // compare instruction and the outer loop latch compare instruction.
964018d25dSMark Danial   if ((isa<BinaryOperator>(I) && &I != &OuterLoopLB->getStepInst()) ||
974018d25dSMark Danial       (isa<CmpInst>(I) && &I != OuterLoopLatchCmp && &I != InnerLoopGuardCmp)) {
984018d25dSMark Danial     return false;
994018d25dSMark Danial   }
1004018d25dSMark Danial   return true;
1014018d25dSMark Danial }
1024018d25dSMark Danial 
arePerfectlyNested(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)103c84532a7SWhitney Tsang bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
104c84532a7SWhitney Tsang                                   ScalarEvolution &SE) {
1054018d25dSMark Danial   return (analyzeLoopNestForPerfectNest(OuterLoop, InnerLoop, SE) ==
1064018d25dSMark Danial           PerfectLoopNest);
1074018d25dSMark Danial }
1084018d25dSMark Danial 
analyzeLoopNestForPerfectNest(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)1094018d25dSMark Danial LoopNest::LoopNestEnum LoopNest::analyzeLoopNestForPerfectNest(
1104018d25dSMark Danial     const Loop &OuterLoop, const Loop &InnerLoop, ScalarEvolution &SE) {
1114018d25dSMark Danial 
11289c1e35fSStefanos Baziotis   assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
11389c1e35fSStefanos Baziotis   assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
114c84532a7SWhitney Tsang   LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName()
115c84532a7SWhitney Tsang                     << "' and '" << InnerLoop.getName()
116c84532a7SWhitney Tsang                     << "' are perfectly nested.\n");
117c84532a7SWhitney Tsang 
118c84532a7SWhitney Tsang   // Determine whether the loops structure satisfies the following requirements:
119c84532a7SWhitney Tsang   //  - the inner loop should be the outer loop's only child
120c84532a7SWhitney Tsang   //  - the outer loop header should 'flow' into the inner loop preheader
121c84532a7SWhitney Tsang   //    or jump around the inner loop to the outer loop latch
122c84532a7SWhitney Tsang   //  - if the inner loop latch exits the inner loop, it should 'flow' into
123c84532a7SWhitney Tsang   //    the outer loop latch.
124c84532a7SWhitney Tsang   if (!checkLoopsStructure(OuterLoop, InnerLoop, SE)) {
125c84532a7SWhitney Tsang     LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure.\n");
1264018d25dSMark Danial     return InvalidLoopStructure;
127c84532a7SWhitney Tsang   }
128c84532a7SWhitney Tsang 
129c84532a7SWhitney Tsang   // Bail out if we cannot retrieve the outer loop bounds.
130c84532a7SWhitney Tsang   auto OuterLoopLB = OuterLoop.getBounds(SE);
131c84532a7SWhitney Tsang   if (OuterLoopLB == None) {
132c84532a7SWhitney Tsang     LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: "
133c84532a7SWhitney Tsang                       << OuterLoop << "\n";);
1344018d25dSMark Danial     return OuterLoopLowerBoundUnknown;
135c84532a7SWhitney Tsang   }
136c84532a7SWhitney Tsang 
1374018d25dSMark Danial   CmpInst *OuterLoopLatchCmp = getOuterLoopLatchCmp(OuterLoop);
1384018d25dSMark Danial   CmpInst *InnerLoopGuardCmp = getInnerLoopGuardCmp(InnerLoop);
139c84532a7SWhitney Tsang 
140c84532a7SWhitney Tsang   // Determine whether instructions in a basic block are one of:
141c84532a7SWhitney Tsang   //  - the inner loop guard comparison
142c84532a7SWhitney Tsang   //  - the outer loop latch comparison
143c84532a7SWhitney Tsang   //  - the outer loop induction variable increment
144c84532a7SWhitney Tsang   //  - a phi node, a cast or a branch
145c84532a7SWhitney Tsang   auto containsOnlySafeInstructions = [&](const BasicBlock &BB) {
146c84532a7SWhitney Tsang     return llvm::all_of(BB, [&](const Instruction &I) {
1474018d25dSMark Danial       bool IsSafeInstr = checkSafeInstruction(I, InnerLoopGuardCmp,
1484018d25dSMark Danial                                               OuterLoopLatchCmp, OuterLoopLB);
1494018d25dSMark Danial       if (IsSafeInstr) {
150c84532a7SWhitney Tsang         DEBUG_WITH_TYPE(VerboseDebug, {
151c84532a7SWhitney Tsang           dbgs() << "Instruction: " << I << "\nin basic block:" << BB
152c84532a7SWhitney Tsang                  << "is unsafe.\n";
153c84532a7SWhitney Tsang         });
154c84532a7SWhitney Tsang       }
1554018d25dSMark Danial       return IsSafeInstr;
156c84532a7SWhitney Tsang     });
157c84532a7SWhitney Tsang   };
158c84532a7SWhitney Tsang 
159c84532a7SWhitney Tsang   // Check the code surrounding the inner loop for instructions that are deemed
160c84532a7SWhitney Tsang   // unsafe.
161c84532a7SWhitney Tsang   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
162c84532a7SWhitney Tsang   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
163c84532a7SWhitney Tsang   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
164c84532a7SWhitney Tsang 
165c84532a7SWhitney Tsang   if (!containsOnlySafeInstructions(*OuterLoopHeader) ||
166c84532a7SWhitney Tsang       !containsOnlySafeInstructions(*OuterLoopLatch) ||
167c84532a7SWhitney Tsang       (InnerLoopPreHeader != OuterLoopHeader &&
168c84532a7SWhitney Tsang        !containsOnlySafeInstructions(*InnerLoopPreHeader)) ||
169c84532a7SWhitney Tsang       !containsOnlySafeInstructions(*InnerLoop.getExitBlock())) {
170c84532a7SWhitney Tsang     LLVM_DEBUG(dbgs() << "Not perfectly nested: code surrounding inner loop is "
171c84532a7SWhitney Tsang                          "unsafe\n";);
1724018d25dSMark Danial     return ImperfectLoopNest;
173c84532a7SWhitney Tsang   }
174c84532a7SWhitney Tsang 
175c84532a7SWhitney Tsang   LLVM_DEBUG(dbgs() << "Loop '" << OuterLoop.getName() << "' and '"
176c84532a7SWhitney Tsang                     << InnerLoop.getName() << "' are perfectly nested.\n");
177c84532a7SWhitney Tsang 
1784018d25dSMark Danial   return PerfectLoopNest;
1794018d25dSMark Danial }
1804018d25dSMark Danial 
getInterveningInstructions(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)1814018d25dSMark Danial LoopNest::InstrVectorTy LoopNest::getInterveningInstructions(
1824018d25dSMark Danial     const Loop &OuterLoop, const Loop &InnerLoop, ScalarEvolution &SE) {
1834018d25dSMark Danial   InstrVectorTy Instr;
1844018d25dSMark Danial   switch (analyzeLoopNestForPerfectNest(OuterLoop, InnerLoop, SE)) {
1854018d25dSMark Danial   case PerfectLoopNest:
1864018d25dSMark Danial     LLVM_DEBUG(dbgs() << "The loop Nest is Perfect, returning empty "
1874018d25dSMark Danial                          "instruction vector. \n";);
1884018d25dSMark Danial     return Instr;
1894018d25dSMark Danial 
1904018d25dSMark Danial   case InvalidLoopStructure:
1914018d25dSMark Danial     LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure. "
1924018d25dSMark Danial                          "Instruction vector is empty.\n";);
1934018d25dSMark Danial     return Instr;
1944018d25dSMark Danial 
1954018d25dSMark Danial   case OuterLoopLowerBoundUnknown:
1964018d25dSMark Danial     LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: "
1974018d25dSMark Danial                       << OuterLoop << "\nInstruction vector is empty.\n";);
1984018d25dSMark Danial     return Instr;
1994018d25dSMark Danial 
2004018d25dSMark Danial   case ImperfectLoopNest:
2014018d25dSMark Danial     break;
2024018d25dSMark Danial   }
2034018d25dSMark Danial 
2044018d25dSMark Danial   // Identify the outer loop latch comparison instruction.
2054018d25dSMark Danial   auto OuterLoopLB = OuterLoop.getBounds(SE);
2064018d25dSMark Danial 
2074018d25dSMark Danial   CmpInst *OuterLoopLatchCmp = getOuterLoopLatchCmp(OuterLoop);
2084018d25dSMark Danial   CmpInst *InnerLoopGuardCmp = getInnerLoopGuardCmp(InnerLoop);
2094018d25dSMark Danial 
2104018d25dSMark Danial   auto GetUnsafeInstructions = [&](const BasicBlock &BB) {
2114018d25dSMark Danial     for (const Instruction &I : BB) {
2124018d25dSMark Danial       if (!checkSafeInstruction(I, InnerLoopGuardCmp, OuterLoopLatchCmp,
2134018d25dSMark Danial                                 OuterLoopLB)) {
2144018d25dSMark Danial         Instr.push_back(&I);
2154018d25dSMark Danial         DEBUG_WITH_TYPE(VerboseDebug, {
2164018d25dSMark Danial           dbgs() << "Instruction: " << I << "\nin basic block:" << BB
2174018d25dSMark Danial                  << "is unsafe.\n";
2184018d25dSMark Danial         });
2194018d25dSMark Danial       }
2204018d25dSMark Danial     }
2214018d25dSMark Danial   };
2224018d25dSMark Danial 
2234018d25dSMark Danial   // Check the code surrounding the inner loop for instructions that are deemed
2244018d25dSMark Danial   // unsafe.
2254018d25dSMark Danial   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
2264018d25dSMark Danial   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
2274018d25dSMark Danial   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
2284018d25dSMark Danial   const BasicBlock *InnerLoopExitBlock = InnerLoop.getExitBlock();
2294018d25dSMark Danial 
2304018d25dSMark Danial   GetUnsafeInstructions(*OuterLoopHeader);
2314018d25dSMark Danial   GetUnsafeInstructions(*OuterLoopLatch);
2324018d25dSMark Danial   GetUnsafeInstructions(*InnerLoopExitBlock);
2334018d25dSMark Danial 
2344018d25dSMark Danial   if (InnerLoopPreHeader != OuterLoopHeader) {
2354018d25dSMark Danial     GetUnsafeInstructions(*InnerLoopPreHeader);
2364018d25dSMark Danial   }
2374018d25dSMark Danial   return Instr;
238c84532a7SWhitney Tsang }
239c84532a7SWhitney Tsang 
240c84532a7SWhitney Tsang SmallVector<LoopVectorTy, 4>
getPerfectLoops(ScalarEvolution & SE) const241c84532a7SWhitney Tsang LoopNest::getPerfectLoops(ScalarEvolution &SE) const {
242c84532a7SWhitney Tsang   SmallVector<LoopVectorTy, 4> LV;
243c84532a7SWhitney Tsang   LoopVectorTy PerfectNest;
244c84532a7SWhitney Tsang 
245c84532a7SWhitney Tsang   for (Loop *L : depth_first(const_cast<Loop *>(Loops.front()))) {
246c84532a7SWhitney Tsang     if (PerfectNest.empty())
247c84532a7SWhitney Tsang       PerfectNest.push_back(L);
248c84532a7SWhitney Tsang 
249c84532a7SWhitney Tsang     auto &SubLoops = L->getSubLoops();
250c84532a7SWhitney Tsang     if (SubLoops.size() == 1 && arePerfectlyNested(*L, *SubLoops.front(), SE)) {
251c84532a7SWhitney Tsang       PerfectNest.push_back(SubLoops.front());
252c84532a7SWhitney Tsang     } else {
253c84532a7SWhitney Tsang       LV.push_back(PerfectNest);
254c84532a7SWhitney Tsang       PerfectNest.clear();
255c84532a7SWhitney Tsang     }
256c84532a7SWhitney Tsang   }
257c84532a7SWhitney Tsang 
258c84532a7SWhitney Tsang   return LV;
259c84532a7SWhitney Tsang }
260c84532a7SWhitney Tsang 
getMaxPerfectDepth(const Loop & Root,ScalarEvolution & SE)261c84532a7SWhitney Tsang unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) {
262c84532a7SWhitney Tsang   LLVM_DEBUG(dbgs() << "Get maximum perfect depth of loop nest rooted by loop '"
263c84532a7SWhitney Tsang                     << Root.getName() << "'\n");
264c84532a7SWhitney Tsang 
265c84532a7SWhitney Tsang   const Loop *CurrentLoop = &Root;
266c84532a7SWhitney Tsang   const auto *SubLoops = &CurrentLoop->getSubLoops();
267c84532a7SWhitney Tsang   unsigned CurrentDepth = 1;
268c84532a7SWhitney Tsang 
269c84532a7SWhitney Tsang   while (SubLoops->size() == 1) {
270c84532a7SWhitney Tsang     const Loop *InnerLoop = SubLoops->front();
271c84532a7SWhitney Tsang     if (!arePerfectlyNested(*CurrentLoop, *InnerLoop, SE)) {
272c84532a7SWhitney Tsang       LLVM_DEBUG({
273c84532a7SWhitney Tsang         dbgs() << "Not a perfect nest: loop '" << CurrentLoop->getName()
274c84532a7SWhitney Tsang                << "' is not perfectly nested with loop '"
275c84532a7SWhitney Tsang                << InnerLoop->getName() << "'\n";
276c84532a7SWhitney Tsang       });
277c84532a7SWhitney Tsang       break;
278c84532a7SWhitney Tsang     }
279c84532a7SWhitney Tsang 
280c84532a7SWhitney Tsang     CurrentLoop = InnerLoop;
281c84532a7SWhitney Tsang     SubLoops = &CurrentLoop->getSubLoops();
282c84532a7SWhitney Tsang     ++CurrentDepth;
283c84532a7SWhitney Tsang   }
284c84532a7SWhitney Tsang 
285c84532a7SWhitney Tsang   return CurrentDepth;
286c84532a7SWhitney Tsang }
287c84532a7SWhitney Tsang 
skipEmptyBlockUntil(const BasicBlock * From,const BasicBlock * End,bool CheckUniquePred)288c0055189SWhitney Tsang const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
2891006ac39SWhitney Tsang                                                 const BasicBlock *End,
2901006ac39SWhitney Tsang                                                 bool CheckUniquePred) {
291c0055189SWhitney Tsang   assert(From && "Expecting valid From");
292c0055189SWhitney Tsang   assert(End && "Expecting valid End");
293c0055189SWhitney Tsang 
29498c6110dSTa-Wei Tu   if (From == End || !From->getUniqueSuccessor())
295c0055189SWhitney Tsang     return *From;
296c0055189SWhitney Tsang 
297c0055189SWhitney Tsang   auto IsEmpty = [](const BasicBlock *BB) {
298c0055189SWhitney Tsang     return (BB->getInstList().size() == 1);
299c0055189SWhitney Tsang   };
300c0055189SWhitney Tsang 
301c0055189SWhitney Tsang   // Visited is used to avoid running into an infinite loop.
302c0055189SWhitney Tsang   SmallPtrSet<const BasicBlock *, 4> Visited;
30398c6110dSTa-Wei Tu   const BasicBlock *BB = From->getUniqueSuccessor();
3041006ac39SWhitney Tsang   const BasicBlock *PredBB = From;
3051006ac39SWhitney Tsang   while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB) &&
3061006ac39SWhitney Tsang          (!CheckUniquePred || BB->getUniquePredecessor())) {
307c0055189SWhitney Tsang     Visited.insert(BB);
308c0055189SWhitney Tsang     PredBB = BB;
30998c6110dSTa-Wei Tu     BB = BB->getUniqueSuccessor();
310c0055189SWhitney Tsang   }
311c0055189SWhitney Tsang 
312c0055189SWhitney Tsang   return (BB == End) ? *End : *PredBB;
313c0055189SWhitney Tsang }
314c0055189SWhitney Tsang 
checkLoopsStructure(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)3157ff2768bSTa-Wei Tu static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
316c84532a7SWhitney Tsang                                 ScalarEvolution &SE) {
317c84532a7SWhitney Tsang   // The inner loop must be the only outer loop's child.
318c84532a7SWhitney Tsang   if ((OuterLoop.getSubLoops().size() != 1) ||
319c84532a7SWhitney Tsang       (InnerLoop.getParentLoop() != &OuterLoop))
320c84532a7SWhitney Tsang     return false;
321c84532a7SWhitney Tsang 
322c84532a7SWhitney Tsang   // We expect loops in normal form which have a preheader, header, latch...
323c84532a7SWhitney Tsang   if (!OuterLoop.isLoopSimplifyForm() || !InnerLoop.isLoopSimplifyForm())
324c84532a7SWhitney Tsang     return false;
325c84532a7SWhitney Tsang 
326c84532a7SWhitney Tsang   const BasicBlock *OuterLoopHeader = OuterLoop.getHeader();
327c84532a7SWhitney Tsang   const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch();
328c84532a7SWhitney Tsang   const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader();
329c84532a7SWhitney Tsang   const BasicBlock *InnerLoopLatch = InnerLoop.getLoopLatch();
330c84532a7SWhitney Tsang   const BasicBlock *InnerLoopExit = InnerLoop.getExitBlock();
331c84532a7SWhitney Tsang 
332c84532a7SWhitney Tsang   // We expect rotated loops. The inner loop should have a single exit block.
333c84532a7SWhitney Tsang   if (OuterLoop.getExitingBlock() != OuterLoopLatch ||
334c84532a7SWhitney Tsang       InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit)
335c84532a7SWhitney Tsang     return false;
336c84532a7SWhitney Tsang 
337abbd652dSTa-Wei Tu   // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
338abbd652dSTa-Wei Tu   auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
339abbd652dSTa-Wei Tu     return any_of(ExitBlock.phis(), [](const PHINode &PN) {
340abbd652dSTa-Wei Tu       return PN.getNumIncomingValues() == 1;
341abbd652dSTa-Wei Tu     });
342abbd652dSTa-Wei Tu   };
343abbd652dSTa-Wei Tu 
344abbd652dSTa-Wei Tu   // Returns whether the block `BB` qualifies for being an extra Phi block. The
345abbd652dSTa-Wei Tu   // extra Phi block is the additional block inserted after the exit block of an
346abbd652dSTa-Wei Tu   // "guarded" inner loop which contains "only" Phi nodes corresponding to the
347abbd652dSTa-Wei Tu   // LCSSA Phi nodes in the exit block.
348abbd652dSTa-Wei Tu   auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
349abbd652dSTa-Wei Tu     return BB.getFirstNonPHI() == BB.getTerminator() &&
350abbd652dSTa-Wei Tu            all_of(BB.phis(), [&](const PHINode &PN) {
351abbd652dSTa-Wei Tu              return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
352abbd652dSTa-Wei Tu                return IncomingBlock == InnerLoopExit ||
353abbd652dSTa-Wei Tu                       IncomingBlock == OuterLoopHeader;
354abbd652dSTa-Wei Tu              });
355abbd652dSTa-Wei Tu            });
356abbd652dSTa-Wei Tu   };
357abbd652dSTa-Wei Tu 
358abbd652dSTa-Wei Tu   const BasicBlock *ExtraPhiBlock = nullptr;
359c84532a7SWhitney Tsang   // Ensure the only branch that may exist between the loops is the inner loop
360c84532a7SWhitney Tsang   // guard.
361c84532a7SWhitney Tsang   if (OuterLoopHeader != InnerLoopPreHeader) {
362c0055189SWhitney Tsang     const BasicBlock &SingleSucc =
363c0055189SWhitney Tsang         LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
364c0055189SWhitney Tsang 
365c0055189SWhitney Tsang     // no conditional branch present
366c0055189SWhitney Tsang     if (&SingleSucc != InnerLoopPreHeader) {
367c0055189SWhitney Tsang       const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
368c84532a7SWhitney Tsang 
369c84532a7SWhitney Tsang       if (!BI || BI != InnerLoop.getLoopGuardBranch())
370c84532a7SWhitney Tsang         return false;
371c84532a7SWhitney Tsang 
372abbd652dSTa-Wei Tu       bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
373abbd652dSTa-Wei Tu 
374c84532a7SWhitney Tsang       // The successors of the inner loop guard should be the inner loop
375c0055189SWhitney Tsang       // preheader or the outer loop latch possibly through empty blocks.
376c84532a7SWhitney Tsang       for (const BasicBlock *Succ : BI->successors()) {
377c0055189SWhitney Tsang         const BasicBlock *PotentialInnerPreHeader = Succ;
378c0055189SWhitney Tsang         const BasicBlock *PotentialOuterLatch = Succ;
379c0055189SWhitney Tsang 
380c0055189SWhitney Tsang         // Ensure the inner loop guard successor is empty before skipping
381c0055189SWhitney Tsang         // blocks.
382c0055189SWhitney Tsang         if (Succ->getInstList().size() == 1) {
383c0055189SWhitney Tsang           PotentialInnerPreHeader =
384c0055189SWhitney Tsang               &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
385c0055189SWhitney Tsang           PotentialOuterLatch =
386c0055189SWhitney Tsang               &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
387c0055189SWhitney Tsang         }
388c0055189SWhitney Tsang 
389c0055189SWhitney Tsang         if (PotentialInnerPreHeader == InnerLoopPreHeader)
390c84532a7SWhitney Tsang           continue;
391c0055189SWhitney Tsang         if (PotentialOuterLatch == OuterLoopLatch)
392c84532a7SWhitney Tsang           continue;
393c84532a7SWhitney Tsang 
394abbd652dSTa-Wei Tu         // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
395abbd652dSTa-Wei Tu         // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
396abbd652dSTa-Wei Tu         // loops are still considered perfectly nested if the extra block only
397abbd652dSTa-Wei Tu         // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
398abbd652dSTa-Wei Tu         if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
399abbd652dSTa-Wei Tu             Succ->getSingleSuccessor() == OuterLoopLatch) {
400abbd652dSTa-Wei Tu           // Points to the extra block so that we can reference it later in the
401abbd652dSTa-Wei Tu           // final check. We can also conclude that the inner loop is
402c0055189SWhitney Tsang           // guarded and there exists LCSSA Phi node in the exit block later if
403c0055189SWhitney Tsang           // we see a non-null `ExtraPhiBlock`.
404abbd652dSTa-Wei Tu           ExtraPhiBlock = Succ;
405abbd652dSTa-Wei Tu           continue;
406abbd652dSTa-Wei Tu         }
407abbd652dSTa-Wei Tu 
408c84532a7SWhitney Tsang         DEBUG_WITH_TYPE(VerboseDebug, {
409c84532a7SWhitney Tsang           dbgs() << "Inner loop guard successor " << Succ->getName()
410c84532a7SWhitney Tsang                  << " doesn't lead to inner loop preheader or "
411c84532a7SWhitney Tsang                     "outer loop latch.\n";
412c84532a7SWhitney Tsang         });
413c84532a7SWhitney Tsang         return false;
414c84532a7SWhitney Tsang       }
415c84532a7SWhitney Tsang     }
416c0055189SWhitney Tsang   }
417c84532a7SWhitney Tsang 
418c0055189SWhitney Tsang   // Ensure the inner loop exit block lead to the outer loop latch possibly
419c0055189SWhitney Tsang   // through empty blocks.
4201006ac39SWhitney Tsang   if ((!ExtraPhiBlock ||
4211006ac39SWhitney Tsang        &LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(),
4221006ac39SWhitney Tsang                                       ExtraPhiBlock) != ExtraPhiBlock) &&
4231006ac39SWhitney Tsang       (&LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(),
4241006ac39SWhitney Tsang                                       OuterLoopLatch) != OuterLoopLatch)) {
425c84532a7SWhitney Tsang     DEBUG_WITH_TYPE(
426c84532a7SWhitney Tsang         VerboseDebug,
427c84532a7SWhitney Tsang         dbgs() << "Inner loop exit block " << *InnerLoopExit
428c84532a7SWhitney Tsang                << " does not directly lead to the outer loop latch.\n";);
429c84532a7SWhitney Tsang     return false;
430c84532a7SWhitney Tsang   }
431c84532a7SWhitney Tsang 
432c84532a7SWhitney Tsang   return true;
433c84532a7SWhitney Tsang }
434c84532a7SWhitney Tsang 
435fa3693adSWhitney Tsang AnalysisKey LoopNestAnalysis::Key;
436fa3693adSWhitney Tsang 
operator <<(raw_ostream & OS,const LoopNest & LN)437c84532a7SWhitney Tsang raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) {
438c84532a7SWhitney Tsang   OS << "IsPerfect=";
439c84532a7SWhitney Tsang   if (LN.getMaxPerfectDepth() == LN.getNestDepth())
440c84532a7SWhitney Tsang     OS << "true";
441c84532a7SWhitney Tsang   else
442c84532a7SWhitney Tsang     OS << "false";
443c84532a7SWhitney Tsang   OS << ", Depth=" << LN.getNestDepth();
444c84532a7SWhitney Tsang   OS << ", OutermostLoop: " << LN.getOutermostLoop().getName();
445c84532a7SWhitney Tsang   OS << ", Loops: ( ";
446c84532a7SWhitney Tsang   for (const Loop *L : LN.getLoops())
447c84532a7SWhitney Tsang     OS << L->getName() << " ";
448c84532a7SWhitney Tsang   OS << ")";
449c84532a7SWhitney Tsang 
450c84532a7SWhitney Tsang   return OS;
451c84532a7SWhitney Tsang }
452c84532a7SWhitney Tsang 
453c84532a7SWhitney Tsang //===----------------------------------------------------------------------===//
454c84532a7SWhitney Tsang // LoopNestPrinterPass implementation
455c84532a7SWhitney Tsang //
456c84532a7SWhitney Tsang 
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)457c84532a7SWhitney Tsang PreservedAnalyses LoopNestPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
458c84532a7SWhitney Tsang                                            LoopStandardAnalysisResults &AR,
459c84532a7SWhitney Tsang                                            LPMUpdater &U) {
460c84532a7SWhitney Tsang   if (auto LN = LoopNest::getLoopNest(L, AR.SE))
461c84532a7SWhitney Tsang     OS << *LN << "\n";
462c84532a7SWhitney Tsang 
463c84532a7SWhitney Tsang   return PreservedAnalyses::all();
464c84532a7SWhitney Tsang }
465