Update change log
[platform/upstream/gcc48.git] / gcc / graphds.c
1 /* Graph representation and manipulation functions.
2    Copyright (C) 2007-2013 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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
9 version.
10
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
14 for more details.
15
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/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "obstack.h"
24 #include "bitmap.h"
25 #include "vec.h"
26 #include "graphds.h"
27
28 /* Dumps graph G into F.  */
29
30 void
31 dump_graph (FILE *f, struct graph *g)
32 {
33   int i;
34   struct graph_edge *e;
35
36   for (i = 0; i < g->n_vertices; i++)
37     {
38       if (!g->vertices[i].pred
39           && !g->vertices[i].succ)
40         continue;
41
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);
45       fprintf (f, "\n");
46
47       fprintf (f, "\t->");
48       for (e = g->vertices[i].succ; e; e = e->succ_next)
49         fprintf (f, " %d", e->dest);
50       fprintf (f, "\n");
51     }
52 }
53
54 /* Creates a new graph with N_VERTICES vertices.  */
55
56 struct graph *
57 new_graph (int n_vertices)
58 {
59   struct graph *g = XNEW (struct graph);
60
61   g->n_vertices = n_vertices;
62   g->vertices = XCNEWVEC (struct vertex, n_vertices);
63
64   return g;
65 }
66
67 /* Adds an edge from F to T to graph G.  The new edge is returned.  */
68
69 struct graph_edge *
70 add_edge (struct graph *g, int f, int t)
71 {
72   struct graph_edge *e = XNEW (struct graph_edge);
73   struct vertex *vf = &g->vertices[f], *vt = &g->vertices[t];
74
75
76   e->src = f;
77   e->dest = t;
78
79   e->pred_next = vt->pred;
80   vt->pred = e;
81
82   e->succ_next = vf->succ;
83   vf->succ = e;
84
85   return e;
86 }
87
88 /* Moves all the edges incident with U to V.  */
89
90 void
91 identify_vertices (struct graph *g, int v, int u)
92 {
93   struct vertex *vv = &g->vertices[v];
94   struct vertex *uu = &g->vertices[u];
95   struct graph_edge *e, *next;
96
97   for (e = uu->succ; e; e = next)
98     {
99       next = e->succ_next;
100
101       e->src = v;
102       e->succ_next = vv->succ;
103       vv->succ = e;
104     }
105   uu->succ = NULL;
106
107   for (e = uu->pred; e; e = next)
108     {
109       next = e->pred_next;
110
111       e->dest = v;
112       e->pred_next = vv->pred;
113       vv->pred = e;
114     }
115   uu->pred = NULL;
116 }
117
118 /* Helper function for graphds_dfs.  Returns the source vertex of E, in the
119    direction given by FORWARD.  */
120
121 static inline int
122 dfs_edge_src (struct graph_edge *e, bool forward)
123 {
124   return forward ? e->src : e->dest;
125 }
126
127 /* Helper function for graphds_dfs.  Returns the destination vertex of E, in
128    the direction given by FORWARD.  */
129
130 static inline int
131 dfs_edge_dest (struct graph_edge *e, bool forward)
132 {
133   return forward ? e->dest : e->src;
134 }
135
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.  */
138
139 static inline struct graph_edge *
140 foll_in_subgraph (struct graph_edge *e, bool forward, bitmap subgraph)
141 {
142   int d;
143
144   if (!subgraph)
145     return e;
146
147   while (e)
148     {
149       d = dfs_edge_dest (e, forward);
150       if (bitmap_bit_p (subgraph, d))
151         return e;
152
153       e = forward ? e->succ_next : e->pred_next;
154     }
155
156   return e;
157 }
158
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.  */
161
162 static inline struct graph_edge *
163 dfs_fst_edge (struct graph *g, int v, bool forward, bitmap subgraph)
164 {
165   struct graph_edge *e;
166
167   e = (forward ? g->vertices[v].succ : g->vertices[v].pred);
168   return foll_in_subgraph (e, forward, subgraph);
169 }
170
171 /* Helper function for graphds_dfs.  Returns the next edge after E, in the
172    graph direction given by FORWARD, that belongs to SUBGRAPH.  */
173
174 static inline struct graph_edge *
175 dfs_next_edge (struct graph_edge *e, bool forward, bitmap subgraph)
176 {
177   return foll_in_subgraph (forward ? e->succ_next : e->pred_next,
178                            forward, subgraph);
179 }
180
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).  */
186
187 int
188 graphds_dfs (struct graph *g, int *qs, int nq, vec<int> *qt,
189              bool forward, bitmap subgraph)
190 {
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);
194   bitmap_iterator bi;
195   unsigned av;
196
197   if (subgraph)
198     {
199       EXECUTE_IF_SET_IN_BITMAP (subgraph, 0, av, bi)
200         {
201           g->vertices[av].component = -1;
202           g->vertices[av].post = -1;
203         }
204     }
205   else
206     {
207       for (i = 0; i < g->n_vertices; i++)
208         {
209           g->vertices[i].component = -1;
210           g->vertices[i].post = -1;
211         }
212     }
213
214   for (i = 0; i < nq; i++)
215     {
216       v = qs[i];
217       if (g->vertices[v].post != -1)
218         continue;
219
220       g->vertices[v].component = comp++;
221       e = dfs_fst_edge (g, v, forward, subgraph);
222       top = 0;
223
224       while (1)
225         {
226           while (e)
227             {
228               if (g->vertices[dfs_edge_dest (e, forward)].component
229                   == -1)
230                 break;
231               e = dfs_next_edge (e, forward, subgraph);
232             }
233
234           if (!e)
235             {
236               if (qt)
237                 qt->safe_push (v);
238               g->vertices[v].post = tick++;
239
240               if (!top)
241                 break;
242
243               e = stack[--top];
244               v = dfs_edge_src (e, forward);
245               e = dfs_next_edge (e, forward, subgraph);
246               continue;
247             }
248
249           stack[top++] = e;
250           v = dfs_edge_dest (e, forward);
251           e = dfs_fst_edge (g, v, forward, subgraph);
252           g->vertices[v].component = comp - 1;
253         }
254     }
255
256   free (stack);
257
258   return comp;
259 }
260
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
266    to determine.
267
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
270    sccs of G.  */
271
272 int
273 graphds_scc (struct graph *g, bitmap subgraph)
274 {
275   int *queue = XNEWVEC (int, g->n_vertices);
276   vec<int> postorder = vNULL;
277   int nq, i, comp;
278   unsigned v;
279   bitmap_iterator bi;
280
281   if (subgraph)
282     {
283       nq = 0;
284       EXECUTE_IF_SET_IN_BITMAP (subgraph, 0, v, bi)
285         {
286           queue[nq++] = v;
287         }
288     }
289   else
290     {
291       for (i = 0; i < g->n_vertices; i++)
292         queue[i] = i;
293       nq = g->n_vertices;
294     }
295
296   graphds_dfs (g, queue, nq, &postorder, false, subgraph);
297   gcc_assert (postorder.length () == (unsigned) nq);
298
299   for (i = 0; i < nq; i++)
300     queue[i] = postorder[nq - i - 1];
301   comp = graphds_dfs (g, queue, nq, NULL, true, subgraph);
302
303   free (queue);
304   postorder.release ();
305
306   return comp;
307 }
308
309 /* Runs CALLBACK for all edges in G.  */
310
311 void
312 for_each_edge (struct graph *g, graphds_edge_callback callback)
313 {
314   struct graph_edge *e;
315   int i;
316
317   for (i = 0; i < g->n_vertices; i++)
318     for (e = g->vertices[i].succ; e; e = e->succ_next)
319       callback (g, e);
320 }
321
322 /* Releases the memory occupied by G.  */
323
324 void
325 free_graph (struct graph *g)
326 {
327   struct graph_edge *e, *n;
328   struct vertex *v;
329   int i;
330
331   for (i = 0; i < g->n_vertices; i++)
332     {
333       v = &g->vertices[i];
334       for (e = v->succ; e; e = n)
335         {
336           n = e->succ_next;
337           free (e);
338         }
339     }
340   free (g->vertices);
341   free (g);
342 }
343
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.  */
347
348 static int
349 tree_nca (int x, int y, int *parent, int *marks, int mark)
350 {
351   if (x == -1 || x == y)
352     return y;
353
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.  */
356   marks[x] = mark;
357   marks[y] = mark;
358
359   while (1)
360     {
361       x = parent[x];
362       if (x == -1)
363         break;
364       if (marks[x] == mark)
365         return x;
366       marks[x] = mark;
367
368       y = parent[y];
369       if (y == -1)
370         break;
371       if (marks[y] == mark)
372         return y;
373       marks[y] = mark;
374     }
375
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
378      tree.  */
379   if (x == -1)
380     {
381       for (y = parent[y]; marks[y] != mark; y = parent[y])
382         continue;
383
384       return y;
385     }
386   else
387     {
388       for (x = parent[x]; marks[x] != mark; x = parent[x])
389         continue;
390
391       return x;
392     }
393 }
394
395 /* Determines the dominance tree of G (stored in the PARENT, SON and BROTHER
396    arrays), where the entry node is ENTRY.  */
397
398 void
399 graphds_domtree (struct graph *g, int entry,
400                  int *parent, int *son, int *brother)
401 {
402   vec<int> postorder = vNULL;
403   int *marks = XCNEWVEC (int, g->n_vertices);
404   int mark = 1, i, v, idom;
405   bool changed = true;
406   struct graph_edge *e;
407
408   /* We use a slight modification of the standard iterative algorithm, as
409      described in
410
411      K. D. Cooper, T. J. Harvey and K. Kennedy: A Simple, Fast Dominance
412         Algorithm
413
414      sort vertices in reverse postorder
415      foreach v
416        dom(v) = everything
417      dom(entry) = entry;
418
419      while (anything changes)
420        foreach v
421          dom(v) = {v} union (intersection of dom(p) over all predecessors of v)
422
423      The sets dom(v) are represented by the parent links in the current version
424      of the dominance tree.  */
425
426   for (i = 0; i < g->n_vertices; i++)
427     {
428       parent[i] = -1;
429       son[i] = -1;
430       brother[i] = -1;
431     }
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);
435
436   while (changed)
437     {
438       changed = false;
439
440       for (i = g->n_vertices - 2; i >= 0; i--)
441         {
442           v = postorder[i];
443           idom = -1;
444           for (e = g->vertices[v].pred; e; e = e->pred_next)
445             {
446               if (e->src != entry
447                   && parent[e->src] == -1)
448                 continue;
449
450               idom = tree_nca (idom, e->src, parent, marks, mark++);
451             }
452
453           if (idom != parent[v])
454             {
455               parent[v] = idom;
456               changed = true;
457             }
458         }
459     }
460
461   free (marks);
462   postorder.release ();
463
464   for (i = 0; i < g->n_vertices; i++)
465     if (parent[i] != -1)
466       {
467         brother[i] = son[parent[i]];
468         son[parent[i]] = i;
469       }
470 }