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