187419Sdes/* Graph representation and manipulation functions.
287419Sdes   Copyright (C) 2007
387419Sdes   Free Software Foundation, Inc.
487419Sdes
587419SdesThis file is part of GCC.
687419Sdes
787419SdesGCC is free software; you can redistribute it and/or modify it under
8110608Sdesthe terms of the GNU General Public License as published by the Free
987419SdesSoftware Foundation; either version 3, or (at your option) any later
1087419Sdesversion.
11170510Syar
1287423SdesGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13110608SdesWARRANTY; without even the implied warranty of MERCHANTABILITY or
14110608SdesFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15110608Sdesfor more details.
16110608Sdes
17110608SdesYou should have received a copy of the GNU General Public License
18110608Sdesalong with GCC; see the file COPYING3.  If not see
19<http://www.gnu.org/licenses/>.  */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "obstack.h"
25#include "bitmap.h"
26#include "vec.h"
27#include "vecprim.h"
28#include "graphds.h"
29
30/* Dumps graph G into F.  */
31
32void
33dump_graph (FILE *f, struct graph *g)
34{
35  int i;
36  struct graph_edge *e;
37
38  for (i = 0; i < g->n_vertices; i++)
39    {
40      if (!g->vertices[i].pred
41	  && !g->vertices[i].succ)
42	continue;
43
44      fprintf (f, "%d (%d)\t<-", i, g->vertices[i].component);
45      for (e = g->vertices[i].pred; e; e = e->pred_next)
46	fprintf (f, " %d", e->src);
47      fprintf (f, "\n");
48
49      fprintf (f, "\t->");
50      for (e = g->vertices[i].succ; e; e = e->succ_next)
51	fprintf (f, " %d", e->dest);
52      fprintf (f, "\n");
53    }
54}
55
56/* Creates a new graph with N_VERTICES vertices.  */
57
58struct graph *
59new_graph (int n_vertices)
60{
61  struct graph *g = XNEW (struct graph);
62
63  g->n_vertices = n_vertices;
64  g->vertices = XCNEWVEC (struct vertex, n_vertices);
65
66  return g;
67}
68
69/* Adds an edge from F to T to graph G.  The new edge is returned.  */
70
71struct graph_edge *
72add_edge (struct graph *g, int f, int t)
73{
74  struct graph_edge *e = XNEW (struct graph_edge);
75  struct vertex *vf = &g->vertices[f], *vt = &g->vertices[t];
76
77
78  e->src = f;
79  e->dest = t;
80
81  e->pred_next = vt->pred;
82  vt->pred = e;
83
84  e->succ_next = vf->succ;
85  vf->succ = e;
86
87  return e;
88}
89
90/* Moves all the edges incident with U to V.  */
91
92void
93identify_vertices (struct graph *g, int v, int u)
94{
95  struct vertex *vv = &g->vertices[v];
96  struct vertex *uu = &g->vertices[u];
97  struct graph_edge *e, *next;
98
99  for (e = uu->succ; e; e = next)
100    {
101      next = e->succ_next;
102
103      e->src = v;
104      e->succ_next = vv->succ;
105      vv->succ = e;
106    }
107  uu->succ = NULL;
108
109  for (e = uu->pred; e; e = next)
110    {
111      next = e->pred_next;
112
113      e->dest = v;
114      e->pred_next = vv->pred;
115      vv->pred = e;
116    }
117  uu->pred = NULL;
118}
119
120/* Helper function for graphds_dfs.  Returns the source vertex of E, in the
121   direction given by FORWARD.  */
122
123static inline int
124dfs_edge_src (struct graph_edge *e, bool forward)
125{
126  return forward ? e->src : e->dest;
127}
128
129/* Helper function for graphds_dfs.  Returns the destination vertex of E, in
130   the direction given by FORWARD.  */
131
132static inline int
133dfs_edge_dest (struct graph_edge *e, bool forward)
134{
135  return forward ? e->dest : e->src;
136}
137
138/* Helper function for graphds_dfs.  Returns the first edge after E (including
139   E), in the graph direction given by FORWARD, that belongs to SUBGRAPH.  */
140
141static inline struct graph_edge *
142foll_in_subgraph (struct graph_edge *e, bool forward, bitmap subgraph)
143{
144  int d;
145
146  if (!subgraph)
147    return e;
148
149  while (e)
150    {
151      d = dfs_edge_dest (e, forward);
152      if (bitmap_bit_p (subgraph, d))
153	return e;
154
155      e = forward ? e->succ_next : e->pred_next;
156    }
157
158  return e;
159}
160
161/* Helper function for graphds_dfs.  Select the first edge from V in G, in the
162   direction given by FORWARD, that belongs to SUBGRAPH.  */
163
164static inline struct graph_edge *
165dfs_fst_edge (struct graph *g, int v, bool forward, bitmap subgraph)
166{
167  struct graph_edge *e;
168
169  e = (forward ? g->vertices[v].succ : g->vertices[v].pred);
170  return foll_in_subgraph (e, forward, subgraph);
171}
172
173/* Helper function for graphds_dfs.  Returns the next edge after E, in the
174   graph direction given by FORWARD, that belongs to SUBGRAPH.  */
175
176static inline struct graph_edge *
177dfs_next_edge (struct graph_edge *e, bool forward, bitmap subgraph)
178{
179  return foll_in_subgraph (forward ? e->succ_next : e->pred_next,
180			   forward, subgraph);
181}
182
183/* Runs dfs search over vertices of G, from NQ vertices in queue QS.
184   The vertices in postorder are stored into QT.  If FORWARD is false,
185   backward dfs is run.  If SUBGRAPH is not NULL, it specifies the
186   subgraph of G to run DFS on.  Returns the number of the components
187   of the graph (number of the restarts of DFS).  */
188
189int
190graphds_dfs (struct graph *g, int *qs, int nq, VEC (int, heap) **qt,
191	     bool forward, bitmap subgraph)
192{
193  int i, tick = 0, v, comp = 0, top;
194  struct graph_edge *e;
195  struct graph_edge **stack = XNEWVEC (struct graph_edge *, g->n_vertices);
196  bitmap_iterator bi;
197  unsigned av;
198
199  if (subgraph)
200    {
201      EXECUTE_IF_SET_IN_BITMAP (subgraph, 0, av, bi)
202	{
203	  g->vertices[av].component = -1;
204	  g->vertices[av].post = -1;
205	}
206    }
207  else
208    {
209      for (i = 0; i < g->n_vertices; i++)
210	{
211	  g->vertices[i].component = -1;
212	  g->vertices[i].post = -1;
213	}
214    }
215
216  for (i = 0; i < nq; i++)
217    {
218      v = qs[i];
219      if (g->vertices[v].post != -1)
220	continue;
221
222      g->vertices[v].component = comp++;
223      e = dfs_fst_edge (g, v, forward, subgraph);
224      top = 0;
225
226      while (1)
227	{
228	  while (e)
229	    {
230	      if (g->vertices[dfs_edge_dest (e, forward)].component
231		  == -1)
232		break;
233	      e = dfs_next_edge (e, forward, subgraph);
234	    }
235
236	  if (!e)
237	    {
238	      if (qt)
239		VEC_safe_push (int, heap, *qt, v);
240	      g->vertices[v].post = tick++;
241
242	      if (!top)
243		break;
244
245	      e = stack[--top];
246	      v = dfs_edge_src (e, forward);
247	      e = dfs_next_edge (e, forward, subgraph);
248	      continue;
249	    }
250
251	  stack[top++] = e;
252	  v = dfs_edge_dest (e, forward);
253	  e = dfs_fst_edge (g, v, forward, subgraph);
254	  g->vertices[v].component = comp - 1;
255	}
256    }
257
258  free (stack);
259
260  return comp;
261}
262
263/* Determines the strongly connected components of G, using the algorithm of
264   Tarjan -- first determine the postorder dfs numbering in reversed graph,
265   then run the dfs on the original graph in the order given by decreasing
266   numbers assigned by the previous pass.  If SUBGRAPH is not NULL, it
267   specifies the subgraph of G whose strongly connected components we want
268   to determine.
269
270   After running this function, v->component is the number of the strongly
271   connected component for each vertex of G.  Returns the number of the
272   sccs of G.  */
273
274int
275graphds_scc (struct graph *g, bitmap subgraph)
276{
277  int *queue = XNEWVEC (int, g->n_vertices);
278  VEC (int, heap) *postorder = NULL;
279  int nq, i, comp;
280  unsigned v;
281  bitmap_iterator bi;
282
283  if (subgraph)
284    {
285      nq = 0;
286      EXECUTE_IF_SET_IN_BITMAP (subgraph, 0, v, bi)
287	{
288	  queue[nq++] = v;
289	}
290    }
291  else
292    {
293      for (i = 0; i < g->n_vertices; i++)
294	queue[i] = i;
295      nq = g->n_vertices;
296    }
297
298  graphds_dfs (g, queue, nq, &postorder, false, subgraph);
299  gcc_assert (VEC_length (int, postorder) == (unsigned) nq);
300
301  for (i = 0; i < nq; i++)
302    queue[i] = VEC_index (int, postorder, nq - i - 1);
303  comp = graphds_dfs (g, queue, nq, NULL, true, subgraph);
304
305  free (queue);
306  VEC_free (int, heap, postorder);
307
308  return comp;
309}
310
311/* Runs CALLBACK for all edges in G.  */
312
313void
314for_each_edge (struct graph *g, graphds_edge_callback callback)
315{
316  struct graph_edge *e;
317  int i;
318
319  for (i = 0; i < g->n_vertices; i++)
320    for (e = g->vertices[i].succ; e; e = e->succ_next)
321      callback (g, e);
322}
323
324/* Releases the memory occupied by G.  */
325
326void
327free_graph (struct graph *g)
328{
329  struct graph_edge *e, *n;
330  struct vertex *v;
331  int i;
332
333  for (i = 0; i < g->n_vertices; i++)
334    {
335      v = &g->vertices[i];
336      for (e = v->succ; e; e = n)
337	{
338	  n = e->succ_next;
339	  free (e);
340	}
341    }
342  free (g->vertices);
343  free (g);
344}
345
346/* Returns the nearest common ancestor of X and Y in tree whose parent
347   links are given by PARENT.  MARKS is the array used to mark the
348   vertices of the tree, and MARK is the number currently used as a mark.  */
349
350static int
351tree_nca (int x, int y, int *parent, int *marks, int mark)
352{
353  if (x == -1 || x == y)
354    return y;
355
356  /* We climb with X and Y up the tree, marking the visited nodes.  When
357     we first arrive to a marked node, it is the common ancestor.  */
358  marks[x] = mark;
359  marks[y] = mark;
360
361  while (1)
362    {
363      x = parent[x];
364      if (x == -1)
365	break;
366      if (marks[x] == mark)
367	return x;
368      marks[x] = mark;
369
370      y = parent[y];
371      if (y == -1)
372	break;
373      if (marks[y] == mark)
374	return y;
375      marks[y] = mark;
376    }
377
378  /* If we reached the root with one of the vertices, continue
379     with the other one till we reach the marked part of the
380     tree.  */
381  if (x == -1)
382    {
383      for (y = parent[y]; marks[y] != mark; y = parent[y])
384	continue;
385
386      return y;
387    }
388  else
389    {
390      for (x = parent[x]; marks[x] != mark; x = parent[x])
391	continue;
392
393      return x;
394    }
395}
396
397/* Determines the dominance tree of G (stored in the PARENT, SON and BROTHER
398   arrays), where the entry node is ENTRY.  */
399
400void
401graphds_domtree (struct graph *g, int entry,
402		 int *parent, int *son, int *brother)
403{
404  VEC (int, heap) *postorder = NULL;
405  int *marks = XCNEWVEC (int, g->n_vertices);
406  int mark = 1, i, v, idom;
407  bool changed = true;
408  struct graph_edge *e;
409
410  /* We use a slight modification of the standard iterative algorithm, as
411     described in
412
413     K. D. Cooper, T. J. Harvey and K. Kennedy: A Simple, Fast Dominance
414	Algorithm
415
416     sort vertices in reverse postorder
417     foreach v
418       dom(v) = everything
419     dom(entry) = entry;
420
421     while (anything changes)
422       foreach v
423         dom(v) = {v} union (intersection of dom(p) over all predecessors of v)
424
425     The sets dom(v) are represented by the parent links in the current version
426     of the dominance tree.  */
427
428  for (i = 0; i < g->n_vertices; i++)
429    {
430      parent[i] = -1;
431      son[i] = -1;
432      brother[i] = -1;
433    }
434  graphds_dfs (g, &entry, 1, &postorder, true, NULL);
435  gcc_assert (VEC_length (int, postorder) == (unsigned) g->n_vertices);
436  gcc_assert (VEC_index (int, postorder, g->n_vertices - 1) == entry);
437
438  while (changed)
439    {
440      changed = false;
441
442      for (i = g->n_vertices - 2; i >= 0; i--)
443	{
444	  v = VEC_index (int, postorder, i);
445	  idom = -1;
446	  for (e = g->vertices[v].pred; e; e = e->pred_next)
447	    {
448	      if (e->src != entry
449		  && parent[e->src] == -1)
450		continue;
451
452	      idom = tree_nca (idom, e->src, parent, marks, mark++);
453	    }
454
455	  if (idom != parent[v])
456	    {
457	      parent[v] = idom;
458	      changed = true;
459	    }
460	}
461    }
462
463  free (marks);
464  VEC_free (int, heap, postorder);
465
466  for (i = 0; i < g->n_vertices; i++)
467    if (parent[i] != -1)
468      {
469	brother[i] = son[parent[i]];
470	son[parent[i]] = i;
471      }
472}
473