1 /* Graph representation and manipulation functions. 2 Copyright (C) 2007 3 Free Software Foundation, Inc. 4 5 This file is part of GCC. 6 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 10 version. 11 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 15 for more details. 16 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/>. */ 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 32 void 33 dump_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 58 struct graph * 59 new_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 71 struct graph_edge * 72 add_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 92 void 93 identify_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 123 static inline int 124 dfs_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 132 static inline int 133 dfs_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 141 static inline struct graph_edge * 142 foll_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 164 static inline struct graph_edge * 165 dfs_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 176 static inline struct graph_edge * 177 dfs_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 189 int 190 graphds_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 274 int 275 graphds_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 313 void 314 for_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 326 void 327 free_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 350 static int 351 tree_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 400 void 401 graphds_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