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