1 /* Graph representation and manipulation functions.
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 /* Dumps graph G into F. */
32 dump_graph (FILE *f
, struct graph
*g
)
37 for (i
= 0; i
< g
->n_vertices
; i
++)
39 if (!g
->vertices
[i
].pred
40 && !g
->vertices
[i
].succ
)
43 fprintf (f
, "%d (%d)\t<-", i
, g
->vertices
[i
].component
);
44 for (e
= g
->vertices
[i
].pred
; e
; e
= e
->pred_next
)
45 fprintf (f
, " %d", e
->src
);
49 for (e
= g
->vertices
[i
].succ
; e
; e
= e
->succ_next
)
50 fprintf (f
, " %d", e
->dest
);
55 /* Creates a new graph with N_VERTICES vertices. */
58 new_graph (int n_vertices
)
60 struct graph
*g
= XNEW (struct graph
);
62 g
->n_vertices
= n_vertices
;
63 g
->vertices
= XCNEWVEC (struct vertex
, n_vertices
);
68 /* Adds an edge from F to T to graph G. The new edge is returned. */
71 add_edge (struct graph
*g
, int f
, int t
)
73 struct graph_edge
*e
= XNEW (struct graph_edge
);
74 struct vertex
*vf
= &g
->vertices
[f
], *vt
= &g
->vertices
[t
];
80 e
->pred_next
= vt
->pred
;
83 e
->succ_next
= vf
->succ
;
89 /* Moves all the edges incident with U to V. */
92 identify_vertices (struct graph
*g
, int v
, int u
)
94 struct vertex
*vv
= &g
->vertices
[v
];
95 struct vertex
*uu
= &g
->vertices
[u
];
96 struct graph_edge
*e
, *next
;
98 for (e
= uu
->succ
; e
; e
= next
)
103 e
->succ_next
= vv
->succ
;
108 for (e
= uu
->pred
; e
; e
= next
)
113 e
->pred_next
= vv
->pred
;
119 /* Helper function for graphds_dfs. Returns the source vertex of E, in the
120 direction given by FORWARD. */
123 dfs_edge_src (struct graph_edge
*e
, bool forward
)
125 return forward
? e
->src
: e
->dest
;
128 /* Helper function for graphds_dfs. Returns the destination vertex of E, in
129 the direction given by FORWARD. */
132 dfs_edge_dest (struct graph_edge
*e
, bool forward
)
134 return forward
? e
->dest
: e
->src
;
137 /* Helper function for graphds_dfs. Returns the first edge after E (including
138 E), in the graph direction given by FORWARD, that belongs to SUBGRAPH. */
140 static inline struct graph_edge
*
141 foll_in_subgraph (struct graph_edge
*e
, bool forward
, bitmap subgraph
)
150 d
= dfs_edge_dest (e
, forward
);
151 if (bitmap_bit_p (subgraph
, d
))
154 e
= forward
? e
->succ_next
: e
->pred_next
;
160 /* Helper function for graphds_dfs. Select the first edge from V in G, in the
161 direction given by FORWARD, that belongs to SUBGRAPH. */
163 static inline struct graph_edge
*
164 dfs_fst_edge (struct graph
*g
, int v
, bool forward
, bitmap subgraph
)
166 struct graph_edge
*e
;
168 e
= (forward
? g
->vertices
[v
].succ
: g
->vertices
[v
].pred
);
169 return foll_in_subgraph (e
, forward
, subgraph
);
172 /* Helper function for graphds_dfs. Returns the next edge after E, in the
173 graph direction given by FORWARD, that belongs to SUBGRAPH. */
175 static inline struct graph_edge
*
176 dfs_next_edge (struct graph_edge
*e
, bool forward
, bitmap subgraph
)
178 return foll_in_subgraph (forward
? e
->succ_next
: e
->pred_next
,
182 /* Runs dfs search over vertices of G, from NQ vertices in queue QS.
183 The vertices in postorder are stored into QT. If FORWARD is false,
184 backward dfs is run. If SUBGRAPH is not NULL, it specifies the
185 subgraph of G to run DFS on. Returns the number of the components
186 of the graph (number of the restarts of DFS). */
189 graphds_dfs (struct graph
*g
, int *qs
, int nq
, vec
<int> *qt
,
190 bool forward
, bitmap subgraph
)
192 int i
, tick
= 0, v
, comp
= 0, top
;
193 struct graph_edge
*e
;
194 struct graph_edge
**stack
= XNEWVEC (struct graph_edge
*, g
->n_vertices
);
200 EXECUTE_IF_SET_IN_BITMAP (subgraph
, 0, av
, bi
)
202 g
->vertices
[av
].component
= -1;
203 g
->vertices
[av
].post
= -1;
208 for (i
= 0; i
< g
->n_vertices
; i
++)
210 g
->vertices
[i
].component
= -1;
211 g
->vertices
[i
].post
= -1;
215 for (i
= 0; i
< nq
; i
++)
218 if (g
->vertices
[v
].post
!= -1)
221 g
->vertices
[v
].component
= comp
++;
222 e
= dfs_fst_edge (g
, v
, forward
, subgraph
);
229 if (g
->vertices
[dfs_edge_dest (e
, forward
)].component
232 e
= dfs_next_edge (e
, forward
, subgraph
);
239 g
->vertices
[v
].post
= tick
++;
245 v
= dfs_edge_src (e
, forward
);
246 e
= dfs_next_edge (e
, forward
, subgraph
);
251 v
= dfs_edge_dest (e
, forward
);
252 e
= dfs_fst_edge (g
, v
, forward
, subgraph
);
253 g
->vertices
[v
].component
= comp
- 1;
262 /* Determines the strongly connected components of G, using the algorithm of
263 Tarjan -- first determine the postorder dfs numbering in reversed graph,
264 then run the dfs on the original graph in the order given by decreasing
265 numbers assigned by the previous pass. If SUBGRAPH is not NULL, it
266 specifies the subgraph of G whose strongly connected components we want
269 After running this function, v->component is the number of the strongly
270 connected component for each vertex of G. Returns the number of the
274 graphds_scc (struct graph
*g
, bitmap subgraph
)
276 int *queue
= XNEWVEC (int, g
->n_vertices
);
277 vec
<int> postorder
= vec
<int>();
285 EXECUTE_IF_SET_IN_BITMAP (subgraph
, 0, v
, bi
)
292 for (i
= 0; i
< g
->n_vertices
; i
++)
297 graphds_dfs (g
, queue
, nq
, &postorder
, false, subgraph
);
298 gcc_assert (postorder
.length () == (unsigned) nq
);
300 for (i
= 0; i
< nq
; i
++)
301 queue
[i
] = postorder
[nq
- i
- 1];
302 comp
= graphds_dfs (g
, queue
, nq
, NULL
, true, subgraph
);
305 postorder
.release ();
310 /* Runs CALLBACK for all edges in G. */
313 for_each_edge (struct graph
*g
, graphds_edge_callback callback
)
315 struct graph_edge
*e
;
318 for (i
= 0; i
< g
->n_vertices
; i
++)
319 for (e
= g
->vertices
[i
].succ
; e
; e
= e
->succ_next
)
323 /* Releases the memory occupied by G. */
326 free_graph (struct graph
*g
)
328 struct graph_edge
*e
, *n
;
332 for (i
= 0; i
< g
->n_vertices
; i
++)
335 for (e
= v
->succ
; e
; e
= n
)
345 /* Returns the nearest common ancestor of X and Y in tree whose parent
346 links are given by PARENT. MARKS is the array used to mark the
347 vertices of the tree, and MARK is the number currently used as a mark. */
350 tree_nca (int x
, int y
, int *parent
, int *marks
, int mark
)
352 if (x
== -1 || x
== y
)
355 /* We climb with X and Y up the tree, marking the visited nodes. When
356 we first arrive to a marked node, it is the common ancestor. */
365 if (marks
[x
] == mark
)
372 if (marks
[y
] == mark
)
377 /* If we reached the root with one of the vertices, continue
378 with the other one till we reach the marked part of the
382 for (y
= parent
[y
]; marks
[y
] != mark
; y
= parent
[y
])
389 for (x
= parent
[x
]; marks
[x
] != mark
; x
= parent
[x
])
396 /* Determines the dominance tree of G (stored in the PARENT, SON and BROTHER
397 arrays), where the entry node is ENTRY. */
400 graphds_domtree (struct graph
*g
, int entry
,
401 int *parent
, int *son
, int *brother
)
403 vec
<int> postorder
= vec
<int>();
404 int *marks
= XCNEWVEC (int, g
->n_vertices
);
405 int mark
= 1, i
, v
, idom
;
407 struct graph_edge
*e
;
409 /* We use a slight modification of the standard iterative algorithm, as
412 K. D. Cooper, T. J. Harvey and K. Kennedy: A Simple, Fast Dominance
415 sort vertices in reverse postorder
420 while (anything changes)
422 dom(v) = {v} union (intersection of dom(p) over all predecessors of v)
424 The sets dom(v) are represented by the parent links in the current version
425 of the dominance tree. */
427 for (i
= 0; i
< g
->n_vertices
; i
++)
433 graphds_dfs (g
, &entry
, 1, &postorder
, true, NULL
);
434 gcc_assert (postorder
.length () == (unsigned) g
->n_vertices
);
435 gcc_assert (postorder
[g
->n_vertices
- 1] == entry
);
441 for (i
= g
->n_vertices
- 2; i
>= 0; i
--)
445 for (e
= g
->vertices
[v
].pred
; e
; e
= e
->pred_next
)
448 && parent
[e
->src
] == -1)
451 idom
= tree_nca (idom
, e
->src
, parent
, marks
, mark
++);
454 if (idom
!= parent
[v
])
463 postorder
.release ();
465 for (i
= 0; i
< g
->n_vertices
; i
++)
468 brother
[i
] = son
[parent
[i
]];