2 * Copyright 2011 Christoph Bumiller
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #ifndef __NV50_IR_GRAPH_H__
24 #define __NV50_IR_GRAPH_H__
26 #include "nv50_ir_util.h"
30 #define ITER_NODE(x) reinterpret_cast<Graph::Node *>((x).get())
31 #define ITER_EDGE(x) reinterpret_cast<Graph::Edge *>((x).get())
48 CROSS
, // e.g. loop break
52 Edge(Node
*dst
, Node
*src
, Type kind
);
55 inline Node
*getOrigin() const { return origin
; }
56 inline Node
*getTarget() const { return target
; }
58 inline Type
getType() const { return type
; }
59 const char *typeStr() const;
66 Edge
*next
[2]; // next edge outgoing/incident from/to origin/target
74 class EdgeIterator
: public Iterator
77 EdgeIterator() : e(0), t(0), d(0), rev(false) { }
78 EdgeIterator(Graph::Edge
*first
, int dir
, bool reverse
)
79 : d(dir
), rev(reverse
)
81 t
= e
= ((rev
&& first
) ? first
->prev
[d
] : first
);
86 Graph::Edge
*n
= (rev
? e
->prev
[d
] : e
->next
[d
]);
87 e
= (n
== t
? NULL
: n
);
89 virtual bool end() const { return !e
; }
90 virtual void *get() const { return e
; }
92 inline Node
*getNode() const { assert(e
); return d
?
93 e
->origin
: e
->target
; }
94 inline Edge
*getEdge() const { return e
; }
95 inline Edge::Type
getType() { return e
? e
->getType() : Edge::UNKNOWN
; }
110 void attach(Node
*, Edge::Type
);
114 inline EdgeIterator
outgoing(bool reverse
= false) const;
115 inline EdgeIterator
incident(bool reverse
= false) const;
117 inline Node
*parent() const; // returns NULL if count(incident edges) != 1
119 bool reachableBy(Node
*node
, Node
*term
);
121 inline bool visit(int);
122 inline int getSequence() const;
124 inline int incidentCountFwd() const; // count of incident non-back edges
125 inline int incidentCount() const { return inCount
; }
126 inline int outgoingCount() const { return outCount
; }
128 Graph
*getGraph() const { return graph
; }
142 int tag
; // for temporary use
149 ~Graph(); // does *not* free the nodes (make it an option ?)
151 inline Node
*getRoot() const { return root
; }
153 inline unsigned int getSize() const { return size
; }
155 inline int nextSequence();
157 void insert(Node
*node
); // attach to or set as root
159 IteratorRef
iteratorDFS(bool preorder
= true);
160 IteratorRef
iteratorCFG();
162 // safe iterators are unaffected by changes to the *edges* of the graph
163 IteratorRef
safeIteratorDFS(bool preorder
= true);
164 IteratorRef
safeIteratorCFG();
166 void classifyEdges();
169 void classifyDFS(Node
*, int&);
177 int Graph::nextSequence()
182 Graph::Node
*Graph::Node::parent() const
190 bool Graph::Node::visit(int v
)
198 int Graph::Node::getSequence() const
203 Graph::EdgeIterator
Graph::Node::outgoing(bool reverse
) const
205 return EdgeIterator(out
, 0, reverse
);
208 Graph::EdgeIterator
Graph::Node::incident(bool reverse
) const
210 return EdgeIterator(in
, 1, reverse
);
213 int Graph::Node::incidentCountFwd() const
216 for (EdgeIterator ei
= incident(); !ei
.end(); ei
.next())
217 if (ei
.getType() != Edge::BACK
)
222 } // namespace nv50_ir
224 #endif // __NV50_IR_GRAPH_H__