LLVM: include/llvm/Support/GenericLoopInfo.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#ifndef LLVM_SUPPORT_GENERICLOOPINFO_H
41#define LLVM_SUPPORT_GENERICLOOPINFO_H
42
49
50namespace llvm {
51
52template <class N, class M> class LoopInfoBase;
53template <class N, class M> class LoopBase;
54
55
56
57
58
59template <class BlockT, class LoopT> class LoopBase {
60 LoopT *ParentLoop;
61
62 std::vector<LoopT *> SubLoops;
63
64
65 std::vector<BlockT *> Blocks;
66
68
69#if LLVM_ENABLE_ABI_BREAKING_CHECKS
70
71 bool IsInvalid = false;
72#endif
73
74 LoopBase(const LoopBase<BlockT, LoopT> &) = delete;
75 const LoopBase<BlockT, LoopT> &
76 operator=(const LoopBase<BlockT, LoopT> &) = delete;
77
78public:
79
80
81
84 unsigned D = 1;
85 for (const LoopT *CurLoop = ParentLoop; CurLoop;
86 CurLoop = CurLoop->ParentLoop)
87 ++D;
88 return D;
89 }
91
92
93
94
95
96
97
98
100
101
102
104 const LoopT *L = static_cast<const LoopT *>(this);
105 while (L->ParentLoop)
106 L = L->ParentLoop;
107 return L;
108 }
109
111 LoopT *L = static_cast<LoopT *>(this);
112 while (L->ParentLoop)
113 L = L->ParentLoop;
114 return L;
115 }
116
117
120 ParentLoop = L;
121 }
122
123
126 if (L == this)
127 return true;
128 if (!L)
129 return false;
130 return contains(L->getParentLoop());
131 }
132
133
136 return DenseBlockSet.count(BB);
137 }
138
139
140 template bool contains(const InstT *Inst) const {
141 return contains(Inst->getParent());
142 }
143
144
147 return SubLoops;
148 }
151 return SubLoops;
152 }
153 using iterator = typename std::vector<LoopT *>::const_iterator;
155 typename std::vector<LoopT *>::const_reverse_iterator;
160
161
162
163
164
165
166
168
169
171
172
184
185
186
189 return Blocks.size();
190 }
191
192
193
198
199
202 return DenseBlockSet;
203 }
204
205
208 return DenseBlockSet;
209 }
210
211
212
213
214
215
216
218#if LLVM_ENABLE_ABI_BREAKING_CHECKS
219 return IsInvalid;
220#else
221 return false;
222#endif
223 }
224
225
226
229 assert(contains(BB) && "Exiting block must be part of the loop");
232 return true;
233 }
234 return false;
235 }
236
237
238
239
240
243 assert(contains(BB) && "block does not belong to the loop");
245 }
246
247
251 [&](BlockT *Pred) { return contains(Pred); });
252 }
253
254
255
256
257
258
259
260
261
262
263
264
266
267
268
270
271
272
274
275
276
278
279
280
282
283
284
286
287
288
289
290
292
293
294
296
297
298
300
301
303
304
305 using Edge = std::pair<BlockT *, BlockT *>;
306
307
309
310
311
312
313
314
315
317
318
319
320
321
323
324
325
327
328
329
337
338
339
340 template
344 PreOrderWorklist.append(L.rbegin(), L.rend());
345
346 while (!PreOrderWorklist.empty()) {
348
349
350 PreOrderWorklist.append(L->rbegin(), L->rend());
352 }
353 }
354
355
356
359 const LoopT *CurLoop = static_cast<const LoopT *>(this);
360 PreOrderLoops.push_back(CurLoop);
362 return PreOrderLoops;
363 }
366 LoopT *CurLoop = static_cast<LoopT *>(this);
367 PreOrderLoops.push_back(CurLoop);
369 return PreOrderLoops;
370 }
371
372
373
374
375
376
377
378
379
380
382
383
384
385
386
388
389
390
393 assert(!NewChild->ParentLoop && "NewChild already has a parent!");
394 NewChild->ParentLoop = static_cast<LoopT *>(this);
395 SubLoops.push_back(NewChild);
396 }
397
398
399
402 assert(I != SubLoops.end() && "Cannot remove end iterator!");
403 LoopT *Child = *I;
404 assert(Child->ParentLoop == this && "Child is not a child of this loop!");
405 SubLoops.erase(SubLoops.begin() + (I - begin()));
406 Child->ParentLoop = nullptr;
407 return Child;
408 }
409
410
411
415
416
417
418
421 Blocks.push_back(BB);
422 DenseBlockSet.insert(BB);
423 }
424
425
428 std::reverse(Blocks.begin() + from, Blocks.end());
429 }
430
431
434 Blocks.reserve(size);
435 }
436
437
438
441 if (Blocks[0] == BB)
442 return;
443 for (unsigned i = 0;; ++i) {
444 assert(i != Blocks.size() && "Loop does not contain BB!");
445 if (Blocks[i] == BB) {
446 Blocks[i] = Blocks[0];
447 Blocks[0] = BB;
448 return;
449 }
450 }
451 }
452
453
454
455
458 auto I = find(Blocks, BB);
459 assert(I != Blocks.end() && "N is not in this list!");
460 Blocks.erase(I);
461
462 DenseBlockSet.erase(BB);
463 }
464
465
467
468
470
471
472
473
474
476
477
479 unsigned Depth = 0) const;
480
481protected:
483
484
486
487 explicit LoopBase(BlockT *BB) : ParentLoop(nullptr) {
488 Blocks.push_back(BB);
489 DenseBlockSet.insert(BB);
490 }
491
492
493
494
495
496
497
498
499
500
502 for (auto *SubLoop : SubLoops)
503 SubLoop->~LoopT();
504
505#if LLVM_ENABLE_ABI_BREAKING_CHECKS
506 IsInvalid = true;
507#endif
508 SubLoops.clear();
509 Blocks.clear();
510 DenseBlockSet.clear();
511 ParentLoop = nullptr;
512 }
513};
514
515template <class BlockT, class LoopT>
520
521
522
523
524
525
526template <class BlockT, class LoopT> class LoopInfoBase {
527
529 std::vector<LoopT *> TopLevelLoops;
531
532 friend class LoopBase<BlockT, LoopT>;
534
535 void operator=(const LoopInfoBase &) = delete;
537
538public:
541
543 : BBMap(std::move(Arg.BBMap)),
544 TopLevelLoops(std::move(Arg.TopLevelLoops)),
545 LoopAllocator(std::move(Arg.LoopAllocator)) {
546
547 Arg.TopLevelLoops.clear();
548 }
550 BBMap = std::move(RHS.BBMap);
551
552 for (auto *L : TopLevelLoops)
553 L->~LoopT();
554
555 TopLevelLoops = std::move(RHS.TopLevelLoops);
556 LoopAllocator = std::move(RHS.LoopAllocator);
557 RHS.TopLevelLoops.clear();
558 return *this;
559 }
560
562 BBMap.clear();
563
564 for (auto *L : TopLevelLoops)
565 L->~LoopT();
566 TopLevelLoops.clear();
567 LoopAllocator.Reset();
568 }
569
570 template <typename... ArgsTy> LoopT *AllocateLoop(ArgsTy &&...Args) {
571 LoopT *Storage = LoopAllocator.Allocate();
572 return new (Storage) LoopT(std::forward(Args)...);
573 }
574
575
576
577
578 using iterator = typename std::vector<LoopT *>::const_iterator;
580 typename std::vector<LoopT *>::const_reverse_iterator;
585 bool empty() const { return TopLevelLoops.empty(); }
586
587
588
589
590
591
593
594
595
596
597
598
599
600
601
603
604
605
606 LoopT *getLoopFor(const BlockT *BB) const { return BBMap.lookup(BB); }
607
608
610
611
612
615 return L ? L->getLoopDepth() : 0;
616 }
617
618
619
620
621
623
624
625
626
628
629
632 return L && L->getHeader() == BB;
633 }
634
635
636 const std::vector<LoopT *> &getTopLevelLoops() const { return TopLevelLoops; }
637
638
640
641
642
643
645 assert(I != end() && "Cannot remove end iterator!");
646 LoopT *L = *I;
647 assert(L->isOutermost() && "Not a top-level loop!");
648 TopLevelLoops.erase(TopLevelLoops.begin() + (I - begin()));
649 return L;
650 }
651
652
653
654
656 if (!L) {
657 BBMap.erase(BB);
658 return;
659 }
660 BBMap[BB] = L;
661 }
662
663
664
666 auto I = find(TopLevelLoops, OldLoop);
667 assert(I != TopLevelLoops.end() && "Old loop not at top level!");
668 *I = NewLoop;
669 assert(!NewLoop->ParentLoop && !OldLoop->ParentLoop &&
670 "Loops already embedded into a subloop!");
671 }
672
673
675 assert(New->isOutermost() && "Loop already in subloop!");
676 TopLevelLoops.push_back(New);
677 }
678
679
680
681
683 auto I = BBMap.find(BB);
684 if (I != BBMap.end()) {
685 for (LoopT *L = I->second; L; L = L->getParentLoop())
686 L->removeBlockFromLoop(BB);
687
688 BBMap.erase(I);
689 }
690 }
691
692
693
695 const LoopT *ParentLoop) {
696 if (!SubLoop)
697 return true;
698 if (SubLoop == ParentLoop)
699 return false;
701 }
702
703
705
706
708
710
711
712
713
714
715
716
717
718
719
720
722 L->~LoopT();
723
724
725
726 LoopAllocator.Deallocate(L);
727 }
728};
729
730}
731
732#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines generic set operations that may be used on set's of different types,...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const_pointer const_iterator
Implements a dense probed hash-table based set.
Core dominator tree base class.
Instances of this class are used to represent loops that are detected in the flow graph.
Definition GenericLoopInfo.h:59
bool isAnnotatedParallel() const
Returns true if the loop is annotated parallel.
Definition GenericLoopInfo.h:475
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
Definition GenericLoopInfo.h:124
SmallPtrSetImpl< const BlockT * > & getBlocksSet()
Return a direct, mutable handle to the blocks set so that we can mutate it efficiently.
Definition GenericLoopInfo.h:200
static void getInnerLoopsInPreorder(const LoopT &L, SmallVectorImpl< Type > &PreOrderLoops)
Return all inner loops in the loop nest rooted by the loop in preorder, with siblings in forward prog...
Definition GenericLoopInfo.h:341
typename std::vector< LoopT * >::const_iterator iterator
Definition GenericLoopInfo.h:153
bool isOutermost() const
Return true if the loop does not have a parent (natural) loop.
Definition GenericLoopInfo.h:170
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
Definition GenericLoopInfo.h:167
void removeBlockFromLoop(BlockT *BB)
This removes the specified basic block from the current loop, updating the Blocks as appropriate.
Definition GenericLoopInfo.h:456
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
std::pair< BlockT *, BlockT * > Edge
Edge type.
Definition GenericLoopInfo.h:305
bool contains(const InstT *Inst) const
Return true if the specified instruction is in this loop.
Definition GenericLoopInfo.h:140
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
Definition GenericLoopInfo.h:187
void verifyLoop() const
Verify loop structure.
void verifyLoopNest(DenseSet< const LoopT * > *Loops) const
Verify loop structure of this loop and all nested loops.
SmallVector< LoopT *, 4 > getLoopsInPreorder()
Definition GenericLoopInfo.h:364
typename std::vector< LoopT * >::const_reverse_iterator reverse_iterator
Definition GenericLoopInfo.h:154
unsigned getNumBackEdges() const
Calculate the number of back edges to the loop header.
Definition GenericLoopInfo.h:248
void reverseBlock(unsigned from)
interface to reverse Blocks[from, end of loop] in this loop
Definition GenericLoopInfo.h:426
SmallVector< const LoopT *, 4 > getLoopsInPreorder() const
Return all loops in the loop nest rooted by the loop in preorder, with siblings in forward program or...
Definition GenericLoopInfo.h:357
BlockT * getUniqueLatchExitBlock() const
Return the unique exit block for the latch, or null if there are multiple different exit blocks or th...
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
LoopBase(BlockT *BB)
Definition GenericLoopInfo.h:487
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
Definition GenericLoopInfo.h:145
BlockT * getHeader() const
Definition GenericLoopInfo.h:90
const LoopT * getOutermostLoop() const
Get the outermost loop in which this loop is contained.
Definition GenericLoopInfo.h:103
~LoopBase()
Definition GenericLoopInfo.h:501
void getLoopLatches(SmallVectorImpl< BlockT * > &LoopLatches) const
Return all loop latch blocks of this loop.
Definition GenericLoopInfo.h:330
unsigned getLoopDepth() const
Return the nesting level of this loop.
Definition GenericLoopInfo.h:82
LoopBase()
This creates an empty loop.
Definition GenericLoopInfo.h:485
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.
std::vector< BlockT * > & getBlocksVector()
Return a direct, mutable handle to the blocks vector so that we can mutate it efficiently with techni...
Definition GenericLoopInfo.h:194
LoopT * removeChildLoop(LoopT *Child)
This removes the specified child from being a subloop of this loop.
Definition GenericLoopInfo.h:412
void reserveBlocks(unsigned size)
interface to do reserve() for Blocks
Definition GenericLoopInfo.h:432
iterator_range< block_iterator > blocks() const
Definition GenericLoopInfo.h:180
block_iterator block_end() const
Definition GenericLoopInfo.h:179
bool isInvalid() const
Return true if this loop is no longer valid.
Definition GenericLoopInfo.h:217
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it.
bool contains(const BlockT *BB) const
Return true if the specified basic block is in this loop.
Definition GenericLoopInfo.h:134
bool isLoopLatch(const BlockT *BB) const
Definition GenericLoopInfo.h:241
iterator end() const
Definition GenericLoopInfo.h:157
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
Definition GenericLoopInfo.h:391
void getExitEdges(SmallVectorImpl< Edge > &ExitEdges) const
Return all pairs of (inside_block,outside_block).
void addBlockEntry(BlockT *BB)
This adds a basic block directly to the basic block list.
Definition GenericLoopInfo.h:419
std::vector< LoopT * > & getSubLoopsVector()
Definition GenericLoopInfo.h:149
reverse_iterator rbegin() const
Definition GenericLoopInfo.h:158
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
bool hasNoExitBlocks() const
Return true if this loop does not have any exit blocks.
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< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
Definition GenericLoopInfo.h:173
reverse_iterator rend() const
Definition GenericLoopInfo.h:159
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
LoopT * getOutermostLoop()
Definition GenericLoopInfo.h:110
void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all unique successor blocks of this loop.
void setParentLoop(LoopT *L)
This is a raw interface for bypassing addChildLoop.
Definition GenericLoopInfo.h:118
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
Definition GenericLoopInfo.h:99
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...
iterator begin() const
Definition GenericLoopInfo.h:156
const SmallPtrSetImpl< const BlockT * > & getBlocksSet() const
Return a direct, immutable handle to the blocks set.
Definition GenericLoopInfo.h:206
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
Definition GenericLoopInfo.h:227
block_iterator block_begin() const
Definition GenericLoopInfo.h:178
void moveToHeader(BlockT *BB)
This method is used to move BB (which must be part of this loop) to be the loop header of the loop (t...
Definition GenericLoopInfo.h:439
typename ArrayRef< BlockT * >::const_iterator block_iterator
Definition GenericLoopInfo.h:177
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
LoopT * removeChildLoop(iterator I)
This removes the specified child from being a subloop of this loop.
Definition GenericLoopInfo.h:400
This class builds and contains all of the top-level loop structures in the specified function.
Definition GenericLoopInfo.h:526
~LoopInfoBase()
Definition GenericLoopInfo.h:540
const std::vector< LoopT * > & getTopLevelLoops() const
Return the top-level loops.
Definition GenericLoopInfo.h:636
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
Definition GenericLoopInfo.h:674
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
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
reverse_iterator rend() const
Definition GenericLoopInfo.h:584
void changeTopLevelLoop(LoopT *OldLoop, LoopT *NewLoop)
Replace the specified loop in the top-level loops list with the indicated loop.
Definition GenericLoopInfo.h:665
iterator end() const
Definition GenericLoopInfo.h:582
void removeBlock(BlockT *BB)
This method completely removes BB from all data structures, including all of the Loop objects it is n...
Definition GenericLoopInfo.h:682
LoopInfoBase(LoopInfoBase &&Arg)
Definition GenericLoopInfo.h:542
LoopT * AllocateLoop(ArgsTy &&...Args)
Definition GenericLoopInfo.h:570
const LoopT * operator[](const BlockT *BB) const
Same as getLoopFor.
Definition GenericLoopInfo.h:609
bool isLoopHeader(const BlockT *BB) const
Definition GenericLoopInfo.h:630
LoopT * removeLoop(iterator I)
This removes the specified top-level loop from this loop info object.
Definition GenericLoopInfo.h:644
LoopT * getSmallestCommonLoop(BlockT *A, BlockT *B) const
Find the innermost loop containing both given blocks.
bool empty() const
Definition GenericLoopInfo.h:585
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.
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
Definition GenericLoopInfo.h:655
typename std::vector< Loop * >::const_iterator iterator
Definition GenericLoopInfo.h:578
typename std::vector< Loop * >::const_reverse_iterator reverse_iterator
Definition GenericLoopInfo.h:579
unsigned getLoopDepth(const BlockT *BB) const
Return the loop nesting level of the specified block.
Definition GenericLoopInfo.h:613
std::vector< LoopT * > & getTopLevelLoopsVector()
Return the top-level loops.
Definition GenericLoopInfo.h:639
iterator begin() const
Definition GenericLoopInfo.h:581
static bool isNotAlreadyContainedIn(const LoopT *SubLoop, const LoopT *ParentLoop)
Definition GenericLoopInfo.h:694
reverse_iterator rbegin() const
Definition GenericLoopInfo.h:583
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Definition GenericLoopInfo.h:606
LoopInfoBase & operator=(LoopInfoBase &&RHS)
Definition GenericLoopInfo.h:549
void destroy(LoopT *L)
Destroy a loop that has been removed from the LoopInfo nest.
Definition GenericLoopInfo.h:721
void releaseMemory()
Definition GenericLoopInfo.h:561
friend class LoopInfo
Definition GenericLoopInfo.h:533
Represents a single loop in the control flow graph.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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...
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.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
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.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Implement std::hash so that hash_code can be used in STL containers.