Index: llvm/include/llvm/Analysis/LoopInfo.h =================================================================== --- llvm/include/llvm/Analysis/LoopInfo.h +++ llvm/include/llvm/Analysis/LoopInfo.h @@ -155,7 +155,10 @@ iterator end() const { return getSubLoops().end(); } reverse_iterator rbegin() const { return getSubLoops().rbegin(); } reverse_iterator rend() const { return getSubLoops().rend(); } - bool empty() const { return getSubLoops().empty(); } + /// Return true if the loop does not contain any sub-loops. + bool isInnermost() const { return getSubLoops().empty(); } + /// Outermost is the same as top-level. + bool isOutermost() const { return getParentLoop() == nullptr; } /// Get a list of the basic blocks which make up this loop. ArrayRef getBlocks() const { Index: llvm/lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1773,7 +1773,7 @@ << TheLoop->getHeader()->getName() << '\n'); // We can only analyze innermost loops. - if (!TheLoop->empty()) { + if (!TheLoop->isInnermost()) { LLVM_DEBUG(dbgs() << "LAA: loop is not the innermost loop\n"); recordAnalysis("NotInnerMostLoop") << "loop is not the innermost loop"; return false; Index: llvm/lib/Analysis/LoopInfo.cpp =================================================================== --- llvm/lib/Analysis/LoopInfo.cpp +++ llvm/lib/Analysis/LoopInfo.cpp @@ -764,7 +764,7 @@ /// Update the parent loop for all subloops directly nested within unloop. void UnloopUpdater::updateSubloopParents() { - while (!Unloop.empty()) { + while (!Unloop.isInnermost()) { Loop *Subloop = *std::prev(Unloop.end()); Unloop.removeChildLoop(std::prev(Unloop.end())); @@ -887,7 +887,7 @@ } // Move all of the subloops to the top-level. - while (!Unloop->empty()) + while (!Unloop->isInnermost()) addTopLevelLoop(Unloop->removeChildLoop(std::prev(Unloop->end()))); return; Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3001,7 +3001,7 @@ OS.indent(Loop->getLoopDepth()*2-2); OS << "This "; - if (Loop->empty()) + if (Loop->isInnermost()) OS << "Inner "; OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; Index: llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp +++ llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp @@ -271,7 +271,7 @@ bool MadeChange = false; // Only prefetch in the inner-most loop - if (!L->empty()) + if (!L->isInnermost()) return MadeChange; SmallPtrSet EphValues; Index: llvm/lib/Transforms/Scalar/LoopDistribute.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopDistribute.cpp +++ llvm/lib/Transforms/Scalar/LoopDistribute.cpp @@ -664,7 +664,7 @@ /// Try to distribute an inner-most loop. bool processLoop(std::function &GetLAA) { - assert(L->empty() && "Only process inner loops."); + assert(L->isInnermost() && "Only process inner loops."); LLVM_DEBUG(dbgs() << "\nLDist: In \"" << L->getHeader()->getParent()->getName() @@ -982,7 +982,7 @@ for (Loop *TopLevelLoop : *LI) for (Loop *L : depth_first(TopLevelLoop)) // We only handle inner-most loops. - if (L->empty()) + if (L->isInnermost()) Worklist.push_back(L); // Now walk the identified inner loops. Index: llvm/lib/Transforms/Scalar/LoopFuse.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopFuse.cpp +++ llvm/lib/Transforms/Scalar/LoopFuse.cpp @@ -1291,7 +1291,7 @@ continue; LI.changeLoopFor(BB, FC0.L); } - while (!FC1.L->empty()) { + while (!FC1.L->isInnermost()) { const auto &ChildLoopIt = FC1.L->begin(); Loop *ChildLoop = *ChildLoopIt; FC1.L->removeChildLoop(ChildLoopIt); @@ -1566,7 +1566,7 @@ continue; LI.changeLoopFor(BB, FC0.L); } - while (!FC1.L->empty()) { + while (!FC1.L->isInnermost()) { const auto &ChildLoopIt = FC1.L->begin(); Loop *ChildLoop = *ChildLoopIt; FC1.L->removeChildLoop(ChildLoopIt); Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -1189,7 +1189,7 @@ removeChildLoop(NewInner, NewOuter); LI->changeTopLevelLoop(NewInner, NewOuter); } - while (!NewOuter->empty()) + while (!NewOuter->isInnermost()) NewInner->addChildLoop(NewOuter->removeChildLoop(NewOuter->begin())); NewOuter->addChildLoop(NewInner); Index: llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp +++ llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp @@ -610,7 +610,7 @@ for (Loop *TopLevelLoop : LI) for (Loop *L : depth_first(TopLevelLoop)) // We only handle inner-most loops. - if (L->empty()) + if (L->isInnermost()) Worklist.push_back(L); // Now walk the identified inner loops. Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -5614,7 +5614,7 @@ if (IU.empty()) return; // Skip nested loops until we can model them better with formulae. - if (!L->empty()) { + if (!L->isInnermost()) { LLVM_DEBUG(dbgs() << "LSR skipping outer loop " << *L << "\n"); return; } Index: llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -384,7 +384,7 @@ // Only analyze inner loops. We can't properly estimate cost of nested loops // and we won't visit inner loops again anyway. - if (!L->empty()) + if (!L->isInnermost()) return None; // Don't simulate loops with a big or unknown tripcount Index: llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -1194,7 +1194,7 @@ LI.addTopLevelLoop(ClonedRootL); AddClonedBlocksToLoop(OrigRootL, *ClonedRootL); - if (OrigRootL.empty()) + if (OrigRootL.isInnermost()) return ClonedRootL; // If we have a nest, we can quickly clone the entire loop nest using an Index: llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp +++ llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp @@ -292,7 +292,7 @@ // Only try to peel innermost loops by default. // The constraint can be relaxed by the target in TTI.getUnrollingPreferences // or by the flag -unroll-allow-loop-nests-peeling. - if (!PP.AllowLoopNestsPeeling && !L->empty()) + if (!PP.AllowLoopNestsPeeling && !L->isInnermost()) return; // If the user provided a peel count, use that. Index: llvm/lib/Transforms/Utils/LoopVersioning.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopVersioning.cpp +++ llvm/lib/Transforms/Utils/LoopVersioning.cpp @@ -276,7 +276,7 @@ for (Loop *TopLevelLoop : *LI) for (Loop *L : depth_first(TopLevelLoop)) // We only handle inner-most loops. - if (L->empty()) + if (L->isInnermost()) Worklist.push_back(L); // Now walk the identified inner loops. Index: llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp @@ -424,7 +424,7 @@ } bool LoopVectorizationLegality::canVectorizeOuterLoop() { - assert(!TheLoop->empty() && "We are not vectorizing an outer loop."); + assert(!TheLoop->isInnermost() && "We are not vectorizing an outer loop."); // Store the result and return it at the end instead of exiting early, in case // allowExtraAnalysis is used to report multiple reasons for not vectorizing. bool Result = true; @@ -1044,7 +1044,7 @@ // Helper function to canVectorizeLoopNestCFG. bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp, bool UseVPlanNativePath) { - assert((UseVPlanNativePath || Lp->empty()) && + assert((UseVPlanNativePath || Lp->isInnermost()) && "VPlan-native path is not enabled."); // TODO: ORE should be improved to show more accurate information when an @@ -1154,7 +1154,7 @@ // Specific checks for outer loops. We skip the remaining legal checks at this // point because they don't support outer loops. - if (!TheLoop->empty()) { + if (!TheLoop->isInnermost()) { assert(UseVPlanNativePath && "VPlan-native path is not enabled."); if (!canVectorizeOuterLoop()) { @@ -1171,7 +1171,7 @@ return Result; } - assert(TheLoop->empty() && "Inner loop expected."); + assert(TheLoop->isInnermost() && "Inner loop expected."); // Check if we can if-convert non-single-bb loops. unsigned NumBlocks = TheLoop->getNumBlocks(); if (NumBlocks != 1 && !canVectorizeWithIfConvert()) { Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1549,7 +1549,7 @@ // representation for pragma 'omp simd' is introduced. static bool isExplicitVecOuterLoop(Loop *OuterLp, OptimizationRemarkEmitter *ORE) { - assert(!OuterLp->empty() && "This is not an outer loop"); + assert(!OuterLp->isInnermost() && "This is not an outer loop"); LoopVectorizeHints Hints(OuterLp, true /*DisableInterleaving*/, *ORE); // Only outer loops with an explicit vectorization hint are supported. @@ -1582,7 +1582,7 @@ // now, only collect outer loops that have explicit vectorization hints. If we // are stress testing the VPlan H-CFG construction, we collect the outermost // loop of every loop nest. - if (L.empty() || VPlanBuildStressTest || + if (L.isInnermost() || VPlanBuildStressTest || (EnableVPlanNativePath && isExplicitVecOuterLoop(&L, ORE))) { LoopBlocksRPO RPOT(&L); RPOT.perform(LI); @@ -6533,7 +6533,7 @@ // transformations before even evaluating whether vectorization is profitable. // Since we cannot modify the incoming IR, we need to build VPlan upfront in // the vectorization pipeline. - if (!OrigLoop->empty()) { + if (!OrigLoop->isInnermost()) { // If the user doesn't provide a vectorization factor, determine a // reasonable one. if (!UserVF) { @@ -6568,7 +6568,7 @@ Optional LoopVectorizationPlanner::plan(unsigned UserVF, unsigned UserIC) { - assert(OrigLoop->empty() && "Inner loop expected."); + assert(OrigLoop->isInnermost() && "Inner loop expected."); Optional MaybeMaxVF = CM.computeMaxVF(UserVF, UserIC); if (!MaybeMaxVF) // Cases that should not to be vectorized nor interleaved. return None; @@ -7167,7 +7167,7 @@ void LoopVectorizationPlanner::buildVPlansWithVPRecipes(unsigned MinVF, unsigned MaxVF) { - assert(OrigLoop->empty() && "Inner loop expected."); + assert(OrigLoop->isInnermost() && "Inner loop expected."); // Collect conditions feeding internal conditional branches; they need to be // represented in VPlan for it to model masking. @@ -7394,7 +7394,7 @@ // transformations before even evaluating whether vectorization is profitable. // Since we cannot modify the incoming IR, we need to build VPlan upfront in // the vectorization pipeline. - assert(!OrigLoop->empty()); + assert(!OrigLoop->isInnermost()); assert(EnableVPlanNativePath && "VPlan-native path is not enabled."); // Create new empty VPlan @@ -7710,7 +7710,7 @@ !EnableLoopVectorization) {} bool LoopVectorizePass::processLoop(Loop *L) { - assert((EnableVPlanNativePath || L->empty()) && + assert((EnableVPlanNativePath || L->isInnermost()) && "VPlan-native path is not enabled. Only process inner loops."); #ifndef NDEBUG @@ -7772,11 +7772,11 @@ // even evaluating whether vectorization is profitable. Since we cannot modify // the incoming IR, we need to build VPlan upfront in the vectorization // pipeline. - if (!L->empty()) + if (!L->isInnermost()) return processLoopInVPlanNativePath(L, PSE, LI, DT, &LVL, TTI, TLI, DB, AC, ORE, BFI, PSI, Hints); - assert(L->empty() && "Inner loop expected."); + assert(L->isInnermost() && "Inner loop expected."); // Check the loop for a trip count threshold: vectorize loops with a tiny trip // count by optimizing for size, to minimize overheads.