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" 16*81ad6265SDimitry Andric #include "llvm/ADT/DepthFirstIterator.h" 175ffd83dbSDimitry Andric #include "llvm/Analysis/ValueTracking.h" 185ffd83dbSDimitry Andric 195ffd83dbSDimitry Andric using namespace llvm; 205ffd83dbSDimitry Andric 215ffd83dbSDimitry Andric #define DEBUG_TYPE "loopnest" 225ffd83dbSDimitry Andric #ifndef NDEBUG 235ffd83dbSDimitry Andric static const char *VerboseDebug = DEBUG_TYPE "-verbose"; 245ffd83dbSDimitry Andric #endif 255ffd83dbSDimitry Andric 265ffd83dbSDimitry Andric /// Determine whether the loops structure violates basic requirements for 275ffd83dbSDimitry Andric /// perfect nesting: 285ffd83dbSDimitry Andric /// - the inner loop should be the outer loop's only child 295ffd83dbSDimitry Andric /// - the outer loop header should 'flow' into the inner loop preheader 305ffd83dbSDimitry Andric /// or jump around the inner loop to the outer loop latch 315ffd83dbSDimitry Andric /// - if the inner loop latch exits the inner loop, it should 'flow' into 325ffd83dbSDimitry Andric /// the outer loop latch. 335ffd83dbSDimitry Andric /// Returns true if the loop structure satisfies the basic requirements and 345ffd83dbSDimitry Andric /// false otherwise. 355ffd83dbSDimitry Andric static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, 365ffd83dbSDimitry Andric ScalarEvolution &SE); 375ffd83dbSDimitry Andric 385ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 395ffd83dbSDimitry Andric // LoopNest implementation 405ffd83dbSDimitry Andric // 415ffd83dbSDimitry Andric 425ffd83dbSDimitry Andric LoopNest::LoopNest(Loop &Root, ScalarEvolution &SE) 435ffd83dbSDimitry Andric : MaxPerfectDepth(getMaxPerfectDepth(Root, SE)) { 44e8d8bef9SDimitry Andric append_range(Loops, breadth_first(&Root)); 455ffd83dbSDimitry Andric } 465ffd83dbSDimitry Andric 475ffd83dbSDimitry Andric std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root, 485ffd83dbSDimitry Andric ScalarEvolution &SE) { 495ffd83dbSDimitry Andric return std::make_unique<LoopNest>(Root, SE); 505ffd83dbSDimitry Andric } 515ffd83dbSDimitry Andric 52349cc55cSDimitry Andric static CmpInst *getOuterLoopLatchCmp(const Loop &OuterLoop) { 53349cc55cSDimitry Andric 54349cc55cSDimitry Andric const BasicBlock *Latch = OuterLoop.getLoopLatch(); 55349cc55cSDimitry Andric assert(Latch && "Expecting a valid loop latch"); 56349cc55cSDimitry Andric 57349cc55cSDimitry Andric const BranchInst *BI = dyn_cast<BranchInst>(Latch->getTerminator()); 58349cc55cSDimitry Andric assert(BI && BI->isConditional() && 59349cc55cSDimitry Andric "Expecting loop latch terminator to be a branch instruction"); 60349cc55cSDimitry Andric 61349cc55cSDimitry Andric CmpInst *OuterLoopLatchCmp = dyn_cast<CmpInst>(BI->getCondition()); 62349cc55cSDimitry Andric DEBUG_WITH_TYPE( 63349cc55cSDimitry Andric VerboseDebug, if (OuterLoopLatchCmp) { 64349cc55cSDimitry Andric dbgs() << "Outer loop latch compare instruction: " << *OuterLoopLatchCmp 65349cc55cSDimitry Andric << "\n"; 66349cc55cSDimitry Andric }); 67349cc55cSDimitry Andric return OuterLoopLatchCmp; 68349cc55cSDimitry Andric } 69349cc55cSDimitry Andric 70349cc55cSDimitry Andric static CmpInst *getInnerLoopGuardCmp(const Loop &InnerLoop) { 71349cc55cSDimitry Andric 72349cc55cSDimitry Andric BranchInst *InnerGuard = InnerLoop.getLoopGuardBranch(); 73349cc55cSDimitry Andric CmpInst *InnerLoopGuardCmp = 74349cc55cSDimitry Andric (InnerGuard) ? dyn_cast<CmpInst>(InnerGuard->getCondition()) : nullptr; 75349cc55cSDimitry Andric 76349cc55cSDimitry Andric DEBUG_WITH_TYPE( 77349cc55cSDimitry Andric VerboseDebug, if (InnerLoopGuardCmp) { 78349cc55cSDimitry Andric dbgs() << "Inner loop guard compare instruction: " << *InnerLoopGuardCmp 79349cc55cSDimitry Andric << "\n"; 80349cc55cSDimitry Andric }); 81349cc55cSDimitry Andric return InnerLoopGuardCmp; 82349cc55cSDimitry Andric } 83349cc55cSDimitry Andric 84349cc55cSDimitry Andric static bool checkSafeInstruction(const Instruction &I, 85349cc55cSDimitry Andric const CmpInst *InnerLoopGuardCmp, 86349cc55cSDimitry Andric const CmpInst *OuterLoopLatchCmp, 87349cc55cSDimitry Andric Optional<Loop::LoopBounds> OuterLoopLB) { 88349cc55cSDimitry Andric 89349cc55cSDimitry Andric bool IsAllowed = 90349cc55cSDimitry Andric isSafeToSpeculativelyExecute(&I) || isa<PHINode>(I) || isa<BranchInst>(I); 91349cc55cSDimitry Andric if (!IsAllowed) 92349cc55cSDimitry Andric return false; 93349cc55cSDimitry Andric // The only binary instruction allowed is the outer loop step instruction, 94349cc55cSDimitry Andric // the only comparison instructions allowed are the inner loop guard 95349cc55cSDimitry Andric // compare instruction and the outer loop latch compare instruction. 96349cc55cSDimitry Andric if ((isa<BinaryOperator>(I) && &I != &OuterLoopLB->getStepInst()) || 97349cc55cSDimitry Andric (isa<CmpInst>(I) && &I != OuterLoopLatchCmp && &I != InnerLoopGuardCmp)) { 98349cc55cSDimitry Andric return false; 99349cc55cSDimitry Andric } 100349cc55cSDimitry Andric return true; 101349cc55cSDimitry Andric } 102349cc55cSDimitry Andric 1035ffd83dbSDimitry Andric bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop, 1045ffd83dbSDimitry Andric ScalarEvolution &SE) { 105349cc55cSDimitry Andric return (analyzeLoopNestForPerfectNest(OuterLoop, InnerLoop, SE) == 106349cc55cSDimitry Andric PerfectLoopNest); 107349cc55cSDimitry Andric } 108349cc55cSDimitry Andric 109349cc55cSDimitry Andric LoopNest::LoopNestEnum LoopNest::analyzeLoopNestForPerfectNest( 110349cc55cSDimitry Andric const Loop &OuterLoop, const Loop &InnerLoop, ScalarEvolution &SE) { 111349cc55cSDimitry Andric 112e8d8bef9SDimitry Andric assert(!OuterLoop.isInnermost() && "Outer loop should have subloops"); 113e8d8bef9SDimitry Andric assert(!InnerLoop.isOutermost() && "Inner loop should have a parent"); 1145ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName() 1155ffd83dbSDimitry Andric << "' and '" << InnerLoop.getName() 1165ffd83dbSDimitry Andric << "' are perfectly nested.\n"); 1175ffd83dbSDimitry Andric 1185ffd83dbSDimitry Andric // Determine whether the loops structure satisfies the following requirements: 1195ffd83dbSDimitry Andric // - the inner loop should be the outer loop's only child 1205ffd83dbSDimitry Andric // - the outer loop header should 'flow' into the inner loop preheader 1215ffd83dbSDimitry Andric // or jump around the inner loop to the outer loop latch 1225ffd83dbSDimitry Andric // - if the inner loop latch exits the inner loop, it should 'flow' into 1235ffd83dbSDimitry Andric // the outer loop latch. 1245ffd83dbSDimitry Andric if (!checkLoopsStructure(OuterLoop, InnerLoop, SE)) { 1255ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure.\n"); 126349cc55cSDimitry Andric return InvalidLoopStructure; 1275ffd83dbSDimitry Andric } 1285ffd83dbSDimitry Andric 1295ffd83dbSDimitry Andric // Bail out if we cannot retrieve the outer loop bounds. 1305ffd83dbSDimitry Andric auto OuterLoopLB = OuterLoop.getBounds(SE); 1315ffd83dbSDimitry Andric if (OuterLoopLB == None) { 1325ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: " 1335ffd83dbSDimitry Andric << OuterLoop << "\n";); 134349cc55cSDimitry Andric return OuterLoopLowerBoundUnknown; 1355ffd83dbSDimitry Andric } 1365ffd83dbSDimitry Andric 137349cc55cSDimitry Andric CmpInst *OuterLoopLatchCmp = getOuterLoopLatchCmp(OuterLoop); 138349cc55cSDimitry Andric CmpInst *InnerLoopGuardCmp = getInnerLoopGuardCmp(InnerLoop); 1395ffd83dbSDimitry Andric 1405ffd83dbSDimitry Andric // Determine whether instructions in a basic block are one of: 1415ffd83dbSDimitry Andric // - the inner loop guard comparison 1425ffd83dbSDimitry Andric // - the outer loop latch comparison 1435ffd83dbSDimitry Andric // - the outer loop induction variable increment 1445ffd83dbSDimitry Andric // - a phi node, a cast or a branch 1455ffd83dbSDimitry Andric auto containsOnlySafeInstructions = [&](const BasicBlock &BB) { 1465ffd83dbSDimitry Andric return llvm::all_of(BB, [&](const Instruction &I) { 147349cc55cSDimitry Andric bool IsSafeInstr = checkSafeInstruction(I, InnerLoopGuardCmp, 148349cc55cSDimitry Andric OuterLoopLatchCmp, OuterLoopLB); 149349cc55cSDimitry Andric if (IsSafeInstr) { 1505ffd83dbSDimitry Andric DEBUG_WITH_TYPE(VerboseDebug, { 1515ffd83dbSDimitry Andric dbgs() << "Instruction: " << I << "\nin basic block:" << BB 1525ffd83dbSDimitry Andric << "is unsafe.\n"; 1535ffd83dbSDimitry Andric }); 1545ffd83dbSDimitry Andric } 155349cc55cSDimitry Andric return IsSafeInstr; 1565ffd83dbSDimitry Andric }); 1575ffd83dbSDimitry Andric }; 1585ffd83dbSDimitry Andric 1595ffd83dbSDimitry Andric // Check the code surrounding the inner loop for instructions that are deemed 1605ffd83dbSDimitry Andric // unsafe. 1615ffd83dbSDimitry Andric const BasicBlock *OuterLoopHeader = OuterLoop.getHeader(); 1625ffd83dbSDimitry Andric const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch(); 1635ffd83dbSDimitry Andric const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader(); 1645ffd83dbSDimitry Andric 1655ffd83dbSDimitry Andric if (!containsOnlySafeInstructions(*OuterLoopHeader) || 1665ffd83dbSDimitry Andric !containsOnlySafeInstructions(*OuterLoopLatch) || 1675ffd83dbSDimitry Andric (InnerLoopPreHeader != OuterLoopHeader && 1685ffd83dbSDimitry Andric !containsOnlySafeInstructions(*InnerLoopPreHeader)) || 1695ffd83dbSDimitry Andric !containsOnlySafeInstructions(*InnerLoop.getExitBlock())) { 1705ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Not perfectly nested: code surrounding inner loop is " 1715ffd83dbSDimitry Andric "unsafe\n";); 172349cc55cSDimitry Andric return ImperfectLoopNest; 1735ffd83dbSDimitry Andric } 1745ffd83dbSDimitry Andric 1755ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Loop '" << OuterLoop.getName() << "' and '" 1765ffd83dbSDimitry Andric << InnerLoop.getName() << "' are perfectly nested.\n"); 1775ffd83dbSDimitry Andric 178349cc55cSDimitry Andric return PerfectLoopNest; 179349cc55cSDimitry Andric } 180349cc55cSDimitry Andric 181349cc55cSDimitry Andric LoopNest::InstrVectorTy LoopNest::getInterveningInstructions( 182349cc55cSDimitry Andric const Loop &OuterLoop, const Loop &InnerLoop, ScalarEvolution &SE) { 183349cc55cSDimitry Andric InstrVectorTy Instr; 184349cc55cSDimitry Andric switch (analyzeLoopNestForPerfectNest(OuterLoop, InnerLoop, SE)) { 185349cc55cSDimitry Andric case PerfectLoopNest: 186349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "The loop Nest is Perfect, returning empty " 187349cc55cSDimitry Andric "instruction vector. \n";); 188349cc55cSDimitry Andric return Instr; 189349cc55cSDimitry Andric 190349cc55cSDimitry Andric case InvalidLoopStructure: 191349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure. " 192349cc55cSDimitry Andric "Instruction vector is empty.\n";); 193349cc55cSDimitry Andric return Instr; 194349cc55cSDimitry Andric 195349cc55cSDimitry Andric case OuterLoopLowerBoundUnknown: 196349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: " 197349cc55cSDimitry Andric << OuterLoop << "\nInstruction vector is empty.\n";); 198349cc55cSDimitry Andric return Instr; 199349cc55cSDimitry Andric 200349cc55cSDimitry Andric case ImperfectLoopNest: 201349cc55cSDimitry Andric break; 202349cc55cSDimitry Andric } 203349cc55cSDimitry Andric 204349cc55cSDimitry Andric // Identify the outer loop latch comparison instruction. 205349cc55cSDimitry Andric auto OuterLoopLB = OuterLoop.getBounds(SE); 206349cc55cSDimitry Andric 207349cc55cSDimitry Andric CmpInst *OuterLoopLatchCmp = getOuterLoopLatchCmp(OuterLoop); 208349cc55cSDimitry Andric CmpInst *InnerLoopGuardCmp = getInnerLoopGuardCmp(InnerLoop); 209349cc55cSDimitry Andric 210349cc55cSDimitry Andric auto GetUnsafeInstructions = [&](const BasicBlock &BB) { 211349cc55cSDimitry Andric for (const Instruction &I : BB) { 212349cc55cSDimitry Andric if (!checkSafeInstruction(I, InnerLoopGuardCmp, OuterLoopLatchCmp, 213349cc55cSDimitry Andric OuterLoopLB)) { 214349cc55cSDimitry Andric Instr.push_back(&I); 215349cc55cSDimitry Andric DEBUG_WITH_TYPE(VerboseDebug, { 216349cc55cSDimitry Andric dbgs() << "Instruction: " << I << "\nin basic block:" << BB 217349cc55cSDimitry Andric << "is unsafe.\n"; 218349cc55cSDimitry Andric }); 219349cc55cSDimitry Andric } 220349cc55cSDimitry Andric } 221349cc55cSDimitry Andric }; 222349cc55cSDimitry Andric 223349cc55cSDimitry Andric // Check the code surrounding the inner loop for instructions that are deemed 224349cc55cSDimitry Andric // unsafe. 225349cc55cSDimitry Andric const BasicBlock *OuterLoopHeader = OuterLoop.getHeader(); 226349cc55cSDimitry Andric const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch(); 227349cc55cSDimitry Andric const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader(); 228349cc55cSDimitry Andric const BasicBlock *InnerLoopExitBlock = InnerLoop.getExitBlock(); 229349cc55cSDimitry Andric 230349cc55cSDimitry Andric GetUnsafeInstructions(*OuterLoopHeader); 231349cc55cSDimitry Andric GetUnsafeInstructions(*OuterLoopLatch); 232349cc55cSDimitry Andric GetUnsafeInstructions(*InnerLoopExitBlock); 233349cc55cSDimitry Andric 234349cc55cSDimitry Andric if (InnerLoopPreHeader != OuterLoopHeader) { 235349cc55cSDimitry Andric GetUnsafeInstructions(*InnerLoopPreHeader); 236349cc55cSDimitry Andric } 237349cc55cSDimitry Andric return Instr; 2385ffd83dbSDimitry Andric } 2395ffd83dbSDimitry Andric 2405ffd83dbSDimitry Andric SmallVector<LoopVectorTy, 4> 2415ffd83dbSDimitry Andric LoopNest::getPerfectLoops(ScalarEvolution &SE) const { 2425ffd83dbSDimitry Andric SmallVector<LoopVectorTy, 4> LV; 2435ffd83dbSDimitry Andric LoopVectorTy PerfectNest; 2445ffd83dbSDimitry Andric 2455ffd83dbSDimitry Andric for (Loop *L : depth_first(const_cast<Loop *>(Loops.front()))) { 2465ffd83dbSDimitry Andric if (PerfectNest.empty()) 2475ffd83dbSDimitry Andric PerfectNest.push_back(L); 2485ffd83dbSDimitry Andric 2495ffd83dbSDimitry Andric auto &SubLoops = L->getSubLoops(); 2505ffd83dbSDimitry Andric if (SubLoops.size() == 1 && arePerfectlyNested(*L, *SubLoops.front(), SE)) { 2515ffd83dbSDimitry Andric PerfectNest.push_back(SubLoops.front()); 2525ffd83dbSDimitry Andric } else { 2535ffd83dbSDimitry Andric LV.push_back(PerfectNest); 2545ffd83dbSDimitry Andric PerfectNest.clear(); 2555ffd83dbSDimitry Andric } 2565ffd83dbSDimitry Andric } 2575ffd83dbSDimitry Andric 2585ffd83dbSDimitry Andric return LV; 2595ffd83dbSDimitry Andric } 2605ffd83dbSDimitry Andric 2615ffd83dbSDimitry Andric unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) { 2625ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Get maximum perfect depth of loop nest rooted by loop '" 2635ffd83dbSDimitry Andric << Root.getName() << "'\n"); 2645ffd83dbSDimitry Andric 2655ffd83dbSDimitry Andric const Loop *CurrentLoop = &Root; 2665ffd83dbSDimitry Andric const auto *SubLoops = &CurrentLoop->getSubLoops(); 2675ffd83dbSDimitry Andric unsigned CurrentDepth = 1; 2685ffd83dbSDimitry Andric 2695ffd83dbSDimitry Andric while (SubLoops->size() == 1) { 2705ffd83dbSDimitry Andric const Loop *InnerLoop = SubLoops->front(); 2715ffd83dbSDimitry Andric if (!arePerfectlyNested(*CurrentLoop, *InnerLoop, SE)) { 2725ffd83dbSDimitry Andric LLVM_DEBUG({ 2735ffd83dbSDimitry Andric dbgs() << "Not a perfect nest: loop '" << CurrentLoop->getName() 2745ffd83dbSDimitry Andric << "' is not perfectly nested with loop '" 2755ffd83dbSDimitry Andric << InnerLoop->getName() << "'\n"; 2765ffd83dbSDimitry Andric }); 2775ffd83dbSDimitry Andric break; 2785ffd83dbSDimitry Andric } 2795ffd83dbSDimitry Andric 2805ffd83dbSDimitry Andric CurrentLoop = InnerLoop; 2815ffd83dbSDimitry Andric SubLoops = &CurrentLoop->getSubLoops(); 2825ffd83dbSDimitry Andric ++CurrentDepth; 2835ffd83dbSDimitry Andric } 2845ffd83dbSDimitry Andric 2855ffd83dbSDimitry Andric return CurrentDepth; 2865ffd83dbSDimitry Andric } 2875ffd83dbSDimitry Andric 288e8d8bef9SDimitry Andric const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From, 289fe6060f1SDimitry Andric const BasicBlock *End, 290fe6060f1SDimitry Andric bool CheckUniquePred) { 291e8d8bef9SDimitry Andric assert(From && "Expecting valid From"); 292e8d8bef9SDimitry Andric assert(End && "Expecting valid End"); 293e8d8bef9SDimitry Andric 294fe6060f1SDimitry Andric if (From == End || !From->getUniqueSuccessor()) 295e8d8bef9SDimitry Andric return *From; 296e8d8bef9SDimitry Andric 297e8d8bef9SDimitry Andric auto IsEmpty = [](const BasicBlock *BB) { 298e8d8bef9SDimitry Andric return (BB->getInstList().size() == 1); 299e8d8bef9SDimitry Andric }; 300e8d8bef9SDimitry Andric 301e8d8bef9SDimitry Andric // Visited is used to avoid running into an infinite loop. 302e8d8bef9SDimitry Andric SmallPtrSet<const BasicBlock *, 4> Visited; 303fe6060f1SDimitry Andric const BasicBlock *BB = From->getUniqueSuccessor(); 304fe6060f1SDimitry Andric const BasicBlock *PredBB = From; 305fe6060f1SDimitry Andric while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB) && 306fe6060f1SDimitry Andric (!CheckUniquePred || BB->getUniquePredecessor())) { 307e8d8bef9SDimitry Andric Visited.insert(BB); 308e8d8bef9SDimitry Andric PredBB = BB; 309fe6060f1SDimitry Andric BB = BB->getUniqueSuccessor(); 310e8d8bef9SDimitry Andric } 311e8d8bef9SDimitry Andric 312e8d8bef9SDimitry Andric return (BB == End) ? *End : *PredBB; 313e8d8bef9SDimitry Andric } 314e8d8bef9SDimitry Andric 3155ffd83dbSDimitry Andric static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, 3165ffd83dbSDimitry Andric ScalarEvolution &SE) { 3175ffd83dbSDimitry Andric // The inner loop must be the only outer loop's child. 3185ffd83dbSDimitry Andric if ((OuterLoop.getSubLoops().size() != 1) || 3195ffd83dbSDimitry Andric (InnerLoop.getParentLoop() != &OuterLoop)) 3205ffd83dbSDimitry Andric return false; 3215ffd83dbSDimitry Andric 3225ffd83dbSDimitry Andric // We expect loops in normal form which have a preheader, header, latch... 3235ffd83dbSDimitry Andric if (!OuterLoop.isLoopSimplifyForm() || !InnerLoop.isLoopSimplifyForm()) 3245ffd83dbSDimitry Andric return false; 3255ffd83dbSDimitry Andric 3265ffd83dbSDimitry Andric const BasicBlock *OuterLoopHeader = OuterLoop.getHeader(); 3275ffd83dbSDimitry Andric const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch(); 3285ffd83dbSDimitry Andric const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader(); 3295ffd83dbSDimitry Andric const BasicBlock *InnerLoopLatch = InnerLoop.getLoopLatch(); 3305ffd83dbSDimitry Andric const BasicBlock *InnerLoopExit = InnerLoop.getExitBlock(); 3315ffd83dbSDimitry Andric 3325ffd83dbSDimitry Andric // We expect rotated loops. The inner loop should have a single exit block. 3335ffd83dbSDimitry Andric if (OuterLoop.getExitingBlock() != OuterLoopLatch || 3345ffd83dbSDimitry Andric InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit) 3355ffd83dbSDimitry Andric return false; 3365ffd83dbSDimitry Andric 337e8d8bef9SDimitry Andric // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node. 338e8d8bef9SDimitry Andric auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) { 339e8d8bef9SDimitry Andric return any_of(ExitBlock.phis(), [](const PHINode &PN) { 340e8d8bef9SDimitry Andric return PN.getNumIncomingValues() == 1; 341e8d8bef9SDimitry Andric }); 342e8d8bef9SDimitry Andric }; 343e8d8bef9SDimitry Andric 344e8d8bef9SDimitry Andric // Returns whether the block `BB` qualifies for being an extra Phi block. The 345e8d8bef9SDimitry Andric // extra Phi block is the additional block inserted after the exit block of an 346e8d8bef9SDimitry Andric // "guarded" inner loop which contains "only" Phi nodes corresponding to the 347e8d8bef9SDimitry Andric // LCSSA Phi nodes in the exit block. 348e8d8bef9SDimitry Andric auto IsExtraPhiBlock = [&](const BasicBlock &BB) { 349e8d8bef9SDimitry Andric return BB.getFirstNonPHI() == BB.getTerminator() && 350e8d8bef9SDimitry Andric all_of(BB.phis(), [&](const PHINode &PN) { 351e8d8bef9SDimitry Andric return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) { 352e8d8bef9SDimitry Andric return IncomingBlock == InnerLoopExit || 353e8d8bef9SDimitry Andric IncomingBlock == OuterLoopHeader; 354e8d8bef9SDimitry Andric }); 355e8d8bef9SDimitry Andric }); 356e8d8bef9SDimitry Andric }; 357e8d8bef9SDimitry Andric 358e8d8bef9SDimitry Andric const BasicBlock *ExtraPhiBlock = nullptr; 3595ffd83dbSDimitry Andric // Ensure the only branch that may exist between the loops is the inner loop 3605ffd83dbSDimitry Andric // guard. 3615ffd83dbSDimitry Andric if (OuterLoopHeader != InnerLoopPreHeader) { 362e8d8bef9SDimitry Andric const BasicBlock &SingleSucc = 363e8d8bef9SDimitry Andric LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader); 364e8d8bef9SDimitry Andric 365e8d8bef9SDimitry Andric // no conditional branch present 366e8d8bef9SDimitry Andric if (&SingleSucc != InnerLoopPreHeader) { 367e8d8bef9SDimitry Andric const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator()); 3685ffd83dbSDimitry Andric 3695ffd83dbSDimitry Andric if (!BI || BI != InnerLoop.getLoopGuardBranch()) 3705ffd83dbSDimitry Andric return false; 3715ffd83dbSDimitry Andric 372e8d8bef9SDimitry Andric bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit); 373e8d8bef9SDimitry Andric 3745ffd83dbSDimitry Andric // The successors of the inner loop guard should be the inner loop 375e8d8bef9SDimitry Andric // preheader or the outer loop latch possibly through empty blocks. 3765ffd83dbSDimitry Andric for (const BasicBlock *Succ : BI->successors()) { 377e8d8bef9SDimitry Andric const BasicBlock *PotentialInnerPreHeader = Succ; 378e8d8bef9SDimitry Andric const BasicBlock *PotentialOuterLatch = Succ; 379e8d8bef9SDimitry Andric 380e8d8bef9SDimitry Andric // Ensure the inner loop guard successor is empty before skipping 381e8d8bef9SDimitry Andric // blocks. 382e8d8bef9SDimitry Andric if (Succ->getInstList().size() == 1) { 383e8d8bef9SDimitry Andric PotentialInnerPreHeader = 384e8d8bef9SDimitry Andric &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader); 385e8d8bef9SDimitry Andric PotentialOuterLatch = 386e8d8bef9SDimitry Andric &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch); 387e8d8bef9SDimitry Andric } 388e8d8bef9SDimitry Andric 389e8d8bef9SDimitry Andric if (PotentialInnerPreHeader == InnerLoopPreHeader) 3905ffd83dbSDimitry Andric continue; 391e8d8bef9SDimitry Andric if (PotentialOuterLatch == OuterLoopLatch) 3925ffd83dbSDimitry Andric continue; 3935ffd83dbSDimitry Andric 394e8d8bef9SDimitry Andric // If `InnerLoopExit` contains LCSSA Phi instructions, additional block 395e8d8bef9SDimitry Andric // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The 396e8d8bef9SDimitry Andric // loops are still considered perfectly nested if the extra block only 397e8d8bef9SDimitry Andric // contains Phi instructions from InnerLoopExit and OuterLoopHeader. 398e8d8bef9SDimitry Andric if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) && 399e8d8bef9SDimitry Andric Succ->getSingleSuccessor() == OuterLoopLatch) { 400e8d8bef9SDimitry Andric // Points to the extra block so that we can reference it later in the 401e8d8bef9SDimitry Andric // final check. We can also conclude that the inner loop is 402e8d8bef9SDimitry Andric // guarded and there exists LCSSA Phi node in the exit block later if 403e8d8bef9SDimitry Andric // we see a non-null `ExtraPhiBlock`. 404e8d8bef9SDimitry Andric ExtraPhiBlock = Succ; 405e8d8bef9SDimitry Andric continue; 406e8d8bef9SDimitry Andric } 407e8d8bef9SDimitry Andric 4085ffd83dbSDimitry Andric DEBUG_WITH_TYPE(VerboseDebug, { 4095ffd83dbSDimitry Andric dbgs() << "Inner loop guard successor " << Succ->getName() 4105ffd83dbSDimitry Andric << " doesn't lead to inner loop preheader or " 4115ffd83dbSDimitry Andric "outer loop latch.\n"; 4125ffd83dbSDimitry Andric }); 4135ffd83dbSDimitry Andric return false; 4145ffd83dbSDimitry Andric } 4155ffd83dbSDimitry Andric } 416e8d8bef9SDimitry Andric } 4175ffd83dbSDimitry Andric 418e8d8bef9SDimitry Andric // Ensure the inner loop exit block lead to the outer loop latch possibly 419e8d8bef9SDimitry Andric // through empty blocks. 420fe6060f1SDimitry Andric if ((!ExtraPhiBlock || 421fe6060f1SDimitry Andric &LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(), 422fe6060f1SDimitry Andric ExtraPhiBlock) != ExtraPhiBlock) && 423fe6060f1SDimitry Andric (&LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(), 424fe6060f1SDimitry Andric OuterLoopLatch) != OuterLoopLatch)) { 4255ffd83dbSDimitry Andric DEBUG_WITH_TYPE( 4265ffd83dbSDimitry Andric VerboseDebug, 4275ffd83dbSDimitry Andric dbgs() << "Inner loop exit block " << *InnerLoopExit 4285ffd83dbSDimitry Andric << " does not directly lead to the outer loop latch.\n";); 4295ffd83dbSDimitry Andric return false; 4305ffd83dbSDimitry Andric } 4315ffd83dbSDimitry Andric 4325ffd83dbSDimitry Andric return true; 4335ffd83dbSDimitry Andric } 4345ffd83dbSDimitry Andric 435e8d8bef9SDimitry Andric AnalysisKey LoopNestAnalysis::Key; 436e8d8bef9SDimitry Andric 4375ffd83dbSDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) { 4385ffd83dbSDimitry Andric OS << "IsPerfect="; 4395ffd83dbSDimitry Andric if (LN.getMaxPerfectDepth() == LN.getNestDepth()) 4405ffd83dbSDimitry Andric OS << "true"; 4415ffd83dbSDimitry Andric else 4425ffd83dbSDimitry Andric OS << "false"; 4435ffd83dbSDimitry Andric OS << ", Depth=" << LN.getNestDepth(); 4445ffd83dbSDimitry Andric OS << ", OutermostLoop: " << LN.getOutermostLoop().getName(); 4455ffd83dbSDimitry Andric OS << ", Loops: ( "; 4465ffd83dbSDimitry Andric for (const Loop *L : LN.getLoops()) 4475ffd83dbSDimitry Andric OS << L->getName() << " "; 4485ffd83dbSDimitry Andric OS << ")"; 4495ffd83dbSDimitry Andric 4505ffd83dbSDimitry Andric return OS; 4515ffd83dbSDimitry Andric } 4525ffd83dbSDimitry Andric 4535ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 4545ffd83dbSDimitry Andric // LoopNestPrinterPass implementation 4555ffd83dbSDimitry Andric // 4565ffd83dbSDimitry Andric 4575ffd83dbSDimitry Andric PreservedAnalyses LoopNestPrinterPass::run(Loop &L, LoopAnalysisManager &AM, 4585ffd83dbSDimitry Andric LoopStandardAnalysisResults &AR, 4595ffd83dbSDimitry Andric LPMUpdater &U) { 4605ffd83dbSDimitry Andric if (auto LN = LoopNest::getLoopNest(L, AR.SE)) 4615ffd83dbSDimitry Andric OS << *LN << "\n"; 4625ffd83dbSDimitry Andric 4635ffd83dbSDimitry Andric return PreservedAnalyses::all(); 4645ffd83dbSDimitry Andric } 465