GIMatchDag.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //===- GIMatchDag.h - Represent a DAG to be matched -----------------------===//
  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. #ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAG_H
  9. #define LLVM_UTILS_TABLEGEN_GIMATCHDAG_H
  10. #include "GIMatchDagEdge.h"
  11. #include "GIMatchDagInstr.h"
  12. #include "GIMatchDagOperands.h"
  13. #include "GIMatchDagPredicate.h"
  14. #include "GIMatchDagPredicateDependencyEdge.h"
  15. namespace llvm {
  16. /// This class manages lifetimes for data associated with the GIMatchDag object.
  17. class GIMatchDagContext {
  18. GIMatchDagOperandListContext OperandListCtx;
  19. public:
  20. const GIMatchDagOperandList &makeEmptyOperandList() {
  21. return OperandListCtx.makeEmptyOperandList();
  22. }
  23. const GIMatchDagOperandList &makeOperandList(const CodeGenInstruction &I) {
  24. return OperandListCtx.makeOperandList(I);
  25. }
  26. const GIMatchDagOperandList &makeMIPredicateOperandList() {
  27. return OperandListCtx.makeMIPredicateOperandList();
  28. }
  29. const GIMatchDagOperandList &makeTwoMOPredicateOperandList() {
  30. return OperandListCtx.makeTwoMOPredicateOperandList();
  31. }
  32. void print(raw_ostream &OS) const {
  33. OperandListCtx.print(OS);
  34. }
  35. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  36. LLVM_DUMP_METHOD void dump() const { print(errs()); }
  37. #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  38. };
  39. class GIMatchDag {
  40. public:
  41. using InstrNodesVec = std::vector<std::unique_ptr<GIMatchDagInstr>>;
  42. using instr_node_iterator = raw_pointer_iterator<InstrNodesVec::iterator>;
  43. using const_instr_node_iterator =
  44. raw_pointer_iterator<InstrNodesVec::const_iterator>;
  45. using EdgesVec = std::vector<std::unique_ptr<GIMatchDagEdge>>;
  46. using edge_iterator = raw_pointer_iterator<EdgesVec::iterator>;
  47. using const_edge_iterator = raw_pointer_iterator<EdgesVec::const_iterator>;
  48. using PredicateNodesVec = std::vector<std::unique_ptr<GIMatchDagPredicate>>;
  49. using predicate_iterator = raw_pointer_iterator<PredicateNodesVec::iterator>;
  50. using const_predicate_iterator =
  51. raw_pointer_iterator<PredicateNodesVec::const_iterator>;
  52. using PredicateDependencyEdgesVec =
  53. std::vector<std::unique_ptr<GIMatchDagPredicateDependencyEdge>>;
  54. using predicate_edge_iterator =
  55. raw_pointer_iterator<PredicateDependencyEdgesVec::iterator>;
  56. using const_predicate_edge_iterator =
  57. raw_pointer_iterator<PredicateDependencyEdgesVec::const_iterator>;
  58. protected:
  59. GIMatchDagContext &Ctx;
  60. InstrNodesVec InstrNodes;
  61. PredicateNodesVec PredicateNodes;
  62. EdgesVec Edges;
  63. PredicateDependencyEdgesVec PredicateDependencies;
  64. std::vector<GIMatchDagInstr *> MatchRoots;
  65. // FIXME: This is a temporary measure while we still accept arbitrary code
  66. // blocks to fix up the matcher while it's being developed.
  67. bool HasPostMatchPredicate = false;
  68. public:
  69. GIMatchDag(GIMatchDagContext &Ctx) : Ctx(Ctx) {}
  70. GIMatchDag(const GIMatchDag &) = delete;
  71. GIMatchDagContext &getContext() const { return Ctx; }
  72. edge_iterator edges_begin() {
  73. return raw_pointer_iterator<EdgesVec::iterator>(Edges.begin());
  74. }
  75. edge_iterator edges_end() {
  76. return raw_pointer_iterator<EdgesVec::iterator>(Edges.end());
  77. }
  78. const_edge_iterator edges_begin() const {
  79. return raw_pointer_iterator<EdgesVec::const_iterator>(Edges.begin());
  80. }
  81. const_edge_iterator edges_end() const {
  82. return raw_pointer_iterator<EdgesVec::const_iterator>(Edges.end());
  83. }
  84. iterator_range<edge_iterator> edges() {
  85. return make_range(edges_begin(), edges_end());
  86. }
  87. iterator_range<const_edge_iterator> edges() const {
  88. return make_range(edges_begin(), edges_end());
  89. }
  90. iterator_range<std::vector<GIMatchDagInstr *>::iterator> roots() {
  91. return make_range(MatchRoots.begin(), MatchRoots.end());
  92. }
  93. iterator_range<std::vector<GIMatchDagInstr *>::const_iterator> roots() const {
  94. return make_range(MatchRoots.begin(), MatchRoots.end());
  95. }
  96. instr_node_iterator instr_nodes_begin() {
  97. return raw_pointer_iterator<InstrNodesVec::iterator>(InstrNodes.begin());
  98. }
  99. instr_node_iterator instr_nodes_end() {
  100. return raw_pointer_iterator<InstrNodesVec::iterator>(InstrNodes.end());
  101. }
  102. const_instr_node_iterator instr_nodes_begin() const {
  103. return raw_pointer_iterator<InstrNodesVec::const_iterator>(
  104. InstrNodes.begin());
  105. }
  106. const_instr_node_iterator instr_nodes_end() const {
  107. return raw_pointer_iterator<InstrNodesVec::const_iterator>(
  108. InstrNodes.end());
  109. }
  110. iterator_range<instr_node_iterator> instr_nodes() {
  111. return make_range(instr_nodes_begin(), instr_nodes_end());
  112. }
  113. iterator_range<const_instr_node_iterator> instr_nodes() const {
  114. return make_range(instr_nodes_begin(), instr_nodes_end());
  115. }
  116. predicate_edge_iterator predicate_edges_begin() {
  117. return raw_pointer_iterator<PredicateDependencyEdgesVec::iterator>(
  118. PredicateDependencies.begin());
  119. }
  120. predicate_edge_iterator predicate_edges_end() {
  121. return raw_pointer_iterator<PredicateDependencyEdgesVec::iterator>(
  122. PredicateDependencies.end());
  123. }
  124. const_predicate_edge_iterator predicate_edges_begin() const {
  125. return raw_pointer_iterator<PredicateDependencyEdgesVec::const_iterator>(
  126. PredicateDependencies.begin());
  127. }
  128. const_predicate_edge_iterator predicate_edges_end() const {
  129. return raw_pointer_iterator<PredicateDependencyEdgesVec::const_iterator>(
  130. PredicateDependencies.end());
  131. }
  132. iterator_range<predicate_edge_iterator> predicate_edges() {
  133. return make_range(predicate_edges_begin(), predicate_edges_end());
  134. }
  135. iterator_range<const_predicate_edge_iterator> predicate_edges() const {
  136. return make_range(predicate_edges_begin(), predicate_edges_end());
  137. }
  138. predicate_iterator predicates_begin() {
  139. return raw_pointer_iterator<PredicateNodesVec::iterator>(
  140. PredicateNodes.begin());
  141. }
  142. predicate_iterator predicates_end() {
  143. return raw_pointer_iterator<PredicateNodesVec::iterator>(
  144. PredicateNodes.end());
  145. }
  146. const_predicate_iterator predicates_begin() const {
  147. return raw_pointer_iterator<PredicateNodesVec::const_iterator>(
  148. PredicateNodes.begin());
  149. }
  150. const_predicate_iterator predicates_end() const {
  151. return raw_pointer_iterator<PredicateNodesVec::const_iterator>(
  152. PredicateNodes.end());
  153. }
  154. iterator_range<predicate_iterator> predicates() {
  155. return make_range(predicates_begin(), predicates_end());
  156. }
  157. iterator_range<const_predicate_iterator> predicates() const {
  158. return make_range(predicates_begin(), predicates_end());
  159. }
  160. template <class... Args> GIMatchDagInstr *addInstrNode(Args &&... args) {
  161. auto Obj =
  162. std::make_unique<GIMatchDagInstr>(*this, std::forward<Args>(args)...);
  163. auto ObjRaw = Obj.get();
  164. InstrNodes.push_back(std::move(Obj));
  165. return ObjRaw;
  166. }
  167. template <class T, class... Args>
  168. T *addPredicateNode(Args &&... args) {
  169. auto Obj = std::make_unique<T>(getContext(), std::forward<Args>(args)...);
  170. auto ObjRaw = Obj.get();
  171. PredicateNodes.push_back(std::move(Obj));
  172. return ObjRaw;
  173. }
  174. template <class... Args> GIMatchDagEdge *addEdge(Args &&... args) {
  175. auto Obj = std::make_unique<GIMatchDagEdge>(std::forward<Args>(args)...);
  176. auto ObjRaw = Obj.get();
  177. Edges.push_back(std::move(Obj));
  178. return ObjRaw;
  179. }
  180. template <class... Args>
  181. GIMatchDagPredicateDependencyEdge *addPredicateDependency(Args &&... args) {
  182. auto Obj = std::make_unique<GIMatchDagPredicateDependencyEdge>(
  183. std::forward<Args>(args)...);
  184. auto ObjRaw = Obj.get();
  185. PredicateDependencies.push_back(std::move(Obj));
  186. return ObjRaw;
  187. }
  188. size_t getInstrNodeIdx(instr_node_iterator I) {
  189. return std::distance(instr_nodes_begin(), I);
  190. }
  191. size_t getInstrNodeIdx(const_instr_node_iterator I) const {
  192. return std::distance(instr_nodes_begin(), I);
  193. }
  194. size_t getNumInstrNodes() const { return InstrNodes.size(); }
  195. size_t getNumEdges() const { return Edges.size(); }
  196. size_t getNumPredicates() const { return PredicateNodes.size(); }
  197. void setHasPostMatchPredicate(bool V) { HasPostMatchPredicate = V; }
  198. bool hasPostMatchPredicate() const { return HasPostMatchPredicate; }
  199. void addMatchRoot(GIMatchDagInstr *N) { MatchRoots.push_back(N); }
  200. LLVM_DUMP_METHOD void print(raw_ostream &OS) const;
  201. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  202. LLVM_DUMP_METHOD void dump() const { print(errs()); }
  203. #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  204. void writeDOTGraph(raw_ostream &OS, StringRef ID) const;
  205. };
  206. raw_ostream &operator<<(raw_ostream &OS, const GIMatchDag &G);
  207. } // end namespace llvm
  208. #endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAG_H