LLVM 24.0.0git
GenericLoopInfoImpl.h
Go to the documentation of this file.
1//===- GenericLoopInfoImp.h - Generic Loop Info Implementation --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This fle contains the implementation of GenericLoopInfo. It should only be
10// included in files that explicitly instantiate a GenericLoopInfo.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
15#define LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
16
19#include "llvm/ADT/STLExtras.h"
21
22namespace llvm {
23
24//===----------------------------------------------------------------------===//
25// APIs for simple analysis of the loop. See header notes.
26
27/// getExitingBlocks - Return all blocks inside the loop that have successors
28/// outside of the loop. These are the blocks _inside of the current loop_
29/// which branch out. The returned list is always unique.
30///
31template <class BlockT, class LoopT>
33 SmallVectorImpl<BlockT *> &ExitingBlocks) const {
34 assert(!isInvalid() && "Loop not in a valid state!");
35 for (const auto BB : blocks())
36 for (auto *Succ : children<BlockT *>(BB))
37 if (!contains(Succ)) {
38 // Not in current loop? It must be an exit block.
39 ExitingBlocks.push_back(BB);
40 break;
41 }
42}
43
44/// getExitingBlock - If getExitingBlocks would return exactly one block,
45/// return that block. Otherwise return null.
46template <class BlockT, class LoopT>
48 assert(!isInvalid() && "Loop not in a valid state!");
49 auto notInLoop = [&](BlockT *BB) { return !contains(BB); };
50 auto isExitBlock = [&](BlockT *BB, bool AllowRepeats) -> BlockT * {
51 assert(!AllowRepeats && "Unexpected parameter value.");
52 // Child not in current loop? It must be an exit block.
53 return any_of(children<BlockT *>(BB), notInLoop) ? BB : nullptr;
54 };
55
57}
58
59/// getExitBlocks - Return all of the successor blocks of this loop. These
60/// are the blocks _outside of the current loop_ which are branched to.
61///
62template <class BlockT, class LoopT>
64 SmallVectorImpl<BlockT *> &ExitBlocks) const {
65 assert(!isInvalid() && "Loop not in a valid state!");
66 for (const auto BB : blocks())
67 for (auto *Succ : children<BlockT *>(BB))
68 if (!contains(Succ))
69 // Not in current loop? It must be an exit block.
70 ExitBlocks.push_back(Succ);
71}
72
73/// getExitBlock - If getExitBlocks would return exactly one block,
74/// return that block. Otherwise return null.
75template <class BlockT, class LoopT>
76std::pair<BlockT *, bool> getExitBlockHelper(const LoopBase<BlockT, LoopT> *L,
77 bool Unique) {
78 assert(!L->isInvalid() && "Loop not in a valid state!");
79 auto notInLoop = [&](BlockT *BB,
80 bool AllowRepeats) -> std::pair<BlockT *, bool> {
81 assert(AllowRepeats == Unique && "Unexpected parameter value.");
82 return {!L->contains(BB) ? BB : nullptr, false};
83 };
84 auto singleExitBlock = [&](BlockT *BB,
85 bool AllowRepeats) -> std::pair<BlockT *, bool> {
86 assert(AllowRepeats == Unique && "Unexpected parameter value.");
88 AllowRepeats);
89 };
90 return find_singleton_nested<BlockT>(L->blocks(), singleExitBlock, Unique);
91}
92
93template <class BlockT, class LoopT>
95 auto RC = getExitBlockHelper(&L, false);
96 if (RC.second)
97 // found multiple exit blocks
98 return false;
99 // return true if there is no exit block
100 return !RC.first;
101}
102
103/// getExitBlock - If getExitBlocks would return exactly one block,
104/// return that block. Otherwise return null.
105template <class BlockT, class LoopT>
107 return getExitBlockHelper(this, false).first;
108}
109
110template <class BlockT, class LoopT>
112 // Each predecessor of each exit block of a normal loop is contained
113 // within the loop.
114 SmallVector<BlockT *, 4> UniqueExitBlocks;
115 getUniqueExitBlocks(UniqueExitBlocks);
116 for (BlockT *EB : UniqueExitBlocks)
117 for (BlockT *Predecessor : inverse_children<BlockT *>(EB))
118 if (!contains(Predecessor))
119 return false;
120 // All the requirements are met.
121 return true;
122}
123
124// Helper function to get unique loop exits. Pred is a predicate pointing to
125// BasicBlocks in a loop which should be considered to find loop exits.
126template <class BlockT, class LoopT, typename PredicateT>
127void getUniqueExitBlocksHelper(const LoopT *L,
128 SmallVectorImpl<BlockT *> &ExitBlocks,
129 PredicateT Pred) {
130 assert(!L->isInvalid() && "Loop not in a valid state!");
132 auto Filtered = make_filter_range(L->blocks(), Pred);
133 for (BlockT *BB : Filtered)
134 for (BlockT *Successor : children<BlockT *>(BB))
135 if (!L->contains(Successor))
136 if (Visited.insert(Successor).second)
137 ExitBlocks.push_back(Successor);
138}
139
140template <class BlockT, class LoopT>
142 SmallVectorImpl<BlockT *> &ExitBlocks) const {
143 getUniqueExitBlocksHelper(this, ExitBlocks,
144 [](const BlockT *BB) { return true; });
145}
146
147template <class BlockT, class LoopT>
149 SmallVectorImpl<BlockT *> &ExitBlocks) const {
150 const BlockT *Latch = getLoopLatch();
151 assert(Latch && "Latch block must exists");
152 getUniqueExitBlocksHelper(this, ExitBlocks,
153 [Latch](const BlockT *BB) { return BB != Latch; });
154}
155
156template <class BlockT, class LoopT>
158 return getExitBlockHelper(this, true).first;
159}
160
161template <class BlockT, class LoopT>
162BlockT *
164 BlockT *Latch = L.getLoopLatch();
165 assert(Latch && "Latch block must exists");
166 auto IsExitBlock = [&L](BlockT *BB, bool AllowRepeats) -> BlockT * {
167 assert(!AllowRepeats && "Unexpected parameter value.");
168 return !L.contains(BB) ? BB : nullptr;
169 };
170 return find_singleton<BlockT>(children<BlockT *>(Latch), IsExitBlock);
171}
172
173/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
174template <class BlockT, class LoopT>
176 const LoopT &L, SmallVectorImpl<Edge> &ExitEdges) const {
177 for (const auto BB : L.blocks())
178 for (auto *Succ : children<BlockT *>(BB))
179 if (!L.contains(Succ))
180 // Not in current loop? It must be an exit block.
181 ExitEdges.emplace_back(BB, Succ);
182}
183
184namespace detail {
185template <class BlockT>
186using has_hoist_check = decltype(&BlockT::isLegalToHoistInto);
187
188template <class BlockT>
190
191/// SFINAE functions that dispatch to the isLegalToHoistInto member function or
192/// return false, if it doesn't exist.
193template <class BlockT> bool isLegalToHoistInto(BlockT *Block) {
195 return Block->isLegalToHoistInto();
196 return false;
197}
198} // namespace detail
199
200/// getLoopPreheader - If there is a preheader for this loop, return it. A
201/// loop has a preheader if there is only one edge to the header of the loop
202/// from outside of the loop and it is legal to hoist instructions into the
203/// predecessor. If this is the case, the block branching to the header of the
204/// loop is the preheader node.
205///
206/// This method returns null if there is no preheader for the loop.
207///
208template <class BlockT, class LoopT>
210 assert(!isInvalid() && "Loop not in a valid state!");
211 // Keep track of nodes outside the loop branching to the header...
212 BlockT *Out = getLoopPredecessor();
213 if (!Out)
214 return nullptr;
215
216 // Make sure we are allowed to hoist instructions into the predecessor.
218 return nullptr;
219
220 // Make sure there is only one exit out of the preheader.
222 return nullptr; // Multiple exits from the block, must not be a preheader.
223
224 // The predecessor has exactly one successor, so it is a preheader.
225 return Out;
226}
227
228/// getLoopPredecessor - If the given loop's header has exactly one unique
229/// predecessor outside the loop, return it. Otherwise return null.
230/// This is less strict that the loop "preheader" concept, which requires
231/// the predecessor to have exactly one successor.
232///
233template <class BlockT, class LoopT>
235 assert(!isInvalid() && "Loop not in a valid state!");
236 // Keep track of nodes outside the loop branching to the header...
237 BlockT *Out = nullptr;
238
239 // Loop over the predecessors of the header node...
240 BlockT *Header = getHeader();
241 for (const auto Pred : inverse_children<BlockT *>(Header)) {
242 if (!contains(Pred)) { // If the block is not in the loop...
243 if (Out && Out != Pred)
244 return nullptr; // Multiple predecessors outside the loop
245 Out = Pred;
246 }
247 }
248
249 return Out;
250}
251
252/// getLoopLatch - If there is a single latch block for this loop, return it.
253/// A latch block is a block that contains a branch back to the header.
254template <class BlockT, class LoopT>
256 assert(!isInvalid() && "Loop not in a valid state!");
257 BlockT *Header = getHeader();
258 BlockT *Latch = nullptr;
259 for (const auto Pred : inverse_children<BlockT *>(Header)) {
260 if (contains(Pred)) {
261 if (Latch)
262 return nullptr;
263 Latch = Pred;
264 }
265 }
266
267 return Latch;
268}
269
270//===----------------------------------------------------------------------===//
271// APIs for updating loop information after changing the CFG
273
274/// addBasicBlockToLoop - This method is used by other analyses to update loop
275/// information. NewBB is set to be a new member of the current loop.
276/// Because of this, it is added as a member of all parent loops, and is added
277/// to the specified LoopInfo object as being in the current basic block. It
278/// is not valid to replace the loop header with this method.
279///
280template <class BlockT, class LoopT>
282 BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) {
283 assert(!isInvalid() && "Loop not in a valid state!");
284#ifndef NDEBUG
285 if (!getBlocks().empty()) {
286 auto SameHeader = LIB[getHeader()];
287 assert(contains(SameHeader) && getHeader() == SameHeader->getHeader() &&
288 "Incorrect LI specified for this loop!");
289 }
290#endif
291 assert(NewBB && "Cannot add a null basic block to the loop!");
292 assert(!LIB[NewBB] && "BasicBlock already in the loop!");
293
294 LoopT *L = static_cast<LoopT *>(this);
295
296 // Add the loop mapping to the LoopInfo object...
297 LIB.changeLoopFor(NewBB, L);
299 // Add the basic block to this loop and all parent loops...
300 while (L) {
301 L->addBlockEntry(NewBB);
302 L = L->getParentLoop();
303 }
304}
305
306/// replaceChildLoopWith - This is used when splitting loops up. It replaces
307/// the OldChild entry in our children list with NewChild, and updates the
308/// parent pointer of OldChild to be null and the NewChild to be this loop.
309/// This updates the loop depth of the new child.
310template <class BlockT, class LoopT>
312 LoopT *NewChild) {
313 assert(!isInvalid() && "Loop not in a valid state!");
314 assert(OldChild->ParentLoop == this && "This loop is already broken!");
315 assert(!NewChild->ParentLoop && "NewChild already has a parent!");
316 typename std::vector<LoopT *>::iterator I = find(SubLoops, OldChild);
317 assert(I != SubLoops.end() && "OldChild not in loop!");
318 *I = NewChild;
319 OldChild->ParentLoop = nullptr;
320 NewChild->ParentLoop = static_cast<LoopT *>(this);
321}
322
323/// verifyLoop - Verify loop structure
324template <class BlockT, class LoopT>
326 assert(!isInvalid() && "Loop not in a valid state!");
327#ifndef NDEBUG
328 assert(!getBlocks().empty() && "Loop header is missing");
329
330 // Setup for using a depth-first iterator to visit every block in the loop.
332 getExitBlocks(ExitBBs);
334 VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
335
336 // Keep track of the BBs visited.
337 SmallPtrSet<BlockT *, 8> VisitedBBs;
338
339 // Check the individual blocks.
340 for (BlockT *BB : depth_first_ext(getHeader(), VisitSet)) {
342 [&](BlockT *B) { return contains(B); }) &&
343 "Loop block has no in-loop successors!");
344
346 [&](BlockT *B) { return contains(B); }) &&
347 "Loop block has no in-loop predecessors!");
348
349 SmallVector<BlockT *, 2> OutsideLoopPreds;
350 for (BlockT *B : inverse_children<BlockT *>(BB))
351 if (!contains(B))
352 OutsideLoopPreds.push_back(B);
353
354 if (BB == getHeader()) {
355 assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");
356 } else if (!OutsideLoopPreds.empty()) {
357 // A non-header loop block shouldn't be reachable from outside the loop,
358 // though it is permitted if the predecessor is not itself actually
359 // reachable.
360 BlockT *EntryBB = &BB->getParent()->front();
361 for (BlockT *CB : depth_first(EntryBB))
362 for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
363 assert(CB != OutsideLoopPreds[i] &&
364 "Loop has multiple entry points!");
365 }
366 assert(BB != &getHeader()->getParent()->front() &&
367 "Loop contains function entry block!");
368
369 VisitedBBs.insert(BB);
370 }
371
372 if (VisitedBBs.size() != getNumBlocks()) {
373 dbgs() << "The following blocks are unreachable in the loop: ";
374 for (auto *BB : getBlocks()) {
375 if (!VisitedBBs.count(BB)) {
376 dbgs() << *BB << "\n";
377 }
378 }
379 assert(false && "Unreachable block in loop");
380 }
382 // Check the subloops.
383 for (iterator I = begin(), E = end(); I != E; ++I)
384 // Each block in each subloop should be contained within this loop.
385 for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
386 BI != BE; ++BI) {
387 assert(contains(*BI) &&
388 "Loop does not contain all the blocks of a subloop!");
389 }
390
391 // Check the parent loop pointer.
392 if (ParentLoop) {
393 assert(is_contained(ParentLoop->getSubLoops(), this) &&
394 "Loop is not a subloop of its parent!");
395 }
396#endif
397}
398
399/// verifyLoop - Verify loop structure of this loop and all nested loops.
400template <class BlockT, class LoopT>
403 assert(!isInvalid() && "Loop not in a valid state!");
404 Loops->insert(static_cast<const LoopT *>(this));
405 // Verify this loop.
406 verifyLoop();
407 // Verify the subloops.
408 for (iterator I = begin(), E = end(); I != E; ++I)
409 (*I)->verifyLoopNest(Loops);
410}
411
412template <class BlockT, class LoopT>
414 bool PrintNested, unsigned Depth) const {
415 OS.indent(Depth * 2);
416 if (static_cast<const LoopT *>(this)->isAnnotatedParallel())
417 OS << "Parallel ";
418 OS << "Loop at depth " << getLoopDepth() << " containing: ";
419
420 BlockT *H = getHeader();
421 for (unsigned i = 0; i < getBlocks().size(); ++i) {
422 BlockT *BB = getBlocks()[i];
423 if (!Verbose) {
424 if (i)
425 OS << ",";
426 BB->printAsOperand(OS, false);
427 } else {
428 OS << '\n';
429 }
430
431 if (BB == H)
432 OS << "<header>";
433 if (isLoopLatch(BB))
434 OS << "<latch>";
435 if (isLoopExiting(BB))
436 OS << "<exiting>";
437 if (Verbose)
438 BB->print(OS);
439 }
440
441 if (PrintNested) {
442 OS << "\n";
443
444 for (iterator I = begin(), E = end(); I != E; ++I)
445 (*I)->print(OS, /*Verbose*/ false, PrintNested, Depth + 2);
446 }
447}
448
449//===----------------------------------------------------------------------===//
450/// Stable LoopInfo Analysis - Build a loop tree using stable iterators so the
451/// result does / not depend on use list (block predecessor) order.
452///
453
454/// Discover a subloop with the specified backedges such that: All blocks within
455/// this loop are mapped to this loop or a subloop. And all subloops within this
456/// loop have their parent loop set to this loop or a subloop.
457template <class BlockT, class LoopT>
458void LoopInfoBase<BlockT, LoopT>::discoverAndMapSubloop(
459 LoopT *L, BlockT *Header, ArrayRef<BlockT *> Backedges,
460 const DominatorTreeBase<BlockT, false> &DomTree) {
461 using InvBlockTraits = GraphTraits<Inverse<BlockT *>>;
462
463 unsigned NumSubloops = 0;
464
465 // Perform a backward CFG traversal using a worklist.
466 std::vector<BlockT *> ReverseCFGWorklist(Backedges.begin(), Backedges.end());
467 while (!ReverseCFGWorklist.empty()) {
468 BlockT *PredBB = ReverseCFGWorklist.back();
469 ReverseCFGWorklist.pop_back();
471 LoopT *Subloop = getLoopFor(PredBB);
472 if (!Subloop) {
473 if (!DomTree.isReachableFromEntry(PredBB))
474 continue;
475
476 // This is an undiscovered block. Map it to the current loop.
477 changeLoopFor(PredBB, L);
478 if (PredBB == Header)
479 continue;
480 // Push all block predecessors on the worklist.
481 ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),
482 InvBlockTraits::child_begin(PredBB),
483 InvBlockTraits::child_end(PredBB));
484 } else {
485 // This is a discovered block. Find its outermost discovered loop.
486 Subloop = Subloop->getOutermostLoop();
487
488 // If it is already discovered to be a subloop of this loop, continue.
489 if (Subloop == L)
490 continue;
491
492 // Discover a subloop of this loop.
493 Subloop->setParentLoop(L);
494 ++NumSubloops;
495 PredBB = pendingHeader(Subloop);
496 // Continue traversal along predecessors that are not loop-back edges from
497 // within this subloop tree itself. Note that a predecessor may directly
498 // reach another subloop that is not yet discovered to be a subloop of
499 // this loop, which we must traverse.
500 for (const auto Pred : inverse_children<BlockT *>(PredBB)) {
501 if (getLoopFor(Pred) != Subloop)
502 ReverseCFGWorklist.push_back(Pred);
503 }
504 }
505 }
506 L->reserveSubLoops(NumSubloops);
507}
508
509/// Analyze LoopInfo discovers loops during a reverse preorder DominatorTree
510/// traversal interleaved with backward CFG traversals within each subloop
511/// (discoverAndMapSubloop). The backward traversal skips inner subloops, so
512/// this part of the algorithm is linear in the number of CFG edges.
513///
514/// Then build a loop-contiguous reverse postorder for in-loops blocks. Lists
515/// are header-first with each subloop's blocks contiguous, ordered by first
516/// appearance in RPO; SubLoops keep program order, TopLevelLoops reverse
517/// program order.
518template <class BlockT, class LoopT>
520 const DomTreeNodeBase<BlockT> *DomRoot = DomTree.getRootNode();
521 ParentPtr = DomRoot->getBlock()->getParent();
522 BlockNumberEpoch = GraphTraits<ParentT>::getNumberEpoch(ParentPtr);
523 BBMap.resize(GraphTraits<ParentT>::getMaxNumber(ParentPtr));
524
525 // Visit dominator tree nodes in reverse preorder: like postorder, this
526 // guarantees a sub-loop is discovered before the outer loop.
527 DomTree.updateDFSNumbers();
529 DomRoot->getDFSNumOut());
530 for (const DomTreeNodeBase<BlockT> *Node : DomTree.nodes())
531 PreorderNodes[Node->getDFSNumIn()] = Node;
532
533 bool HasLoops = false;
534 for (const DomTreeNodeBase<BlockT> *DomNode : llvm::reverse(PreorderNodes)) {
535 BlockT *Header = DomNode->getBlock();
536 SmallVector<BlockT *, 4> Backedges;
537
538 // Check each predecessor of the potential loop header.
539 for (const auto Backedge : inverse_children<BlockT *>(Header)) {
540 // If Header dominates predBB, this is a new loop. Collect the backedges.
541 const DomTreeNodeBase<BlockT> *BackedgeNode = DomTree.getNode(Backedge);
542 if (BackedgeNode && DomTree.dominates(DomNode, BackedgeNode))
543 Backedges.push_back(Backedge);
544 }
545 // Perform a backward CFG traversal to discover and map blocks in this loop.
546 if (!Backedges.empty()) {
547 HasLoops = true;
548 LoopT *L = allocateLoop(Header);
549 discoverAndMapSubloop(L, Header, Backedges, DomTree);
550 }
551 }
552 // Most functions have no loops; skip the layout construction.
553 if (!HasLoops)
554 return;
555
556 // Record each in-loop block with its innermost loop in forward CFG postorder,
557 // and build the loop list in PO.
560 PO.reserve(BBMap.size());
561 for (BlockT *BB : post_order(ParentPtr)) {
562 LoopT *L = lookupLoopFor(BB);
563 if (!L)
564 continue;
565 PO.emplace_back(BB, L);
566 ++L->BlockLen;
567 if (BB != pendingHeader(L))
568 continue;
569 LoopsPO.push_back(L);
570 if (LoopT *Parent = L->getParentLoop())
571 Parent->BlockLen += L->BlockLen;
572 else
573 TopLevelLoops.push_back(L);
574 }
575 // Headers are dominator-tree nodes, hence reachable and in the postorder.
576 assert(!LoopsPO.empty() && "discovered loops but found no header");
577
578 BlockLayout.reset(new BlockT *[PO.size()]);
579 BlockT **RootCursor = BlockLayout.get();
580 for (auto &[BB, L] : llvm::reverse(PO)) {
581 if (L->BlockCapacity == 0) {
582 // The first block of a L is its the header. Carve its slice from the
583 // parent (already visited)'s cursor.
584 if (LoopT *Parent = L->getParentLoop()) {
585 assert(Parent->BlockCapacity != 0 &&
586 "parent slice not carved before child");
587 L->BlockData = Parent->BlockData + Parent->BlockCapacity;
588 Parent->BlockCapacity += L->BlockLen;
589 Parent->SubLoops.push_back(L);
590 } else {
591 L->BlockData = RootCursor;
592 RootCursor += L->BlockLen;
593 }
594 }
595 // Each block lands once, at its innermost loop's cursor.
596 L->BlockData[L->BlockCapacity++] = BB;
597 }
598
599 // Mark every slice as borrowed from BlockLayout; a later mutation copies it
600 // into private storage (see materializeBlocks).
601 for (LoopT *L : LoopsPO) {
602 assert(L->BlockCapacity == L->BlockLen && "layout slice not fully used");
603 L->BlockCapacity = LoopT::BorrowedCapacity;
604 }
605}
606
607template <class BlockT, class LoopT>
610 SmallVector<LoopT *, 4> PreOrderLoops;
611 // The outer-most loop actually goes into the result in the same relative
612 // order as we walk it. But LoopInfo stores the top level loops in reverse
613 // program order so for here we reverse it to get forward program order.
614 // FIXME: If we change the order of LoopInfo we will want to remove the
615 // reverse here.
616 for (LoopT *RootL : reverse(*this)) {
617 PreOrderLoops.push_back(RootL);
618 LoopT::getInnerLoopsInPreorder(*RootL, PreOrderLoops);
619 }
620
621 return PreOrderLoops;
622}
623
624template <class BlockT, class LoopT>
627 SmallVector<LoopT *, 4> PreOrderLoops, PreOrderWorklist;
628 // The outer-most loop actually goes into the result in the same relative
629 // order as we walk it. LoopInfo stores the top level loops in reverse
630 // program order so we walk in order here.
631 // FIXME: If we change the order of LoopInfo we will want to add a reverse
632 // here.
633 for (LoopT *RootL : *this) {
634 assert(PreOrderWorklist.empty() &&
635 "Must start with an empty preorder walk worklist.");
636 PreOrderWorklist.push_back(RootL);
637 do {
638 LoopT *L = PreOrderWorklist.pop_back_val();
639 // Sub-loops are stored in forward program order, but will process the
640 // worklist backwards so we can just append them in order.
641 PreOrderWorklist.append(L->begin(), L->end());
642 PreOrderLoops.push_back(L);
643 } while (!PreOrderWorklist.empty());
644 }
645
646 return PreOrderLoops;
647}
648
649template <class BlockT, class LoopT>
651 LoopT *B) const {
652 if (!A || !B)
653 return nullptr;
654
655 // If loops A and B have different depth replace them with parent loop
656 // until they have the same depth.
657 unsigned DepthA = A->getLoopDepth(), DepthB = B->getLoopDepth();
658 for (; DepthA > DepthB; --DepthA)
659 A = A->getParentLoop();
660 for (; DepthB > DepthA; --DepthB)
661 B = B->getParentLoop();
662
663 // Loops A and B are at same depth but may be disjoint, replace them with
664 // parent loops until we find loop that contains both or we run out of
665 // parent loops.
666 while (A != B) {
667 A = A->getParentLoop();
668 B = B->getParentLoop();
669 }
670
671 return A;
672}
673
674template <class BlockT, class LoopT>
676 BlockT *B) const {
678}
679
680// Debugging
681template <class BlockT, class LoopT>
683 for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
684 TopLevelLoops[i]->print(OS);
685}
686
687template <typename T>
688bool compareVectors(std::vector<T> &BB1, std::vector<T> &BB2) {
689 llvm::sort(BB1);
690 llvm::sort(BB2);
691 return BB1 == BB2;
692}
693
694template <class BlockT, class LoopT>
697 const LoopT &L) {
698 LoopHeaders[L.getHeader()] = &L;
699 for (LoopT *SL : L)
700 addInnerLoopsToHeadersMap(LoopHeaders, LI, *SL);
701}
702
703#ifndef NDEBUG
704template <class BlockT, class LoopT>
705static void compareLoops(const LoopT *L, const LoopT *OtherL,
706 DenseMap<BlockT *, const LoopT *> &OtherLoopHeaders) {
707 BlockT *H = L->getHeader();
708 BlockT *OtherH = OtherL->getHeader();
709 assert(H == OtherH &&
710 "Mismatched headers even though found in the same map entry!");
711
712 assert(L->getLoopDepth() == OtherL->getLoopDepth() &&
713 "Mismatched loop depth!");
714 const LoopT *ParentL = L, *OtherParentL = OtherL;
715 do {
716 assert(ParentL->getHeader() == OtherParentL->getHeader() &&
717 "Mismatched parent loop headers!");
718 ParentL = ParentL->getParentLoop();
719 OtherParentL = OtherParentL->getParentLoop();
720 } while (ParentL);
721
722 for (const LoopT *SubL : *L) {
723 BlockT *SubH = SubL->getHeader();
724 const LoopT *OtherSubL = OtherLoopHeaders.lookup(SubH);
725 assert(OtherSubL && "Inner loop is missing in computed loop info!");
726 OtherLoopHeaders.erase(SubH);
727 compareLoops(SubL, OtherSubL, OtherLoopHeaders);
728 }
729
730 std::vector<BlockT *> BBs = L->getBlocks();
731 std::vector<BlockT *> OtherBBs = OtherL->getBlocks();
732 assert(compareVectors(BBs, OtherBBs) &&
733 "Mismatched basic blocks in the loops!");
734}
735#endif
736
737template <class BlockT, class LoopT>
739 const DomTreeBase<BlockT> &DomTree) const {
741 for (iterator I = begin(), E = end(); I != E; ++I) {
742 assert((*I)->isOutermost() && "Top-level loop has a parent!");
743 (*I)->verifyLoopNest(&Loops);
744 }
745
746// Verify that blocks are mapped to valid loops.
747#ifndef NDEBUG
748 // Every loop must point back at this LoopInfo (see resetLoopInfoOwners).
749 for (const LoopT *L : Loops)
750 assert(L->LI == this && "Loop has a stale owning-LoopInfo back-pointer");
751
752 // Recompute the innermost loop of each block from the loops' block lists,
753 // which are maintained independently of BBMap. Using contains() here would
754 // derive from BBMap itself and check nothing.
755 SmallVector<const LoopT *> Innermost(BBMap.size());
757 while (!Worklist.empty()) {
758 const LoopT *L = Worklist.pop_back_val();
759 // A loop is visited before its children, so a child's blocks overwrite the
760 // entries written by its ancestors.
761 for (const BlockT *BB : L->getBlocks()) {
763 assert(Number < Innermost.size() && "block missing from BBMap");
764 Innermost[Number] = L;
765 }
766 Worklist.append(L->begin(), L->end());
767 }
768
769 for (auto [Number, L] : enumerate(BBMap)) {
770 assert((!L || Loops.count(L)) && "orphaned loop");
771 assert(L == Innermost[Number] &&
772 "BBMap should point to the innermost loop containing the block");
773 }
774
775 // Recompute LoopInfo to verify loops structure.
777 OtherLI.analyze(DomTree);
778
779 // Build a map we can use to move from our LI to the computed one. This
780 // allows us to ignore the particular order in any layer of the loop forest
781 // while still comparing the structure.
782 DenseMap<BlockT *, const LoopT *> OtherLoopHeaders;
783 for (LoopT *L : OtherLI)
784 addInnerLoopsToHeadersMap(OtherLoopHeaders, OtherLI, *L);
785
786 // Walk the top level loops and ensure there is a corresponding top-level
787 // loop in the computed version and then recursively compare those loop
788 // nests.
789 for (LoopT *L : *this) {
790 BlockT *Header = L->getHeader();
791 const LoopT *OtherL = OtherLoopHeaders.lookup(Header);
792 assert(OtherL && "Top level loop is missing in computed loop info!");
793 // Now that we've matched this loop, erase its header from the map.
794 OtherLoopHeaders.erase(Header);
795 // And recursively compare these loops.
796 compareLoops(L, OtherL, OtherLoopHeaders);
797 }
798
799 // Any remaining entries in the map are loops which were found when computing
800 // a fresh LoopInfo but not present in the current one.
801 if (!OtherLoopHeaders.empty()) {
802 for (const auto &HeaderAndLoop : OtherLoopHeaders)
803 dbgs() << "Found new loop: " << *HeaderAndLoop.second << "\n";
804 llvm_unreachable("Found new loops when recomputing LoopInfo!");
805 }
806#endif
807}
808
809} // namespace llvm
810
811#endif // LLVM_SUPPORT_GENERICLOOPINFOIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
bbsections Prepares for basic block by splitting functions into clusters of basic blocks
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
Hexagon Hardware Loops
static bool isExitBlock(BasicBlock *BB, const SmallVectorImpl< BasicBlock * > &ExitBlocks)
Return true if the specified block is in the list.
Definition LCSSA.cpp:68
#define I(x, y, z)
Definition MD5.cpp:57
#define H(x, y, z)
Definition MD5.cpp:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:250
bool erase(const KeyT &Val)
Definition DenseMap.h:377
bool empty() const
Definition DenseMap.h:171
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Base class for the actual dominator tree node.
NodeT * getBlock() const
unsigned getDFSNumOut() const
Core dominator tree base class.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Instances of this class are used to represent loops that are detected in the flow graph.
bool isAnnotatedParallel() const
Returns true if the loop is annotated parallel.
typename std::vector< Loop * >::const_iterator iterator
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
void verifyLoop() const
Verify loop structure.
void verifyLoopNest(DenseSet< const LoopT * > *Loops) const
Verify loop structure of this loop and all nested loops.
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
BlockT * getHeader() const
unsigned getLoopDepth() const
Return the nesting level of this loop.
void print(raw_ostream &OS, bool Verbose=false, bool PrintNested=true, unsigned Depth=0) const
Print loop with all the BBs inside it.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
bool isInvalid() const
Return true if this loop is no longer valid.
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it.
bool isLoopLatch(const BlockT *BB) const
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild)
This is used when splitting loops up.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
ArrayRef< BasicBlock * > getBlocks() const
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop.
bool hasDedicatedExits() const
Return true if no exit block for the loop has a predecessor that is outside the loop.
void getUniqueNonLatchExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop except successors from Latch block are not considered...
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
typename ArrayRef< BasicBlock * >::const_iterator block_iterator
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
This class builds and contains all of the top-level loop structures in the specified function.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
bool hasNoExitBlocks(const LoopT &L) const
Return true if L does not have any exit blocks.
SmallVector< LoopT *, 4 > getLoopsInReverseSiblingPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in reverse p...
void print(raw_ostream &OS) const
iterator end() const
SmallVector< LoopT *, 4 > getLoopsInPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
LoopT * getSmallestCommonLoop(LoopT *A, LoopT *B) const
Find the innermost loop containing both given loops.
typename std::vector< LoopT * >::const_iterator iterator
iterator/begin/end - The interface to the top-level loops in the current function.
iterator begin() const
BlockT * getUniqueLatchExitBlock(const LoopT &L) const
Return the unique exit block for the latch of L, or null if there are multiple different exit blocks ...
void getExitEdges(const LoopT &L, SmallVectorImpl< Edge > &ExitEdges) const
Return all pairs of (inside_block,outside_block).
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void changeLoopFor(const BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
size_type size() const
Definition SmallPtrSet.h:99
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
decltype(&BlockT::isLegalToHoistInto) has_hoist_check
llvm::is_detected< has_hoist_check, BlockT > detect_has_hoist_check
bool isLegalToHoistInto(BlockT *Block)
SFINAE functions that dispatch to the isLegalToHoistInto member function or return false,...
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static void compareLoops(const LoopT *L, const LoopT *OtherL, DenseMap< BlockT *, const LoopT * > &OtherLoopHeaders)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
DominatorTreeBase< T, false > DomTreeBase
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
Definition STLExtras.h:299
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:551
std::pair< BlockT *, bool > getExitBlockHelper(const LoopBase< BlockT, LoopT > *L, bool Unique)
getExitBlock - If getExitBlocks would return exactly one block, return that block.
std::pair< T *, bool > find_singleton_nested(R &&Range, Predicate P, bool AllowRepeats=false)
Return a pair consisting of the single value in Range that satisfies P(<member of Range> ,...
Definition STLExtras.h:1862
T * find_singleton(R &&Range, Predicate P, bool AllowRepeats=false)
Return the single value in Range that satisfies P(<member of Range> *, AllowRepeats)->T * returning n...
Definition STLExtras.h:1837
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
void addInnerLoopsToHeadersMap(DenseMap< BlockT *, const LoopT * > &LoopHeaders, const LoopInfoBase< BlockT, LoopT > &LI, const LoopT &L)
void getUniqueExitBlocksHelper(const LoopT *L, SmallVectorImpl< BlockT * > &ExitBlocks, PredicateT Pred)
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
bool compareVectors(std::vector< T > &BB1, std::vector< T > &BB2)
iterator_range< df_iterator< T > > depth_first(const T &G)
std::pair< iterator, bool > insert(NodeRef N)