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"
1681ad6265SDimitry 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
LoopNest(Loop & Root,ScalarEvolution & SE)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
getLoopNest(Loop & Root,ScalarEvolution & SE)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
getOuterLoopLatchCmp(const Loop & OuterLoop)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
getInnerLoopGuardCmp(const Loop & InnerLoop)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
checkSafeInstruction(const Instruction & I,const CmpInst * InnerLoopGuardCmp,const CmpInst * OuterLoopLatchCmp,std::optional<Loop::LoopBounds> OuterLoopLB)84349cc55cSDimitry Andric static bool checkSafeInstruction(const Instruction &I,
85349cc55cSDimitry Andric const CmpInst *InnerLoopGuardCmp,
86349cc55cSDimitry Andric const CmpInst *OuterLoopLatchCmp,
87*bdd1243dSDimitry Andric std::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
arePerfectlyNested(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)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
analyzeLoopNestForPerfectNest(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)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);
131*bdd1243dSDimitry Andric if (OuterLoopLB == std::nullopt) {
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
getInterveningInstructions(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)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>
getPerfectLoops(ScalarEvolution & SE) const2415ffd83dbSDimitry 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
getMaxPerfectDepth(const Loop & Root,ScalarEvolution & SE)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
skipEmptyBlockUntil(const BasicBlock * From,const BasicBlock * End,bool CheckUniquePred)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) {
298*bdd1243dSDimitry Andric return (BB->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
checkLoopsStructure(const Loop & OuterLoop,const Loop & InnerLoop,ScalarEvolution & SE)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.
382*bdd1243dSDimitry Andric if (Succ->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
operator <<(raw_ostream & OS,const LoopNest & LN)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
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)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