Interval.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file contains the declaration of the Interval class, which
  15. // represents a set of CFG nodes and is a portion of an interval partition.
  16. //
  17. // Intervals have some interesting and useful properties, including the
  18. // following:
  19. // 1. The header node of an interval dominates all of the elements of the
  20. // interval
  21. //
  22. //===----------------------------------------------------------------------===//
  23. #ifndef LLVM_ANALYSIS_INTERVAL_H
  24. #define LLVM_ANALYSIS_INTERVAL_H
  25. #include "llvm/ADT/GraphTraits.h"
  26. #include <vector>
  27. namespace llvm {
  28. class BasicBlock;
  29. class raw_ostream;
  30. //===----------------------------------------------------------------------===//
  31. //
  32. /// Interval Class - An Interval is a set of nodes defined such that every node
  33. /// in the interval has all of its predecessors in the interval (except for the
  34. /// header)
  35. ///
  36. class Interval {
  37. /// HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
  38. /// interval. Also, any loops in this interval must go through the HeaderNode.
  39. ///
  40. BasicBlock *HeaderNode;
  41. public:
  42. using succ_iterator = std::vector<BasicBlock*>::iterator;
  43. using pred_iterator = std::vector<BasicBlock*>::iterator;
  44. using node_iterator = std::vector<BasicBlock*>::iterator;
  45. inline Interval(BasicBlock *Header) : HeaderNode(Header) {
  46. Nodes.push_back(Header);
  47. }
  48. inline BasicBlock *getHeaderNode() const { return HeaderNode; }
  49. /// Nodes - The basic blocks in this interval.
  50. std::vector<BasicBlock*> Nodes;
  51. /// Successors - List of BasicBlocks that are reachable directly from nodes in
  52. /// this interval, but are not in the interval themselves.
  53. /// These nodes necessarily must be header nodes for other intervals.
  54. std::vector<BasicBlock*> Successors;
  55. /// Predecessors - List of BasicBlocks that have this Interval's header block
  56. /// as one of their successors.
  57. std::vector<BasicBlock*> Predecessors;
  58. /// contains - Find out if a basic block is in this interval
  59. inline bool contains(BasicBlock *BB) const {
  60. for (BasicBlock *Node : Nodes)
  61. if (Node == BB)
  62. return true;
  63. return false;
  64. // I don't want the dependency on <algorithm>
  65. //return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
  66. }
  67. /// isSuccessor - find out if a basic block is a successor of this Interval
  68. inline bool isSuccessor(BasicBlock *BB) const {
  69. for (BasicBlock *Successor : Successors)
  70. if (Successor == BB)
  71. return true;
  72. return false;
  73. // I don't want the dependency on <algorithm>
  74. //return find(Successors.begin(), Successors.end(), BB) != Successors.end();
  75. }
  76. /// Equality operator. It is only valid to compare two intervals from the
  77. /// same partition, because of this, all we have to check is the header node
  78. /// for equality.
  79. inline bool operator==(const Interval &I) const {
  80. return HeaderNode == I.HeaderNode;
  81. }
  82. /// print - Show contents in human readable format...
  83. void print(raw_ostream &O) const;
  84. };
  85. /// succ_begin/succ_end - define methods so that Intervals may be used
  86. /// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
  87. ///
  88. inline Interval::succ_iterator succ_begin(Interval *I) {
  89. return I->Successors.begin();
  90. }
  91. inline Interval::succ_iterator succ_end(Interval *I) {
  92. return I->Successors.end();
  93. }
  94. /// pred_begin/pred_end - define methods so that Intervals may be used
  95. /// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
  96. ///
  97. inline Interval::pred_iterator pred_begin(Interval *I) {
  98. return I->Predecessors.begin();
  99. }
  100. inline Interval::pred_iterator pred_end(Interval *I) {
  101. return I->Predecessors.end();
  102. }
  103. template <> struct GraphTraits<Interval*> {
  104. using NodeRef = Interval *;
  105. using ChildIteratorType = Interval::succ_iterator;
  106. static NodeRef getEntryNode(Interval *I) { return I; }
  107. /// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
  108. static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); }
  109. static ChildIteratorType child_end(NodeRef N) { return succ_end(N); }
  110. };
  111. template <> struct GraphTraits<Inverse<Interval*>> {
  112. using NodeRef = Interval *;
  113. using ChildIteratorType = Interval::pred_iterator;
  114. static NodeRef getEntryNode(Inverse<Interval *> G) { return G.Graph; }
  115. static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
  116. static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
  117. };
  118. } // end namespace llvm
  119. #endif // LLVM_ANALYSIS_INTERVAL_H
  120. #ifdef __GNUC__
  121. #pragma GCC diagnostic pop
  122. #endif