graphds.c 10 KB

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