1 /* Graph representation and manipulation functions.
2 Copyright (C) 2007-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 /* Dumps graph G into F. */
31 dump_graph (FILE *f
, struct graph
*g
)
36 for (i
= 0; i
< g
->n_vertices
; i
++)
38 if (!g
->vertices
[i
].pred
39 && !g
->vertices
[i
].succ
)
42 fprintf (f
, "%d (%d)\t<-", i
, g
->vertices
[i
].component
);
43 for (e
= g
->vertices
[i
].pred
; e
; e
= e
->pred_next
)
44 fprintf (f
, " %d", e
->src
);
48 for (e
= g
->vertices
[i
].succ
; e
; e
= e
->succ_next
)
49 fprintf (f
, " %d", e
->dest
);
54 /* Creates a new graph with N_VERTICES vertices. */
57 new_graph (int n_vertices
)
59 struct graph
*g
= XNEW (struct graph
);
61 g
->n_vertices
= n_vertices
;
62 g
->vertices
= XCNEWVEC (struct vertex
, n_vertices
);
67 /* Adds an edge from F to T to graph G. The new edge is returned. */
70 add_edge (struct graph
*g
, int f
, int t
)
72 struct graph_edge
*e
= XNEW (struct graph_edge
);
73 struct vertex
*vf
= &g
->vertices
[f
], *vt
= &g
->vertices
[t
];
79 e
->pred_next
= vt
->pred
;
82 e
->succ_next
= vf
->succ
;
88 /* Moves all the edges incident with U to V. */
91 identify_vertices (struct graph
*g
, int v
, int u
)
93 struct vertex
*vv
= &g
->vertices
[v
];
94 struct vertex
*uu
= &g
->vertices
[u
];
95 struct graph_edge
*e
, *next
;
97 for (e
= uu
->succ
; e
; e
= next
)
102 e
->succ_next
= vv
->succ
;
107 for (e
= uu
->pred
; e
; e
= next
)
112 e
->pred_next
= vv
->pred
;
118 /* Helper function for graphds_dfs. Returns the source vertex of E, in the
119 direction given by FORWARD. */
122 dfs_edge_src (struct graph_edge
*e
, bool forward
)
124 return forward
? e
->src
: e
->dest
;
127 /* Helper function for graphds_dfs. Returns the destination vertex of E, in
128 the direction given by FORWARD. */
131 dfs_edge_dest (struct graph_edge
*e
, bool forward
)
133 return forward
? e
->dest
: e
->src
;
136 /* Helper function for graphds_dfs. Returns the first edge after E (including
137 E), in the graph direction given by FORWARD, that belongs to SUBGRAPH. */
139 static inline struct graph_edge
*
140 foll_in_subgraph (struct graph_edge
*e
, bool forward
, bitmap subgraph
)
149 d
= dfs_edge_dest (e
, forward
);
150 if (bitmap_bit_p (subgraph
, d
))
153 e
= forward
? e
->succ_next
: e
->pred_next
;
159 /* Helper function for graphds_dfs. Select the first edge from V in G, in the
160 direction given by FORWARD, that belongs to SUBGRAPH. */
162 static inline struct graph_edge
*
163 dfs_fst_edge (struct graph
*g
, int v
, bool forward
, bitmap subgraph
)
165 struct graph_edge
*e
;
167 e
= (forward
? g
->vertices
[v
].succ
: g
->vertices
[v
].pred
);
168 return foll_in_subgraph (e
, forward
, subgraph
);
171 /* Helper function for graphds_dfs. Returns the next edge after E, in the
172 graph direction given by FORWARD, that belongs to SUBGRAPH. */
174 static inline struct graph_edge
*
175 dfs_next_edge (struct graph_edge
*e
, bool forward
, bitmap subgraph
)
177 return foll_in_subgraph (forward
? e
->succ_next
: e
->pred_next
,
181 /* Runs dfs search over vertices of G, from NQ vertices in queue QS.
182 The vertices in postorder are stored into QT. If FORWARD is false,
183 backward dfs is run. If SUBGRAPH is not NULL, it specifies the
184 subgraph of G to run DFS on. Returns the number of the components
185 of the graph (number of the restarts of DFS). */
188 graphds_dfs (struct graph
*g
, int *qs
, int nq
, vec
<int> *qt
,
189 bool forward
, bitmap subgraph
)
191 int i
, tick
= 0, v
, comp
= 0, top
;
192 struct graph_edge
*e
;
193 struct graph_edge
**stack
= XNEWVEC (struct graph_edge
*, g
->n_vertices
);
199 EXECUTE_IF_SET_IN_BITMAP (subgraph
, 0, av
, bi
)
201 g
->vertices
[av
].component
= -1;
202 g
->vertices
[av
].post
= -1;
207 for (i
= 0; i
< g
->n_vertices
; i
++)
209 g
->vertices
[i
].component
= -1;
210 g
->vertices
[i
].post
= -1;
214 for (i
= 0; i
< nq
; i
++)
217 if (g
->vertices
[v
].post
!= -1)
220 g
->vertices
[v
].component
= comp
++;
221 e
= dfs_fst_edge (g
, v
, forward
, subgraph
);
228 if (g
->vertices
[dfs_edge_dest (e
, forward
)].component
231 e
= dfs_next_edge (e
, forward
, subgraph
);
238 g
->vertices
[v
].post
= tick
++;
244 v
= dfs_edge_src (e
, forward
);
245 e
= dfs_next_edge (e
, forward
, subgraph
);
250 v
= dfs_edge_dest (e
, forward
);
251 e
= dfs_fst_edge (g
, v
, forward
, subgraph
);
252 g
->vertices
[v
].component
= comp
- 1;
261 /* Determines the strongly connected components of G, using the algorithm of
262 Tarjan -- first determine the postorder dfs numbering in reversed graph,
263 then run the dfs on the original graph in the order given by decreasing
264 numbers assigned by the previous pass. If SUBGRAPH is not NULL, it
265 specifies the subgraph of G whose strongly connected components we want
268 After running this function, v->component is the number of the strongly
269 connected component for each vertex of G. Returns the number of the
273 graphds_scc (struct graph
*g
, bitmap subgraph
)
275 int *queue
= XNEWVEC (int, g
->n_vertices
);
276 vec
<int> postorder
= vNULL
;
284 EXECUTE_IF_SET_IN_BITMAP (subgraph
, 0, v
, bi
)
291 for (i
= 0; i
< g
->n_vertices
; i
++)
296 graphds_dfs (g
, queue
, nq
, &postorder
, false, subgraph
);
297 gcc_assert (postorder
.length () == (unsigned) nq
);
299 for (i
= 0; i
< nq
; i
++)
300 queue
[i
] = postorder
[nq
- i
- 1];
301 comp
= graphds_dfs (g
, queue
, nq
, NULL
, true, subgraph
);
304 postorder
.release ();
309 /* Runs CALLBACK for all edges in G. */
312 for_each_edge (struct graph
*g
, graphds_edge_callback callback
)
314 struct graph_edge
*e
;
317 for (i
= 0; i
< g
->n_vertices
; i
++)
318 for (e
= g
->vertices
[i
].succ
; e
; e
= e
->succ_next
)
322 /* Releases the memory occupied by G. */
325 free_graph (struct graph
*g
)
327 struct graph_edge
*e
, *n
;
331 for (i
= 0; i
< g
->n_vertices
; i
++)
334 for (e
= v
->succ
; e
; e
= n
)
344 /* Returns the nearest common ancestor of X and Y in tree whose parent
345 links are given by PARENT. MARKS is the array used to mark the
346 vertices of the tree, and MARK is the number currently used as a mark. */
349 tree_nca (int x
, int y
, int *parent
, int *marks
, int mark
)
351 if (x
== -1 || x
== y
)
354 /* We climb with X and Y up the tree, marking the visited nodes. When
355 we first arrive to a marked node, it is the common ancestor. */
364 if (marks
[x
] == mark
)
371 if (marks
[y
] == mark
)
376 /* If we reached the root with one of the vertices, continue
377 with the other one till we reach the marked part of the
381 for (y
= parent
[y
]; marks
[y
] != mark
; y
= parent
[y
])
388 for (x
= parent
[x
]; marks
[x
] != mark
; x
= parent
[x
])
395 /* Determines the dominance tree of G (stored in the PARENT, SON and BROTHER
396 arrays), where the entry node is ENTRY. */
399 graphds_domtree (struct graph
*g
, int entry
,
400 int *parent
, int *son
, int *brother
)
402 vec
<int> postorder
= vNULL
;
403 int *marks
= XCNEWVEC (int, g
->n_vertices
);
404 int mark
= 1, i
, v
, idom
;
406 struct graph_edge
*e
;
408 /* We use a slight modification of the standard iterative algorithm, as
411 K. D. Cooper, T. J. Harvey and K. Kennedy: A Simple, Fast Dominance
414 sort vertices in reverse postorder
419 while (anything changes)
421 dom(v) = {v} union (intersection of dom(p) over all predecessors of v)
423 The sets dom(v) are represented by the parent links in the current version
424 of the dominance tree. */
426 for (i
= 0; i
< g
->n_vertices
; i
++)
432 graphds_dfs (g
, &entry
, 1, &postorder
, true, NULL
);
433 gcc_assert (postorder
.length () == (unsigned) g
->n_vertices
);
434 gcc_assert (postorder
[g
->n_vertices
- 1] == entry
);
440 for (i
= g
->n_vertices
- 2; i
>= 0; i
--)
444 for (e
= g
->vertices
[v
].pred
; e
; e
= e
->pred_next
)
447 && parent
[e
->src
] == -1)
450 idom
= tree_nca (idom
, e
->src
, parent
, marks
, mark
++);
453 if (idom
!= parent
[v
])
462 postorder
.release ();
464 for (i
= 0; i
< g
->n_vertices
; i
++)
467 brother
[i
] = son
[parent
[i
]];