1 //===- GIMatchDag.h - Represent a DAG to be matched -----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAG_H
10 #define LLVM_UTILS_TABLEGEN_GIMATCHDAG_H
12 #include "GIMatchDagEdge.h"
13 #include "GIMatchDagInstr.h"
14 #include "GIMatchDagOperands.h"
15 #include "GIMatchDagPredicate.h"
16 #include "GIMatchDagPredicateDependencyEdge.h"
21 /// This class manages lifetimes for data associated with the GIMatchDag object.
22 class GIMatchDagContext
{
23 GIMatchDagOperandListContext OperandListCtx
;
26 const GIMatchDagOperandList
&makeEmptyOperandList() {
27 return OperandListCtx
.makeEmptyOperandList();
30 const GIMatchDagOperandList
&makeOperandList(const CodeGenInstruction
&I
) {
31 return OperandListCtx
.makeOperandList(I
);
34 const GIMatchDagOperandList
&makeMIPredicateOperandList() {
35 return OperandListCtx
.makeMIPredicateOperandList();
39 const GIMatchDagOperandList
&makeTwoMOPredicateOperandList() {
40 return OperandListCtx
.makeTwoMOPredicateOperandList();
43 void print(raw_ostream
&OS
) const {
44 OperandListCtx
.print(OS
);
47 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
48 LLVM_DUMP_METHOD
void dump() const { print(errs()); }
49 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
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
>;
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
>;
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
>;
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
>;
76 GIMatchDagContext
&Ctx
;
77 InstrNodesVec InstrNodes
;
78 PredicateNodesVec PredicateNodes
;
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;
87 GIMatchDag(GIMatchDagContext
&Ctx
)
88 : Ctx(Ctx
), InstrNodes(), PredicateNodes(), Edges(),
89 PredicateDependencies() {}
90 GIMatchDag(const GIMatchDag
&) = delete;
92 GIMatchDagContext
&getContext() const { return Ctx
; }
93 edge_iterator
edges_begin() {
94 return raw_pointer_iterator
<EdgesVec::iterator
>(Edges
.begin());
96 edge_iterator
edges_end() {
97 return raw_pointer_iterator
<EdgesVec::iterator
>(Edges
.end());
99 const_edge_iterator
edges_begin() const {
100 return raw_pointer_iterator
<EdgesVec::const_iterator
>(Edges
.begin());
102 const_edge_iterator
edges_end() const {
103 return raw_pointer_iterator
<EdgesVec::const_iterator
>(Edges
.end());
105 iterator_range
<edge_iterator
> edges() {
106 return make_range(edges_begin(), edges_end());
108 iterator_range
<const_edge_iterator
> edges() const {
109 return make_range(edges_begin(), edges_end());
111 iterator_range
<std::vector
<GIMatchDagInstr
*>::iterator
> roots() {
112 return make_range(MatchRoots
.begin(), MatchRoots
.end());
114 iterator_range
<std::vector
<GIMatchDagInstr
*>::const_iterator
> roots() const {
115 return make_range(MatchRoots
.begin(), MatchRoots
.end());
118 instr_node_iterator
instr_nodes_begin() {
119 return raw_pointer_iterator
<InstrNodesVec::iterator
>(InstrNodes
.begin());
121 instr_node_iterator
instr_nodes_end() {
122 return raw_pointer_iterator
<InstrNodesVec::iterator
>(InstrNodes
.end());
124 const_instr_node_iterator
instr_nodes_begin() const {
125 return raw_pointer_iterator
<InstrNodesVec::const_iterator
>(
128 const_instr_node_iterator
instr_nodes_end() const {
129 return raw_pointer_iterator
<InstrNodesVec::const_iterator
>(
132 iterator_range
<instr_node_iterator
> instr_nodes() {
133 return make_range(instr_nodes_begin(), instr_nodes_end());
135 iterator_range
<const_instr_node_iterator
> instr_nodes() const {
136 return make_range(instr_nodes_begin(), instr_nodes_end());
138 predicate_edge_iterator
predicate_edges_begin() {
139 return raw_pointer_iterator
<PredicateDependencyEdgesVec::iterator
>(
140 PredicateDependencies
.begin());
142 predicate_edge_iterator
predicate_edges_end() {
143 return raw_pointer_iterator
<PredicateDependencyEdgesVec::iterator
>(
144 PredicateDependencies
.end());
146 const_predicate_edge_iterator
predicate_edges_begin() const {
147 return raw_pointer_iterator
<PredicateDependencyEdgesVec::const_iterator
>(
148 PredicateDependencies
.begin());
150 const_predicate_edge_iterator
predicate_edges_end() const {
151 return raw_pointer_iterator
<PredicateDependencyEdgesVec::const_iterator
>(
152 PredicateDependencies
.end());
154 iterator_range
<predicate_edge_iterator
> predicate_edges() {
155 return make_range(predicate_edges_begin(), predicate_edges_end());
157 iterator_range
<const_predicate_edge_iterator
> predicate_edges() const {
158 return make_range(predicate_edges_begin(), predicate_edges_end());
160 predicate_iterator
predicates_begin() {
161 return raw_pointer_iterator
<PredicateNodesVec::iterator
>(
162 PredicateNodes
.begin());
164 predicate_iterator
predicates_end() {
165 return raw_pointer_iterator
<PredicateNodesVec::iterator
>(
166 PredicateNodes
.end());
168 const_predicate_iterator
predicates_begin() const {
169 return raw_pointer_iterator
<PredicateNodesVec::const_iterator
>(
170 PredicateNodes
.begin());
172 const_predicate_iterator
predicates_end() const {
173 return raw_pointer_iterator
<PredicateNodesVec::const_iterator
>(
174 PredicateNodes
.end());
176 iterator_range
<predicate_iterator
> predicates() {
177 return make_range(predicates_begin(), predicates_end());
179 iterator_range
<const_predicate_iterator
> predicates() const {
180 return make_range(predicates_begin(), predicates_end());
183 template <class... Args
> GIMatchDagInstr
*addInstrNode(Args
&&... args
) {
185 std::make_unique
<GIMatchDagInstr
>(*this, std::forward
<Args
>(args
)...);
186 auto ObjRaw
= Obj
.get();
187 InstrNodes
.push_back(std::move(Obj
));
191 template <class T
, class... 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
));
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
));
206 template <class... 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
));
215 size_t getInstrNodeIdx(instr_node_iterator I
) {
216 return std::distance(instr_nodes_begin(), I
);
218 size_t getInstrNodeIdx(const_instr_node_iterator I
) const {
219 return std::distance(instr_nodes_begin(), I
);
221 size_t getNumInstrNodes() const { return InstrNodes
.size(); }
222 size_t getNumEdges() const { return Edges
.size(); }
223 size_t getNumPredicates() const { return PredicateNodes
.size(); }
225 void setHasPostMatchPredicate(bool V
) { HasPostMatchPredicate
= V
; }
226 bool hasPostMatchPredicate() const { return HasPostMatchPredicate
; }
228 void addMatchRoot(GIMatchDagInstr
*N
) { MatchRoots
.push_back(N
); }
230 LLVM_DUMP_METHOD
void print(raw_ostream
&OS
) const;
232 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
233 LLVM_DUMP_METHOD
void dump() const { print(errs()); }
234 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
236 void writeDOTGraph(raw_ostream
&OS
, StringRef ID
) const;
239 raw_ostream
&operator<<(raw_ostream
&OS
, const GIMatchDag
&G
);
241 } // end namespace llvm
243 #endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAG_H