1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011 Christoph Bumiller
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included in
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * all copies or substantial portions of the Software.
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef __NV50_IR_GRAPH_H__
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define __NV50_IR_GRAPH_H__
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50_ir_util.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <vector>
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace nv50_ir {
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ITER_NODE(x) reinterpret_cast<Graph::Node *>((x).get())
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ITER_EDGE(x) reinterpret_cast<Graph::Edge *>((x).get())
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// A connected graph.
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Graph
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   class Node;
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   class Edge
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   public:
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      enum Type
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         UNKNOWN,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         TREE,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         FORWARD,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BACK,
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         CROSS, // e.g. loop break
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         DUMMY
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      };
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Edge(Node *dst, Node *src, Type kind);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ~Edge() { unlink(); }
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Node *getOrigin() const { return origin; }
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Node *getTarget() const { return target; }
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Type getType() const { return type; }
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *typeStr() const;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   private:
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Node *origin;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Node *target;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Type type;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Edge *next[2]; // next edge outgoing/incident from/to origin/target
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Edge *prev[2];
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void unlink();
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      friend class Graph;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   class EdgeIterator : public Iterator
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   public:
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EdgeIterator() : e(0), t(0), d(0), rev(false) { }
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EdgeIterator(Graph::Edge *first, int dir, bool reverse)
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         : d(dir), rev(reverse)
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t = e = ((rev && first) ? first->prev[d] : first);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      virtual void next()
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Graph::Edge *n = (rev ? e->prev[d] : e->next[d]);
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         e = (n == t ? NULL : n);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      virtual bool end() const { return !e; }
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      virtual void *get() const { return e; }
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Node *getNode() const { assert(e); return d ?
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   e->origin : e->target; }
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Edge *getEdge() const { return e; }
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Edge::Type getType() { return e ? e->getType() : Edge::UNKNOWN; }
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   private:
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Graph::Edge *e;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Graph::Edge *t;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int d;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool rev;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   class Node
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   public:
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Node(void *);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ~Node() { cut(); }
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void attach(Node *, Edge::Type);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool detach(Node *);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void cut();
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline EdgeIterator outgoing(bool reverse = false) const;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline EdgeIterator incident(bool reverse = false) const;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline Node *parent() const; // returns NULL if count(incident edges) != 1
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool reachableBy(const Node *node, const Node *term) const;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline bool visit(int);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline int  getSequence() const;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline int incidentCountFwd() const; // count of incident non-back edges
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline int incidentCount() const { return inCount; }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inline int outgoingCount() const { return outCount; }
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Graph *getGraph() const { return graph; }
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void *data;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   private:
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Edge *in;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Edge *out;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Graph *graph;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int visited;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int16_t inCount;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int16_t outCount;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   public:
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int tag; // for temporary use
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      friend class Graph;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Graph();
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ~Graph(); // does *not* free the nodes (make it an option ?)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inline Node *getRoot() const { return root; }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inline unsigned int getSize() const { return size; }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inline int nextSequence();
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void insert(Node *node); // attach to or set as root
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   IteratorRef iteratorDFS(bool preorder = true);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   IteratorRef iteratorCFG();
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   // safe iterators are unaffected by changes to the *edges* of the graph
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   IteratorRef safeIteratorDFS(bool preorder = true);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   IteratorRef safeIteratorCFG();
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void classifyEdges();
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   // @weights: indexed by Node::tag
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int findLightestPathWeight(Node *, Node *, const std::vector<int>& weights);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void classifyDFS(Node *, int&);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Node *root;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int size;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int sequence;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint Graph::nextSequence()
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ++sequence;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGraph::Node *Graph::Node::parent() const
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (inCount != 1)
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(in);
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return in->origin;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool Graph::Node::visit(int v)
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (visited == v)
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visited = v;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint Graph::Node::getSequence() const
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visited;
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGraph::EdgeIterator Graph::Node::outgoing(bool reverse) const
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EdgeIterator(out, 0, reverse);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGraph::EdgeIterator Graph::Node::incident(bool reverse) const
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EdgeIterator(in, 1, reverse);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint Graph::Node::incidentCountFwd() const
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int n = 0;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (EdgeIterator ei = incident(); !ei.end(); ei.next())
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ei.getType() != Edge::BACK)
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ++n;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return n;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // namespace nv50_ir
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif // __NV50_IR_GRAPH_H__
229