xref: /llvm-project/llvm/include/llvm/ADT/GenericCycleImpl.h (revision 6233346895abfb57782511cddc263d439fdd537b)
1 //===- GenericCycleImpl.h -------------------------------------*- 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 /// \file
10 /// This template implementation resides in a separate file so that it
11 /// does not get injected into every .cpp file that includes the
12 /// generic header.
13 ///
14 /// DO NOT INCLUDE THIS FILE WHEN MERELY USING CYCLEINFO.
15 ///
16 /// This file should only be included by files that implement a
17 /// specialization of the relevant templates. Currently these are:
18 /// - llvm/lib/IR/CycleInfo.cpp
19 /// - llvm/lib/CodeGen/MachineCycleAnalysis.cpp
20 ///
21 //===----------------------------------------------------------------------===//
22 
23 #ifndef LLVM_ADT_GENERICCYCLEIMPL_H
24 #define LLVM_ADT_GENERICCYCLEIMPL_H
25 
26 #include "llvm/ADT/DenseSet.h"
27 #include "llvm/ADT/DepthFirstIterator.h"
28 #include "llvm/ADT/GenericCycleInfo.h"
29 #include "llvm/ADT/StringExtras.h"
30 
31 #define DEBUG_TYPE "generic-cycle-impl"
32 
33 namespace llvm {
34 
35 template <typename ContextT>
36 bool GenericCycle<ContextT>::contains(const GenericCycle *C) const {
37   if (!C)
38     return false;
39 
40   if (Depth > C->Depth)
41     return false;
42   while (Depth < C->Depth)
43     C = C->ParentCycle;
44   return this == C;
45 }
46 
47 template <typename ContextT>
48 void GenericCycle<ContextT>::getExitBlocks(
49     SmallVectorImpl<BlockT *> &TmpStorage) const {
50   if (!ExitBlocksCache.empty()) {
51     TmpStorage = ExitBlocksCache;
52     return;
53   }
54 
55   TmpStorage.clear();
56 
57   size_t NumExitBlocks = 0;
58   for (BlockT *Block : blocks()) {
59     llvm::append_range(TmpStorage, successors(Block));
60 
61     for (size_t Idx = NumExitBlocks, End = TmpStorage.size(); Idx < End;
62          ++Idx) {
63       BlockT *Succ = TmpStorage[Idx];
64       if (!contains(Succ)) {
65         auto ExitEndIt = TmpStorage.begin() + NumExitBlocks;
66         if (std::find(TmpStorage.begin(), ExitEndIt, Succ) == ExitEndIt)
67           TmpStorage[NumExitBlocks++] = Succ;
68       }
69     }
70 
71     TmpStorage.resize(NumExitBlocks);
72   }
73   ExitBlocksCache.append(TmpStorage.begin(), TmpStorage.end());
74 }
75 
76 template <typename ContextT>
77 void GenericCycle<ContextT>::getExitingBlocks(
78     SmallVectorImpl<BlockT *> &TmpStorage) const {
79   TmpStorage.clear();
80 
81   for (BlockT *Block : blocks()) {
82     for (BlockT *Succ : successors(Block)) {
83       if (!contains(Succ)) {
84         TmpStorage.push_back(Block);
85         break;
86       }
87     }
88   }
89 }
90 
91 template <typename ContextT>
92 auto GenericCycle<ContextT>::getCyclePreheader() const -> BlockT * {
93   BlockT *Predecessor = getCyclePredecessor();
94   if (!Predecessor)
95     return nullptr;
96 
97   assert(isReducible() && "Cycle Predecessor must be in a reducible cycle!");
98 
99   if (succ_size(Predecessor) != 1)
100     return nullptr;
101 
102   // Make sure we are allowed to hoist instructions into the predecessor.
103   if (!Predecessor->isLegalToHoistInto())
104     return nullptr;
105 
106   return Predecessor;
107 }
108 
109 template <typename ContextT>
110 auto GenericCycle<ContextT>::getCyclePredecessor() const -> BlockT * {
111   if (!isReducible())
112     return nullptr;
113 
114   BlockT *Out = nullptr;
115 
116   // Loop over the predecessors of the header node...
117   BlockT *Header = getHeader();
118   for (const auto Pred : predecessors(Header)) {
119     if (!contains(Pred)) {
120       if (Out && Out != Pred)
121         return nullptr;
122       Out = Pred;
123     }
124   }
125 
126   return Out;
127 }
128 
129 /// \brief Verify that this is actually a well-formed cycle in the CFG.
130 template <typename ContextT> void GenericCycle<ContextT>::verifyCycle() const {
131 #ifndef NDEBUG
132   assert(!Blocks.empty() && "Cycle cannot be empty.");
133   DenseSet<BlockT *> Blocks;
134   for (BlockT *BB : blocks()) {
135     assert(Blocks.insert(BB).second); // duplicates in block list?
136   }
137   assert(!Entries.empty() && "Cycle must have one or more entries.");
138 
139   DenseSet<BlockT *> Entries;
140   for (BlockT *Entry : entries()) {
141     assert(Entries.insert(Entry).second); // duplicate entry?
142     assert(contains(Entry));
143   }
144 
145   // Setup for using a depth-first iterator to visit every block in the cycle.
146   SmallVector<BlockT *, 8> ExitBBs;
147   getExitBlocks(ExitBBs);
148   df_iterator_default_set<BlockT *> VisitSet;
149   VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
150 
151   // Keep track of the BBs visited.
152   SmallPtrSet<BlockT *, 8> VisitedBBs;
153 
154   // Check the individual blocks.
155   for (BlockT *BB : depth_first_ext(getHeader(), VisitSet)) {
156     assert(llvm::any_of(llvm::children<BlockT *>(BB),
157                         [&](BlockT *B) { return contains(B); }) &&
158            "Cycle block has no in-cycle successors!");
159 
160     assert(llvm::any_of(llvm::inverse_children<BlockT *>(BB),
161                         [&](BlockT *B) { return contains(B); }) &&
162            "Cycle block has no in-cycle predecessors!");
163 
164     DenseSet<BlockT *> OutsideCyclePreds;
165     for (BlockT *B : llvm::inverse_children<BlockT *>(BB))
166       if (!contains(B))
167         OutsideCyclePreds.insert(B);
168 
169     if (Entries.contains(BB)) {
170       assert(!OutsideCyclePreds.empty() && "Entry is unreachable!");
171     } else if (!OutsideCyclePreds.empty()) {
172       // A non-entry block shouldn't be reachable from outside the cycle,
173       // though it is permitted if the predecessor is not itself actually
174       // reachable.
175       BlockT *EntryBB = &BB->getParent()->front();
176       for (BlockT *CB : depth_first(EntryBB))
177         assert(!OutsideCyclePreds.contains(CB) &&
178                "Non-entry block reachable from outside!");
179     }
180     assert(BB != &getHeader()->getParent()->front() &&
181            "Cycle contains function entry block!");
182 
183     VisitedBBs.insert(BB);
184   }
185 
186   if (VisitedBBs.size() != getNumBlocks()) {
187     dbgs() << "The following blocks are unreachable in the cycle:\n  ";
188     ListSeparator LS;
189     for (auto *BB : Blocks) {
190       if (!VisitedBBs.count(BB)) {
191         dbgs() << LS;
192         BB->printAsOperand(dbgs());
193       }
194     }
195     dbgs() << "\n";
196     llvm_unreachable("Unreachable block in cycle");
197   }
198 
199   verifyCycleNest();
200 #endif
201 }
202 
203 /// \brief Verify the parent-child relations of this cycle.
204 ///
205 /// Note that this does \em not check that cycle is really a cycle in the CFG.
206 template <typename ContextT>
207 void GenericCycle<ContextT>::verifyCycleNest() const {
208 #ifndef NDEBUG
209   // Check the subcycles.
210   for (GenericCycle *Child : children()) {
211     // Each block in each subcycle should be contained within this cycle.
212     for (BlockT *BB : Child->blocks()) {
213       assert(contains(BB) &&
214              "Cycle does not contain all the blocks of a subcycle!");
215     }
216     assert(Child->Depth == Depth + 1);
217   }
218 
219   // Check the parent cycle pointer.
220   if (ParentCycle) {
221     assert(is_contained(ParentCycle->children(), this) &&
222            "Cycle is not a subcycle of its parent!");
223   }
224 #endif
225 }
226 
227 /// \brief Helper class for computing cycle information.
228 template <typename ContextT> class GenericCycleInfoCompute {
229   using BlockT = typename ContextT::BlockT;
230   using CycleInfoT = GenericCycleInfo<ContextT>;
231   using CycleT = typename CycleInfoT::CycleT;
232 
233   CycleInfoT &Info;
234 
235   struct DFSInfo {
236     unsigned Start = 0; // DFS start; positive if block is found
237     unsigned End = 0;   // DFS end
238 
239     DFSInfo() = default;
240     explicit DFSInfo(unsigned Start) : Start(Start) {}
241 
242     explicit operator bool() const { return Start; }
243 
244     /// Whether this node is an ancestor (or equal to) the node \p Other
245     /// in the DFS tree.
246     bool isAncestorOf(const DFSInfo &Other) const {
247       return Start <= Other.Start && Other.End <= End;
248     }
249   };
250 
251   DenseMap<BlockT *, DFSInfo> BlockDFSInfo;
252   SmallVector<BlockT *, 8> BlockPreorder;
253 
254   GenericCycleInfoCompute(const GenericCycleInfoCompute &) = delete;
255   GenericCycleInfoCompute &operator=(const GenericCycleInfoCompute &) = delete;
256 
257 public:
258   GenericCycleInfoCompute(CycleInfoT &Info) : Info(Info) {}
259 
260   void run(BlockT *EntryBlock);
261 
262   static void updateDepth(CycleT *SubTree);
263 
264 private:
265   void dfs(BlockT *EntryBlock);
266 };
267 
268 template <typename ContextT>
269 auto GenericCycleInfo<ContextT>::getTopLevelParentCycle(BlockT *Block)
270     -> CycleT * {
271   auto Cycle = BlockMapTopLevel.find(Block);
272   if (Cycle != BlockMapTopLevel.end())
273     return Cycle->second;
274 
275   auto MapIt = BlockMap.find(Block);
276   if (MapIt == BlockMap.end())
277     return nullptr;
278 
279   auto *C = MapIt->second;
280   while (C->ParentCycle)
281     C = C->ParentCycle;
282   BlockMapTopLevel.try_emplace(Block, C);
283   return C;
284 }
285 
286 template <typename ContextT>
287 void GenericCycleInfo<ContextT>::moveTopLevelCycleToNewParent(CycleT *NewParent,
288                                                               CycleT *Child) {
289   assert((!Child->ParentCycle && !NewParent->ParentCycle) &&
290          "NewParent and Child must be both top level cycle!\n");
291   auto &CurrentContainer =
292       Child->ParentCycle ? Child->ParentCycle->Children : TopLevelCycles;
293   auto Pos = llvm::find_if(CurrentContainer, [=](const auto &Ptr) -> bool {
294     return Child == Ptr.get();
295   });
296   assert(Pos != CurrentContainer.end());
297   NewParent->Children.push_back(std::move(*Pos));
298   *Pos = std::move(CurrentContainer.back());
299   CurrentContainer.pop_back();
300   Child->ParentCycle = NewParent;
301 
302   NewParent->Blocks.insert(Child->block_begin(), Child->block_end());
303 
304   for (auto &It : BlockMapTopLevel)
305     if (It.second == Child)
306       It.second = NewParent;
307   NewParent->clearCache();
308   Child->clearCache();
309 }
310 
311 template <typename ContextT>
312 void GenericCycleInfo<ContextT>::addBlockToCycle(BlockT *Block, CycleT *Cycle) {
313   // FixMe: Appending NewBlock is fine as a set of blocks in a cycle. When
314   // printing, cycle NewBlock is at the end of list but it should be in the
315   // middle to represent actual traversal of a cycle.
316   Cycle->appendBlock(Block);
317   BlockMap.try_emplace(Block, Cycle);
318 
319   CycleT *ParentCycle = Cycle->getParentCycle();
320   while (ParentCycle) {
321     Cycle = ParentCycle;
322     Cycle->appendBlock(Block);
323     ParentCycle = Cycle->getParentCycle();
324   }
325 
326   BlockMapTopLevel.try_emplace(Block, Cycle);
327   Cycle->clearCache();
328 }
329 
330 /// \brief Main function of the cycle info computations.
331 template <typename ContextT>
332 void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
333   LLVM_DEBUG(errs() << "Entry block: " << Info.Context.print(EntryBlock)
334                     << "\n");
335   dfs(EntryBlock);
336 
337   SmallVector<BlockT *, 8> Worklist;
338 
339   for (BlockT *HeaderCandidate : llvm::reverse(BlockPreorder)) {
340     const DFSInfo CandidateInfo = BlockDFSInfo.lookup(HeaderCandidate);
341 
342     for (BlockT *Pred : predecessors(HeaderCandidate)) {
343       const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred);
344       // This automatically ignores unreachable predecessors since they have
345       // zeros in their DFSInfo.
346       if (CandidateInfo.isAncestorOf(PredDFSInfo))
347         Worklist.push_back(Pred);
348     }
349     if (Worklist.empty()) {
350       continue;
351     }
352 
353     // Found a cycle with the candidate as its header.
354     LLVM_DEBUG(errs() << "Found cycle for header: "
355                       << Info.Context.print(HeaderCandidate) << "\n");
356     std::unique_ptr<CycleT> NewCycle = std::make_unique<CycleT>();
357     NewCycle->appendEntry(HeaderCandidate);
358     NewCycle->appendBlock(HeaderCandidate);
359     Info.BlockMap.try_emplace(HeaderCandidate, NewCycle.get());
360 
361     // Helper function to process (non-back-edge) predecessors of a discovered
362     // block and either add them to the worklist or recognize that the given
363     // block is an additional cycle entry.
364     auto ProcessPredecessors = [&](BlockT *Block) {
365       LLVM_DEBUG(errs() << "  block " << Info.Context.print(Block) << ": ");
366 
367       bool IsEntry = false;
368       for (BlockT *Pred : predecessors(Block)) {
369         const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred);
370         if (CandidateInfo.isAncestorOf(PredDFSInfo)) {
371           Worklist.push_back(Pred);
372         } else if (!PredDFSInfo) {
373           // Ignore an unreachable predecessor. It will will incorrectly cause
374           // Block to be treated as a cycle entry.
375           LLVM_DEBUG(errs() << " skipped unreachable predecessor.\n");
376         } else {
377           IsEntry = true;
378         }
379       }
380       if (IsEntry) {
381         assert(!NewCycle->isEntry(Block));
382         LLVM_DEBUG(errs() << "append as entry\n");
383         NewCycle->appendEntry(Block);
384       } else {
385         LLVM_DEBUG(errs() << "append as child\n");
386       }
387     };
388 
389     do {
390       BlockT *Block = Worklist.pop_back_val();
391       if (Block == HeaderCandidate)
392         continue;
393 
394       // If the block has already been discovered by some cycle
395       // (possibly by ourself), then the outermost cycle containing it
396       // should become our child.
397       if (auto *BlockParent = Info.getTopLevelParentCycle(Block)) {
398         LLVM_DEBUG(errs() << "  block " << Info.Context.print(Block) << ": ");
399 
400         if (BlockParent != NewCycle.get()) {
401           LLVM_DEBUG(errs()
402                      << "discovered child cycle "
403                      << Info.Context.print(BlockParent->getHeader()) << "\n");
404           // Make BlockParent the child of NewCycle.
405           Info.moveTopLevelCycleToNewParent(NewCycle.get(), BlockParent);
406 
407           for (auto *ChildEntry : BlockParent->entries())
408             ProcessPredecessors(ChildEntry);
409         } else {
410           LLVM_DEBUG(errs()
411                      << "known child cycle "
412                      << Info.Context.print(BlockParent->getHeader()) << "\n");
413         }
414       } else {
415         Info.BlockMap.try_emplace(Block, NewCycle.get());
416         assert(!is_contained(NewCycle->Blocks, Block));
417         NewCycle->Blocks.insert(Block);
418         ProcessPredecessors(Block);
419         Info.BlockMapTopLevel.try_emplace(Block, NewCycle.get());
420       }
421     } while (!Worklist.empty());
422 
423     Info.TopLevelCycles.push_back(std::move(NewCycle));
424   }
425 
426   // Fix top-level cycle links and compute cycle depths.
427   for (auto *TLC : Info.toplevel_cycles()) {
428     LLVM_DEBUG(errs() << "top-level cycle: "
429                       << Info.Context.print(TLC->getHeader()) << "\n");
430 
431     TLC->ParentCycle = nullptr;
432     updateDepth(TLC);
433   }
434 }
435 
436 /// \brief Recompute depth values of \p SubTree and all descendants.
437 template <typename ContextT>
438 void GenericCycleInfoCompute<ContextT>::updateDepth(CycleT *SubTree) {
439   for (CycleT *Cycle : depth_first(SubTree))
440     Cycle->Depth = Cycle->ParentCycle ? Cycle->ParentCycle->Depth + 1 : 1;
441 }
442 
443 /// \brief Compute a DFS of basic blocks starting at the function entry.
444 ///
445 /// Fills BlockDFSInfo with start/end counters and BlockPreorder.
446 template <typename ContextT>
447 void GenericCycleInfoCompute<ContextT>::dfs(BlockT *EntryBlock) {
448   SmallVector<unsigned, 8> DFSTreeStack;
449   SmallVector<BlockT *, 8> TraverseStack;
450   unsigned Counter = 0;
451   TraverseStack.emplace_back(EntryBlock);
452 
453   do {
454     BlockT *Block = TraverseStack.back();
455     LLVM_DEBUG(errs() << "DFS visiting block: " << Info.Context.print(Block)
456                       << "\n");
457     if (!BlockDFSInfo.count(Block)) {
458       // We're visiting the block for the first time. Open its DFSInfo, add
459       // successors to the traversal stack, and remember the traversal stack
460       // depth at which the block was opened, so that we can correctly record
461       // its end time.
462       LLVM_DEBUG(errs() << "  first encountered at depth "
463                         << TraverseStack.size() << "\n");
464 
465       DFSTreeStack.emplace_back(TraverseStack.size());
466       llvm::append_range(TraverseStack, successors(Block));
467 
468       bool Added = BlockDFSInfo.try_emplace(Block, ++Counter).second;
469       (void)Added;
470       assert(Added);
471       BlockPreorder.push_back(Block);
472       LLVM_DEBUG(errs() << "  preorder number: " << Counter << "\n");
473     } else {
474       assert(!DFSTreeStack.empty());
475       if (DFSTreeStack.back() == TraverseStack.size()) {
476         LLVM_DEBUG(errs() << "  ended at " << Counter << "\n");
477         BlockDFSInfo.find(Block)->second.End = Counter;
478         DFSTreeStack.pop_back();
479       } else {
480         LLVM_DEBUG(errs() << "  already done\n");
481       }
482       TraverseStack.pop_back();
483     }
484   } while (!TraverseStack.empty());
485   assert(DFSTreeStack.empty());
486 
487   LLVM_DEBUG(
488     errs() << "Preorder:\n";
489     for (int i = 0, e = BlockPreorder.size(); i != e; ++i) {
490       errs() << "  " << Info.Context.print(BlockPreorder[i]) << ": " << i << "\n";
491     }
492   );
493 }
494 
495 /// \brief Reset the object to its initial state.
496 template <typename ContextT> void GenericCycleInfo<ContextT>::clear() {
497   TopLevelCycles.clear();
498   BlockMap.clear();
499   BlockMapTopLevel.clear();
500 }
501 
502 /// \brief Compute the cycle info for a function.
503 template <typename ContextT>
504 void GenericCycleInfo<ContextT>::compute(FunctionT &F) {
505   GenericCycleInfoCompute<ContextT> Compute(*this);
506   Context = ContextT(&F);
507 
508   LLVM_DEBUG(errs() << "Computing cycles for function: " << F.getName()
509                     << "\n");
510   Compute.run(&F.front());
511 }
512 
513 template <typename ContextT>
514 void GenericCycleInfo<ContextT>::splitCriticalEdge(BlockT *Pred, BlockT *Succ,
515                                                    BlockT *NewBlock) {
516   // Edge Pred-Succ is replaced by edges Pred-NewBlock and NewBlock-Succ, all
517   // cycles that had blocks Pred and Succ also get NewBlock.
518   CycleT *Cycle = getSmallestCommonCycle(getCycle(Pred), getCycle(Succ));
519   if (!Cycle)
520     return;
521 
522   addBlockToCycle(NewBlock, Cycle);
523   verifyCycleNest();
524 }
525 
526 /// \brief Find the innermost cycle containing a given block.
527 ///
528 /// \returns the innermost cycle containing \p Block or nullptr if
529 ///          it is not contained in any cycle.
530 template <typename ContextT>
531 auto GenericCycleInfo<ContextT>::getCycle(const BlockT *Block) const
532     -> CycleT * {
533   return BlockMap.lookup(Block);
534 }
535 
536 /// \brief Find the innermost cycle containing both given cycles.
537 ///
538 /// \returns the innermost cycle containing both \p A and \p B
539 ///          or nullptr if there is no such cycle.
540 template <typename ContextT>
541 auto GenericCycleInfo<ContextT>::getSmallestCommonCycle(CycleT *A,
542                                                         CycleT *B) const
543     -> CycleT * {
544   if (!A || !B)
545     return nullptr;
546 
547   // If cycles A and B have different depth replace them with parent cycle
548   // until they have the same depth.
549   while (A->getDepth() > B->getDepth())
550     A = A->getParentCycle();
551   while (B->getDepth() > A->getDepth())
552     B = B->getParentCycle();
553 
554   // Cycles A and B are at same depth but may be disjoint, replace them with
555   // parent cycles until we find cycle that contains both or we run out of
556   // parent cycles.
557   while (A != B) {
558     A = A->getParentCycle();
559     B = B->getParentCycle();
560   }
561 
562   return A;
563 }
564 
565 /// \brief get the depth for the cycle which containing a given block.
566 ///
567 /// \returns the depth for the innermost cycle containing \p Block or 0 if it is
568 ///          not contained in any cycle.
569 template <typename ContextT>
570 unsigned GenericCycleInfo<ContextT>::getCycleDepth(const BlockT *Block) const {
571   CycleT *Cycle = getCycle(Block);
572   if (!Cycle)
573     return 0;
574   return Cycle->getDepth();
575 }
576 
577 /// \brief Verify the internal consistency of the cycle tree.
578 ///
579 /// Note that this does \em not check that cycles are really cycles in the CFG,
580 /// or that the right set of cycles in the CFG were found.
581 template <typename ContextT>
582 void GenericCycleInfo<ContextT>::verifyCycleNest(bool VerifyFull) const {
583 #ifndef NDEBUG
584   DenseSet<BlockT *> CycleHeaders;
585 
586   for (CycleT *TopCycle : toplevel_cycles()) {
587     for (CycleT *Cycle : depth_first(TopCycle)) {
588       BlockT *Header = Cycle->getHeader();
589       assert(CycleHeaders.insert(Header).second);
590       if (VerifyFull)
591         Cycle->verifyCycle();
592       else
593         Cycle->verifyCycleNest();
594       // Check the block map entries for blocks contained in this cycle.
595       for (BlockT *BB : Cycle->blocks()) {
596         auto MapIt = BlockMap.find(BB);
597         assert(MapIt != BlockMap.end());
598         assert(Cycle->contains(MapIt->second));
599       }
600     }
601   }
602 #endif
603 }
604 
605 /// \brief Verify that the entire cycle tree well-formed.
606 template <typename ContextT> void GenericCycleInfo<ContextT>::verify() const {
607   verifyCycleNest(/*VerifyFull=*/true);
608 }
609 
610 /// \brief Print the cycle info.
611 template <typename ContextT>
612 void GenericCycleInfo<ContextT>::print(raw_ostream &Out) const {
613   for (const auto *TLC : toplevel_cycles()) {
614     for (const CycleT *Cycle : depth_first(TLC)) {
615       for (unsigned I = 0; I < Cycle->Depth; ++I)
616         Out << "    ";
617 
618       Out << Cycle->print(Context) << '\n';
619     }
620   }
621 }
622 
623 } // namespace llvm
624 
625 #undef DEBUG_TYPE
626 
627 #endif // LLVM_ADT_GENERICCYCLEIMPL_H
628