Skip to content

Commit 89c1e35

Browse files
committed
[LoopInfo] empty() -> isInnermost(), add isOutermost()
Differential Revision: https://reviews.llvm.org/D82895
1 parent 4edb3d3 commit 89c1e35

26 files changed

+57
-47
lines changed

llvm/include/llvm/Analysis/LoopInfo.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,17 @@ template <class BlockT, class LoopT> class LoopBase {
155155
iterator end() const { return getSubLoops().end(); }
156156
reverse_iterator rbegin() const { return getSubLoops().rbegin(); }
157157
reverse_iterator rend() const { return getSubLoops().rend(); }
158-
bool empty() const { return getSubLoops().empty(); }
158+
159+
// LoopInfo does not detect irreducible control flow, just natural
160+
// loops. That is, it is possible that there is cyclic control
161+
// flow within the "innermost loop" or around the "outermost
162+
// loop".
163+
164+
/// Return true if the loop does not contain any (natural) loops.
165+
bool isInnermost() const { return getSubLoops().empty(); }
166+
/// Return true if the loop does not have a parent (natural) loop
167+
// (i.e. it is outermost, which is the same as top-level).
168+
bool isOutermost() const { return getParentLoop() == nullptr; }
159169

160170
/// Get a list of the basic blocks which make up this loop.
161171
ArrayRef<BlockT *> getBlocks() const {
@@ -974,7 +984,7 @@ template <class BlockT, class LoopT> class LoopInfoBase {
974984
LoopT *removeLoop(iterator I) {
975985
assert(I != end() && "Cannot remove end iterator!");
976986
LoopT *L = *I;
977-
assert(!L->getParentLoop() && "Not a top-level loop!");
987+
assert(L->isOutermost() && "Not a top-level loop!");
978988
TopLevelLoops.erase(TopLevelLoops.begin() + (I - begin()));
979989
return L;
980990
}
@@ -1002,7 +1012,7 @@ template <class BlockT, class LoopT> class LoopInfoBase {
10021012

10031013
/// This adds the specified loop to the collection of top-level loops.
10041014
void addTopLevelLoop(LoopT *New) {
1005-
assert(!New->getParentLoop() && "Loop already in subloop!");
1015+
assert(New->isOutermost() && "Loop already in subloop!");
10061016
TopLevelLoops.push_back(New);
10071017
}
10081018

llvm/include/llvm/Analysis/LoopInfoImpl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
502502
if (Subloop && Block == Subloop->getHeader()) {
503503
// We reach this point once per subloop after processing all the blocks in
504504
// the subloop.
505-
if (Subloop->getParentLoop())
505+
if (!Subloop->isOutermost())
506506
Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
507507
else
508508
LI->addTopLevelLoop(Subloop);
@@ -681,7 +681,7 @@ void LoopInfoBase<BlockT, LoopT>::verify(
681681
const DomTreeBase<BlockT> &DomTree) const {
682682
DenseSet<const LoopT *> Loops;
683683
for (iterator I = begin(), E = end(); I != E; ++I) {
684-
assert(!(*I)->getParentLoop() && "Top-level loop has a parent!");
684+
assert((*I)->isOutermost() && "Top-level loop has a parent!");
685685
(*I)->verifyLoopNest(&Loops);
686686
}
687687

llvm/lib/Analysis/LoopAccessAnalysis.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1769,7 +1769,7 @@ bool LoopAccessInfo::canAnalyzeLoop() {
17691769
<< TheLoop->getHeader()->getName() << '\n');
17701770

17711771
// We can only analyze innermost loops.
1772-
if (!TheLoop->empty()) {
1772+
if (!TheLoop->isInnermost()) {
17731773
LLVM_DEBUG(dbgs() << "LAA: loop is not the innermost loop\n");
17741774
recordAnalysis("NotInnerMostLoop") << "loop is not the innermost loop";
17751775
return false;

llvm/lib/Analysis/LoopCacheAnalysis.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ CacheCost::CacheCost(const LoopVectorTy &Loops, const LoopInfo &LI,
499499
std::unique_ptr<CacheCost>
500500
CacheCost::getCacheCost(Loop &Root, LoopStandardAnalysisResults &AR,
501501
DependenceInfo &DI, Optional<unsigned> TRT) {
502-
if (Root.getParentLoop()) {
502+
if (!Root.isOutermost()) {
503503
LLVM_DEBUG(dbgs() << "Expecting the outermost loop in a loop nest\n");
504504
return nullptr;
505505
}

llvm/lib/Analysis/LoopInfo.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ void UnloopUpdater::removeBlocksFromAncestors() {
764764

765765
/// Update the parent loop for all subloops directly nested within unloop.
766766
void UnloopUpdater::updateSubloopParents() {
767-
while (!Unloop.empty()) {
767+
while (!Unloop.isInnermost()) {
768768
Loop *Subloop = *std::prev(Unloop.end());
769769
Unloop.removeChildLoop(std::prev(Unloop.end()));
770770

@@ -862,7 +862,7 @@ void LoopInfo::erase(Loop *Unloop) {
862862
auto InvalidateOnExit = make_scope_exit([&]() { destroy(Unloop); });
863863

864864
// First handle the special case of no parent loop to simplify the algorithm.
865-
if (!Unloop->getParentLoop()) {
865+
if (Unloop->isOutermost()) {
866866
// Since BBLoop had no parent, Unloop blocks are no longer in a loop.
867867
for (Loop::block_iterator I = Unloop->block_begin(),
868868
E = Unloop->block_end();
@@ -887,7 +887,7 @@ void LoopInfo::erase(Loop *Unloop) {
887887
}
888888

889889
// Move all of the subloops to the top-level.
890-
while (!Unloop->empty())
890+
while (!Unloop->isInnermost())
891891
addTopLevelLoop(Unloop->removeChildLoop(std::prev(Unloop->end())));
892892

893893
return;

llvm/lib/Analysis/LoopNestAnalysis.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
5353

5454
bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
5555
ScalarEvolution &SE) {
56-
assert(!OuterLoop.getSubLoops().empty() && "Outer loop should have subloops");
57-
assert(InnerLoop.getParentLoop() && "Inner loop should have a parent");
56+
assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
57+
assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
5858
LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName()
5959
<< "' and '" << InnerLoop.getName()
6060
<< "' are perfectly nested.\n");

llvm/lib/Analysis/LoopPass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ LPPassManager::LPPassManager()
7777

7878
// Insert loop into loop nest (LoopInfo) and loop queue (LQ).
7979
void LPPassManager::addLoop(Loop &L) {
80-
if (!L.getParentLoop()) {
80+
if (L.isOutermost()) {
8181
// This is the top level loop.
8282
LQ.push_front(&L);
8383
return;

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3022,7 +3022,7 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
30223022
OS.indent(Loop->getLoopDepth()*2-2);
30233023

30243024
OS << "This ";
3025-
if (Loop->empty())
3025+
if (Loop->isInnermost())
30263026
OS << "Inner ";
30273027
OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
30283028

llvm/lib/CodeGen/HardwareLoops.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ bool HardwareLoops::runOnFunction(Function &F) {
234234

235235
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) {
236236
Loop *L = *I;
237-
if (!L->getParentLoop())
237+
if (L->isOutermost())
238238
TryConvertLoop(L);
239239
}
240240

llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ bool ARMLowOverheadLoops::runOnMachineFunction(MachineFunction &mf) {
10431043

10441044
bool Changed = false;
10451045
for (auto ML : *MLI) {
1046-
if (!ML->getParentLoop())
1046+
if (ML->isOutermost())
10471047
Changed |= ProcessLoop(ML);
10481048
}
10491049
Changed |= RevertNonLoops();

llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ bool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) {
390390
TRI = HST.getRegisterInfo();
391391

392392
for (auto &L : *MLI)
393-
if (!L->getParentLoop()) {
393+
if (L->isOutermost()) {
394394
bool L0Used = false;
395395
bool L1Used = false;
396396
Changed |= convertToHardwareLoop(L, L0Used, L1Used);

llvm/lib/Transforms/Scalar/LICM.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ bool LoopInvariantCodeMotion::runOnLoop(
449449
// specifically moving instructions across the loop boundary and so it is
450450
// especially in need of sanity checking here.
451451
assert(L->isLCSSAForm(*DT) && "Loop not left in LCSSA form after LICM!");
452-
assert((!L->getParentLoop() || L->getParentLoop()->isLCSSAForm(*DT)) &&
452+
assert((L->isOutermost() || L->getParentLoop()->isLCSSAForm(*DT)) &&
453453
"Parent loop not left in LCSSA form after LICM!");
454454

455455
if (MSSAU.get() && VerifyMemorySSA)

llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ bool LoopDataPrefetch::runOnLoop(Loop *L) {
271271
bool MadeChange = false;
272272

273273
// Only prefetch in the inner-most loop
274-
if (!L->empty())
274+
if (!L->isInnermost())
275275
return MadeChange;
276276

277277
SmallPtrSet<const Value *, 32> EphValues;

llvm/lib/Transforms/Scalar/LoopDistribute.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ class LoopDistributeForLoop {
664664

665665
/// Try to distribute an inner-most loop.
666666
bool processLoop(std::function<const LoopAccessInfo &(Loop &)> &GetLAA) {
667-
assert(L->empty() && "Only process inner loops.");
667+
assert(L->isInnermost() && "Only process inner loops.");
668668

669669
LLVM_DEBUG(dbgs() << "\nLDist: In \""
670670
<< L->getHeader()->getParent()->getName()
@@ -982,7 +982,7 @@ static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
982982
for (Loop *TopLevelLoop : *LI)
983983
for (Loop *L : depth_first(TopLevelLoop))
984984
// We only handle inner-most loops.
985-
if (L->empty())
985+
if (L->isInnermost())
986986
Worklist.push_back(L);
987987

988988
// Now walk the identified inner loops.

llvm/lib/Transforms/Scalar/LoopFuse.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,7 @@ struct LoopFuser {
14831483
continue;
14841484
LI.changeLoopFor(BB, FC0.L);
14851485
}
1486-
while (!FC1.L->empty()) {
1486+
while (!FC1.L->isInnermost()) {
14871487
const auto &ChildLoopIt = FC1.L->begin();
14881488
Loop *ChildLoop = *ChildLoopIt;
14891489
FC1.L->removeChildLoop(ChildLoopIt);
@@ -1777,7 +1777,7 @@ struct LoopFuser {
17771777
continue;
17781778
LI.changeLoopFor(BB, FC0.L);
17791779
}
1780-
while (!FC1.L->empty()) {
1780+
while (!FC1.L->isInnermost()) {
17811781
const auto &ChildLoopIt = FC1.L->begin();
17821782
Loop *ChildLoop = *ChildLoopIt;
17831783
FC1.L->removeChildLoop(ChildLoopIt);

llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
12111211
bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
12121212
bool IsLoopMemset) {
12131213
if (ApplyCodeSizeHeuristics && CurLoop->getNumBlocks() > 1) {
1214-
if (!CurLoop->getParentLoop() && (!IsMemset || !IsLoopMemset)) {
1214+
if (CurLoop->isOutermost() && (!IsMemset || !IsLoopMemset)) {
12151215
LLVM_DEBUG(dbgs() << " " << CurLoop->getHeader()->getParent()->getName()
12161216
<< " : LIR " << (IsMemset ? "Memset" : "Memcpy")
12171217
<< " avoided: multi-block top-level loop\n");

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ void LoopInterchangeTransform::restructureLoops(
11971197
removeChildLoop(NewInner, NewOuter);
11981198
LI->changeTopLevelLoop(NewInner, NewOuter);
11991199
}
1200-
while (!NewOuter->empty())
1200+
while (!NewOuter->isInnermost())
12011201
NewInner->addChildLoop(NewOuter->removeChildLoop(NewOuter->begin()));
12021202
NewOuter->addChildLoop(NewInner);
12031203

llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
623623
for (Loop *TopLevelLoop : LI)
624624
for (Loop *L : depth_first(TopLevelLoop))
625625
// We only handle inner-most loops.
626-
if (L->empty())
626+
if (L->isInnermost())
627627
Worklist.push_back(L);
628628

629629
// Now walk the identified inner loops.

llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ class ConstantTerminatorFoldingImpl {
452452
if (LI.isLoopHeader(BB)) {
453453
assert(LI.getLoopFor(BB) != &L && "Attempt to remove current loop!");
454454
Loop *DL = LI.getLoopFor(BB);
455-
if (DL->getParentLoop()) {
455+
if (!DL->isOutermost()) {
456456
for (auto *PL = DL->getParentLoop(); PL; PL = PL->getParentLoop())
457457
for (auto *BB : DL->getBlocks())
458458
PL->removeBlockFromLoop(BB);

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -5619,7 +5619,7 @@ LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE,
56195619
if (IU.empty()) return;
56205620

56215621
// Skip nested loops until we can model them better with formulae.
5622-
if (!L->empty()) {
5622+
if (!L->isInnermost()) {
56235623
LLVM_DEBUG(dbgs() << "LSR skipping outer loop " << *L << "\n");
56245624
return;
56255625
}

llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ static Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
345345

346346
// Only analyze inner loops. We can't properly estimate cost of nested loops
347347
// and we won't visit inner loops again anyway.
348-
if (!L->empty())
348+
if (!L->isInnermost())
349349
return None;
350350

351351
// Don't simulate loops with a big or unknown tripcount

llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,7 @@ static Loop *cloneLoopNest(Loop &OrigRootL, Loop *RootParentL,
12141214
LI.addTopLevelLoop(ClonedRootL);
12151215
AddClonedBlocksToLoop(OrigRootL, *ClonedRootL);
12161216

1217-
if (OrigRootL.empty())
1217+
if (OrigRootL.isInnermost())
12181218
return ClonedRootL;
12191219

12201220
// If we have a nest, we can quickly clone the entire loop nest using an
@@ -2353,12 +2353,12 @@ static void unswitchNontrivialInvariants(
23532353
for (Loop *UpdatedL :
23542354
llvm::concat<Loop *>(NonChildClonedLoops, HoistedLoops)) {
23552355
UpdateLoop(*UpdatedL);
2356-
if (!UpdatedL->getParentLoop())
2356+
if (UpdatedL->isOutermost())
23572357
OuterExitL = nullptr;
23582358
}
23592359
if (IsStillLoop) {
23602360
UpdateLoop(L);
2361-
if (!L.getParentLoop())
2361+
if (L.isOutermost())
23622362
OuterExitL = nullptr;
23632363
}
23642364

llvm/lib/Transforms/Utils/LoopPeel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
304304
// Only try to peel innermost loops by default.
305305
// The constraint can be relaxed by the target in TTI.getUnrollingPreferences
306306
// or by the flag -unroll-allow-loop-nests-peeling.
307-
if (!PP.AllowLoopNestsPeeling && !L->empty())
307+
if (!PP.AllowLoopNestsPeeling && !L->isInnermost())
308308
return;
309309

310310
// If the user provided a peel count, use that.

llvm/lib/Transforms/Utils/LoopVersioning.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ bool runImpl(LoopInfo *LI, function_ref<const LoopAccessInfo &(Loop &)> GetLAA,
268268
for (Loop *TopLevelLoop : *LI)
269269
for (Loop *L : depth_first(TopLevelLoop))
270270
// We only handle inner-most loops.
271-
if (L->empty())
271+
if (L->isInnermost())
272272
Worklist.push_back(L);
273273

274274
// Now walk the identified inner loops.

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ bool LoopVectorizationLegality::isUniform(Value *V) {
431431
}
432432

433433
bool LoopVectorizationLegality::canVectorizeOuterLoop() {
434-
assert(!TheLoop->empty() && "We are not vectorizing an outer loop.");
434+
assert(!TheLoop->isInnermost() && "We are not vectorizing an outer loop.");
435435
// Store the result and return it at the end instead of exiting early, in case
436436
// allowExtraAnalysis is used to report multiple reasons for not vectorizing.
437437
bool Result = true;
@@ -1055,7 +1055,7 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
10551055
// Helper function to canVectorizeLoopNestCFG.
10561056
bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp,
10571057
bool UseVPlanNativePath) {
1058-
assert((UseVPlanNativePath || Lp->empty()) &&
1058+
assert((UseVPlanNativePath || Lp->isInnermost()) &&
10591059
"VPlan-native path is not enabled.");
10601060

10611061
// TODO: ORE should be improved to show more accurate information when an
@@ -1165,7 +1165,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
11651165

11661166
// Specific checks for outer loops. We skip the remaining legal checks at this
11671167
// point because they don't support outer loops.
1168-
if (!TheLoop->empty()) {
1168+
if (!TheLoop->isInnermost()) {
11691169
assert(UseVPlanNativePath && "VPlan-native path is not enabled.");
11701170

11711171
if (!canVectorizeOuterLoop()) {
@@ -1182,7 +1182,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
11821182
return Result;
11831183
}
11841184

1185-
assert(TheLoop->empty() && "Inner loop expected.");
1185+
assert(TheLoop->isInnermost() && "Inner loop expected.");
11861186
// Check if we can if-convert non-single-bb loops.
11871187
unsigned NumBlocks = TheLoop->getNumBlocks();
11881188
if (NumBlocks != 1 && !canVectorizeWithIfConvert()) {

0 commit comments

Comments
 (0)