Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- GenericCycleInfo.h - Info for Cycles in any IR ------*- 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. /// \brief Find all cycles in a control-flow graph, including irreducible loops.
  11. ///
  12. /// See docs/CycleTerminology.rst for a formal definition of cycles.
  13. ///
  14. /// Briefly:
  15. /// - A cycle is a generalization of a loop which can represent
  16. ///   irreducible control flow.
  17. /// - Cycles identified in a program are implementation defined,
  18. ///   depending on the DFS traversal chosen.
  19. /// - Cycles are well-nested, and form a forest with a parent-child
  20. ///   relationship.
  21. /// - In any choice of DFS, every natural loop L is represented by a
  22. ///   unique cycle C which is a superset of L.
  23. /// - In the absence of irreducible control flow, the cycles are
  24. ///   exactly the natural loops in the program.
  25. ///
  26. //===----------------------------------------------------------------------===//
  27.  
  28. #ifndef LLVM_ADT_GENERICCYCLEINFO_H
  29. #define LLVM_ADT_GENERICCYCLEINFO_H
  30.  
  31. #include "llvm/ADT/ArrayRef.h"
  32. #include "llvm/ADT/DenseMap.h"
  33. #include "llvm/ADT/GenericSSAContext.h"
  34. #include "llvm/ADT/GraphTraits.h"
  35. #include "llvm/ADT/SmallVector.h"
  36. #include "llvm/ADT/iterator.h"
  37. #include "llvm/Support/Debug.h"
  38. #include "llvm/Support/Printable.h"
  39. #include "llvm/Support/raw_ostream.h"
  40. #include <vector>
  41.  
  42. namespace llvm {
  43.  
  44. template <typename ContextT> class GenericCycleInfo;
  45. template <typename ContextT> class GenericCycleInfoCompute;
  46.  
  47. /// A possibly irreducible generalization of a \ref Loop.
  48. template <typename ContextT> class GenericCycle {
  49. public:
  50.   using BlockT = typename ContextT::BlockT;
  51.   using FunctionT = typename ContextT::FunctionT;
  52.   template <typename> friend class GenericCycleInfo;
  53.   template <typename> friend class GenericCycleInfoCompute;
  54.  
  55. private:
  56.   /// The parent cycle. Is null for the root "cycle". Top-level cycles point
  57.   /// at the root.
  58.   GenericCycle *ParentCycle = nullptr;
  59.  
  60.   /// The entry block(s) of the cycle. The header is the only entry if
  61.   /// this is a loop. Is empty for the root "cycle", to avoid
  62.   /// unnecessary memory use.
  63.   SmallVector<BlockT *, 1> Entries;
  64.  
  65.   /// Child cycles, if any.
  66.   std::vector<std::unique_ptr<GenericCycle>> Children;
  67.  
  68.   /// Basic blocks that are contained in the cycle, including entry blocks,
  69.   /// and including blocks that are part of a child cycle.
  70.   std::vector<BlockT *> Blocks;
  71.  
  72.   /// Depth of the cycle in the tree. The root "cycle" is at depth 0.
  73.   ///
  74.   /// \note Depths are not necessarily contiguous. However, child loops always
  75.   ///       have strictly greater depth than their parents, and sibling loops
  76.   ///       always have the same depth.
  77.   unsigned Depth = 0;
  78.  
  79.   void clear() {
  80.     Entries.clear();
  81.     Children.clear();
  82.     Blocks.clear();
  83.     Depth = 0;
  84.     ParentCycle = nullptr;
  85.   }
  86.  
  87.   void appendEntry(BlockT *Block) { Entries.push_back(Block); }
  88.   void appendBlock(BlockT *Block) { Blocks.push_back(Block); }
  89.  
  90.   GenericCycle(const GenericCycle &) = delete;
  91.   GenericCycle &operator=(const GenericCycle &) = delete;
  92.   GenericCycle(GenericCycle &&Rhs) = delete;
  93.   GenericCycle &operator=(GenericCycle &&Rhs) = delete;
  94.  
  95. public:
  96.   GenericCycle() = default;
  97.  
  98.   /// \brief Whether the cycle is a natural loop.
  99.   bool isReducible() const { return Entries.size() == 1; }
  100.  
  101.   BlockT *getHeader() const { return Entries[0]; }
  102.  
  103.   const SmallVectorImpl<BlockT *> & getEntries() const {
  104.     return Entries;
  105.   }
  106.  
  107.   /// \brief Return whether \p Block is an entry block of the cycle.
  108.   bool isEntry(const BlockT *Block) const {
  109.     return is_contained(Entries, Block);
  110.   }
  111.  
  112.   /// \brief Return whether \p Block is contained in the cycle.
  113.   bool contains(const BlockT *Block) const {
  114.     return is_contained(Blocks, Block);
  115.   }
  116.  
  117.   /// \brief Returns true iff this cycle contains \p C.
  118.   ///
  119.   /// Note: Non-strict containment check, i.e. returns true if C is the
  120.   /// same cycle.
  121.   bool contains(const GenericCycle *C) const;
  122.  
  123.   const GenericCycle *getParentCycle() const { return ParentCycle; }
  124.   GenericCycle *getParentCycle() { return ParentCycle; }
  125.   unsigned getDepth() const { return Depth; }
  126.  
  127.   /// Return all of the successor blocks of this cycle.
  128.   ///
  129.   /// These are the blocks _outside of the current cycle_ which are
  130.   /// branched to.
  131.   void getExitBlocks(SmallVectorImpl<BlockT *> &TmpStorage) const;
  132.  
  133.   /// Return the preheader block for this cycle. Pre-header is well-defined for
  134.   /// reducible cycle in docs/LoopTerminology.rst as: the only one entering
  135.   /// block and its only edge is to the entry block. Return null for irreducible
  136.   /// cycles.
  137.   BlockT *getCyclePreheader() const;
  138.  
  139.   /// If the cycle has exactly one entry with exactly one predecessor, return
  140.   /// it, otherwise return nullptr.
  141.   BlockT *getCyclePredecessor() const;
  142.  
  143.   /// Iteration over child cycles.
  144.   //@{
  145.   using const_child_iterator_base =
  146.       typename std::vector<std::unique_ptr<GenericCycle>>::const_iterator;
  147.   struct const_child_iterator
  148.       : iterator_adaptor_base<const_child_iterator, const_child_iterator_base> {
  149.     using Base =
  150.         iterator_adaptor_base<const_child_iterator, const_child_iterator_base>;
  151.  
  152.     const_child_iterator() = default;
  153.     explicit const_child_iterator(const_child_iterator_base I) : Base(I) {}
  154.  
  155.     const const_child_iterator_base &wrapped() { return Base::wrapped(); }
  156.     GenericCycle *operator*() const { return Base::I->get(); }
  157.   };
  158.  
  159.   const_child_iterator child_begin() const {
  160.     return const_child_iterator{Children.begin()};
  161.   }
  162.   const_child_iterator child_end() const {
  163.     return const_child_iterator{Children.end()};
  164.   }
  165.   size_t getNumChildren() const { return Children.size(); }
  166.   iterator_range<const_child_iterator> children() const {
  167.     return llvm::make_range(const_child_iterator{Children.begin()},
  168.                             const_child_iterator{Children.end()});
  169.   }
  170.   //@}
  171.  
  172.   /// Iteration over blocks in the cycle (including entry blocks).
  173.   //@{
  174.   using const_block_iterator = typename std::vector<BlockT *>::const_iterator;
  175.  
  176.   const_block_iterator block_begin() const {
  177.     return const_block_iterator{Blocks.begin()};
  178.   }
  179.   const_block_iterator block_end() const {
  180.     return const_block_iterator{Blocks.end()};
  181.   }
  182.   size_t getNumBlocks() const { return Blocks.size(); }
  183.   iterator_range<const_block_iterator> blocks() const {
  184.     return llvm::make_range(block_begin(), block_end());
  185.   }
  186.   //@}
  187.  
  188.   /// Iteration over entry blocks.
  189.   //@{
  190.   using const_entry_iterator =
  191.       typename SmallVectorImpl<BlockT *>::const_iterator;
  192.  
  193.   size_t getNumEntries() const { return Entries.size(); }
  194.   iterator_range<const_entry_iterator> entries() const {
  195.     return llvm::make_range(Entries.begin(), Entries.end());
  196.   }
  197.   //@}
  198.  
  199.   Printable printEntries(const ContextT &Ctx) const {
  200.     return Printable([this, &Ctx](raw_ostream &Out) {
  201.       bool First = true;
  202.       for (auto *Entry : Entries) {
  203.         if (!First)
  204.           Out << ' ';
  205.         First = false;
  206.         Out << Ctx.print(Entry);
  207.       }
  208.     });
  209.   }
  210.  
  211.   Printable print(const ContextT &Ctx) const {
  212.     return Printable([this, &Ctx](raw_ostream &Out) {
  213.       Out << "depth=" << Depth << ": entries(" << printEntries(Ctx) << ')';
  214.  
  215.       for (auto *Block : Blocks) {
  216.         if (isEntry(Block))
  217.           continue;
  218.  
  219.         Out << ' ' << Ctx.print(Block);
  220.       }
  221.     });
  222.   }
  223. };
  224.  
  225. /// \brief Cycle information for a function.
  226. template <typename ContextT> class GenericCycleInfo {
  227. public:
  228.   using BlockT = typename ContextT::BlockT;
  229.   using CycleT = GenericCycle<ContextT>;
  230.   using FunctionT = typename ContextT::FunctionT;
  231.   template <typename> friend class GenericCycle;
  232.   template <typename> friend class GenericCycleInfoCompute;
  233.  
  234. private:
  235.   ContextT Context;
  236.  
  237.   /// Map basic blocks to their inner-most containing cycle.
  238.   DenseMap<BlockT *, CycleT *> BlockMap;
  239.  
  240.   /// Map basic blocks to their top level containing cycle.
  241.   DenseMap<BlockT *, CycleT *> BlockMapTopLevel;
  242.  
  243.   /// Top-level cycles discovered by any DFS.
  244.   ///
  245.   /// Note: The implementation treats the nullptr as the parent of
  246.   /// every top-level cycle. See \ref contains for an example.
  247.   std::vector<std::unique_ptr<CycleT>> TopLevelCycles;
  248.  
  249.   /// Move \p Child to \p NewParent by manipulating Children vectors.
  250.   ///
  251.   /// Note: This is an incomplete operation that does not update the depth of
  252.   /// the subtree.
  253.   void moveTopLevelCycleToNewParent(CycleT *NewParent, CycleT *Child);
  254.  
  255. public:
  256.   GenericCycleInfo() = default;
  257.   GenericCycleInfo(GenericCycleInfo &&) = default;
  258.   GenericCycleInfo &operator=(GenericCycleInfo &&) = default;
  259.  
  260.   void clear();
  261.   void compute(FunctionT &F);
  262.  
  263.   FunctionT *getFunction() const { return Context.getFunction(); }
  264.   const ContextT &getSSAContext() const { return Context; }
  265.  
  266.   CycleT *getCycle(const BlockT *Block) const;
  267.   unsigned getCycleDepth(const BlockT *Block) const;
  268.   CycleT *getTopLevelParentCycle(BlockT *Block);
  269.  
  270.   /// Methods for debug and self-test.
  271.   //@{
  272. #ifndef NDEBUG
  273.   bool validateTree() const;
  274. #endif
  275.   void print(raw_ostream &Out) const;
  276.   void dump() const { print(dbgs()); }
  277.   //@}
  278.  
  279.   /// Iteration over top-level cycles.
  280.   //@{
  281.   using const_toplevel_iterator_base =
  282.       typename std::vector<std::unique_ptr<CycleT>>::const_iterator;
  283.   struct const_toplevel_iterator
  284.       : iterator_adaptor_base<const_toplevel_iterator,
  285.                               const_toplevel_iterator_base> {
  286.     using Base = iterator_adaptor_base<const_toplevel_iterator,
  287.                                        const_toplevel_iterator_base>;
  288.  
  289.     const_toplevel_iterator() = default;
  290.     explicit const_toplevel_iterator(const_toplevel_iterator_base I)
  291.         : Base(I) {}
  292.  
  293.     const const_toplevel_iterator_base &wrapped() { return Base::wrapped(); }
  294.     CycleT *operator*() const { return Base::I->get(); }
  295.   };
  296.  
  297.   const_toplevel_iterator toplevel_begin() const {
  298.     return const_toplevel_iterator{TopLevelCycles.begin()};
  299.   }
  300.   const_toplevel_iterator toplevel_end() const {
  301.     return const_toplevel_iterator{TopLevelCycles.end()};
  302.   }
  303.  
  304.   iterator_range<const_toplevel_iterator> toplevel_cycles() const {
  305.     return llvm::make_range(const_toplevel_iterator{TopLevelCycles.begin()},
  306.                             const_toplevel_iterator{TopLevelCycles.end()});
  307.   }
  308.   //@}
  309. };
  310.  
  311. /// \brief GraphTraits for iterating over a sub-tree of the CycleT tree.
  312. template <typename CycleRefT, typename ChildIteratorT> struct CycleGraphTraits {
  313.   using NodeRef = CycleRefT;
  314.  
  315.   using nodes_iterator = ChildIteratorT;
  316.   using ChildIteratorType = nodes_iterator;
  317.  
  318.   static NodeRef getEntryNode(NodeRef Graph) { return Graph; }
  319.  
  320.   static ChildIteratorType child_begin(NodeRef Ref) {
  321.     return Ref->child_begin();
  322.   }
  323.   static ChildIteratorType child_end(NodeRef Ref) { return Ref->child_end(); }
  324.  
  325.   // Not implemented:
  326.   // static nodes_iterator nodes_begin(GraphType *G)
  327.   // static nodes_iterator nodes_end  (GraphType *G)
  328.   //    nodes_iterator/begin/end - Allow iteration over all nodes in the graph
  329.  
  330.   // typedef EdgeRef           - Type of Edge token in the graph, which should
  331.   //                             be cheap to copy.
  332.   // typedef ChildEdgeIteratorType - Type used to iterate over children edges in
  333.   //                             graph, dereference to a EdgeRef.
  334.  
  335.   // static ChildEdgeIteratorType child_edge_begin(NodeRef)
  336.   // static ChildEdgeIteratorType child_edge_end(NodeRef)
  337.   //     Return iterators that point to the beginning and ending of the
  338.   //     edge list for the given callgraph node.
  339.   //
  340.   // static NodeRef edge_dest(EdgeRef)
  341.   //     Return the destination node of an edge.
  342.   // static unsigned       size       (GraphType *G)
  343.   //    Return total number of nodes in the graph
  344. };
  345.  
  346. template <typename BlockT>
  347. struct GraphTraits<const GenericCycle<BlockT> *>
  348.     : CycleGraphTraits<const GenericCycle<BlockT> *,
  349.                        typename GenericCycle<BlockT>::const_child_iterator> {};
  350. template <typename BlockT>
  351. struct GraphTraits<GenericCycle<BlockT> *>
  352.     : CycleGraphTraits<GenericCycle<BlockT> *,
  353.                        typename GenericCycle<BlockT>::const_child_iterator> {};
  354.  
  355. } // namespace llvm
  356.  
  357. #endif // LLVM_ADT_GENERICCYCLEINFO_H
  358.