CACAO
dominators.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/dominators.cpp - dominators and dominance frontier
2 
3  Copyright (C) 2005-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include "config.h"
29 # include <cassert>
30 
31 #include "mm/dumpmemory.hpp"
32 
33 #include "toolbox/bitvector.hpp"
34 
35 #include "vm/jit/jit.hpp"
36 
39 
40 #include "vm/jit/show.hpp"
41 
42 #if !defined(NDEBUG)
43 /* # define DOM_DEBUG_CHECK */
44 # define DOM_DEBUG_VERBOSE
45 #endif
46 
47 #ifdef DOM_DEBUG_CHECK
48 # define _DOM_CHECK_BOUNDS(i,l,h) assert( ((i) >= (l)) && ((i) < (h)));
49 # define _DOM_ASSERT(a) assert((a));
50 #else
51 # define _DOM_CHECK_BOUNDS(i,l,h)
52 # define _DOM_ASSERT(a)
53 #endif
54 
55 /* function prototypes */
56 void dom_Dominators_init(dominatordata *dd, int basicblockcount);
57 #ifdef DOM_DEBUG_CHECK
58 int dom_AncestorWithLowestSemi(dominatordata *dd, int v, int basicblockcount);
59 void dom_Link(dominatordata *dd, int p, int n, int basicblockcount);
60 void dom_DFS(graphdata *gd, dominatordata *dd, int p, int n, int *N,
61  int basicblockcount);
62 #else
64 void dom_Link(dominatordata *dd, int p, int n);
65 void dom_DFS(graphdata *gd, dominatordata *dd, int p, int n, int *N);
66 #endif
67 
68 /*************************************
69 Calculate Dominators
70 *************************************/
71 dominatordata *compute_Dominators(graphdata *gd, int basicblockcount) {
72  int i,j,n,N,p,s,s_,v,y;
73  graphiterator iter;
74  dominatordata *dd;
75 
77 
78  dom_Dominators_init(dd, basicblockcount);
79 
80  N=0;
81 
82  /* 1 ist the root node of the method */
83  /* 0 is the artificial parent, where locals are set to their parameters */
84  dom_DFS(gd, dd, -1, 0, &N
85 #ifdef DOM_DEBUG_CHECK
86  ,basicblockcount
87 #endif
88  );
89 
90  for(i = N-1; i > 0; i--) {
91  _DOM_CHECK_BOUNDS(i, 0, basicblockcount);
92  n = dd->vertex[i];
93  _DOM_CHECK_BOUNDS(n, 0, basicblockcount);
94  p = dd->parent[n];
95  s = p;
96  j = graph_get_first_predecessor(gd, n, &iter);
97  for (; j != -1; j = graph_get_next(&iter)) {
98  _DOM_CHECK_BOUNDS(j, 0, basicblockcount);
99  if (dd->dfnum[j] <= dd->dfnum[n])
100  s_ = j;
101  else
102  s_ = dd->semi[dom_AncestorWithLowestSemi(dd, j
103 #ifdef DOM_DEBUG_CHECK
104  ,basicblockcount
105 #endif
106  )];
107  _DOM_CHECK_BOUNDS(s_, 0, basicblockcount);
108  _DOM_CHECK_BOUNDS(s, 0, basicblockcount);
109  if (dd->dfnum[s_] < dd->dfnum[s])
110  s = s_;
111  }
112  dd->semi[n] = s;
113  _DOM_CHECK_BOUNDS(dd->num_bucket[s], 0, basicblockcount);
114  dd->bucket[s][dd->num_bucket[s]] = n;
115  dd->num_bucket[s]++;
116  dom_Link(dd, p, n
117 #ifdef DOM_DEBUG_CHECK
118  , basicblockcount
119 #endif
120  );
121  _DOM_CHECK_BOUNDS(p, 0, basicblockcount);
122  for(j = 0; j < dd->num_bucket[p]; j++) {
123  _DOM_CHECK_BOUNDS(j, 0, basicblockcount);
124  v = dd->bucket[p][j];
126 #ifdef DOM_DEBUG_CHECK
127  , basicblockcount
128 #endif
129  );
130  _DOM_CHECK_BOUNDS(y, 0, basicblockcount);
131  _DOM_CHECK_BOUNDS(v, 0, basicblockcount);
132  if (dd->semi[y] == dd->semi[v])
133  dd->idom[v] = p;
134  else
135  dd->samedom[v] = y;
136  }
137  dd->num_bucket[p] = 0;
138  }
139  for(i = 1; i < N; i++) {
140  n = dd->vertex[i];
141  _DOM_CHECK_BOUNDS(n, 0, basicblockcount);
142  if (dd->samedom[n] != -1) {
143  _DOM_CHECK_BOUNDS(dd->samedom[n], 0, basicblockcount);
144  dd->idom[n] = dd->idom[dd->samedom[n]];
145  }
146  }
147  return dd;
148 }
149 
150 /********************************************
151 compute Dominace Frontier
152 ********************************************/
153 void computeDF(graphdata *gd, dominatordata *dd, int basicblockcount, int n) {
154  int c,i,j;
155  bool *_S;
156  graphiterator iter;
157 
158  _S = (bool*) DumpMemory::allocate(sizeof(bool) * basicblockcount);
159  for(i = 0; i < basicblockcount; i++)
160  _S[i] = false;
161  i = graph_get_first_successor(gd, n, &iter);
162  for (; i != -1; i = graph_get_next(&iter)) {
163  _DOM_CHECK_BOUNDS(i, 0, basicblockcount);
164  if (dd->idom[i] != n)
165  _S[i] = true;
166  }
167  for(c=0; c < basicblockcount; c++) {
168  if (dd->idom[c] == n) {
169  computeDF(gd, dd, basicblockcount, c);
170  for(j=0; j < dd->num_DF[c]; j++) {
171  _DOM_CHECK_BOUNDS(dd->DF[c][j], 0, basicblockcount);
172  if (n != dd->idom[dd->DF[c][j]])
173  /* n does not dominate DF[c][j] -> traverse idom list? */
174  _S[dd->DF[c][j]] = true;
175  }
176  }
177  }
178  for(i = 0; i < basicblockcount; i++)
179  if (_S[i]) {
180  _DOM_CHECK_BOUNDS(dd->num_DF[n], 0, basicblockcount);
181  dd->DF[n][dd->num_DF[n]] = i;
182  dd->num_DF[n]++;
183  }
184 }
185 
186 
187 void dom_Dominators_init(dominatordata *dd, int basicblockcount) {
188  int i;
189 
190  dd->dfnum = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
191  dd->vertex = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
192  dd->parent = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
193  dd->semi = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
194  dd->ancestor = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
195  dd->idom = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
196  dd->samedom = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
197  dd->bucket = (int**) DumpMemory::allocate(sizeof(int*) * basicblockcount);
198  dd->num_bucket = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
199  dd->DF = (int**) DumpMemory::allocate(sizeof(int*) * basicblockcount);
200  dd->num_DF = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
201  dd->best = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
202  for (i=0; i < basicblockcount; i++) {
203  dd->dfnum[i] = -1;
204  dd->semi[i] = dd->ancestor[i] = dd->idom[i] = dd->samedom[i] = -1;
205  dd->num_bucket[i] = 0;
206  dd->bucket[i] = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
207  dd->num_DF[i] = 0;
208  dd->DF[i] = (int*) DumpMemory::allocate(sizeof(int) * basicblockcount);
209  }
210 }
211 
212 /**************************************
213 Create Depth First Spanning Tree
214 **************************************/
215 #ifdef DOM_DEBUG_CHECK
216 void dom_DFS(graphdata *gd, dominatordata *dd, int p, int n, int *N,
217  int basicblockcount) {
218 #else
219 void dom_DFS(graphdata *gd, dominatordata *dd, int p, int n, int *N) {
220 #endif
221  int i;
222  graphiterator iter;
223 
224  _DOM_CHECK_BOUNDS(n,0,basicblockcount);
225  if (dd->dfnum[n] == -1) { /* not visited till now? */
226  dd->dfnum[n] = *N;
227  _DOM_CHECK_BOUNDS(*N,0,basicblockcount);
228  dd->vertex[*N] = n;
229  dd->parent[n] = p;
230  (*N)++;
231  i = graph_get_first_successor(gd, n, &iter);
232  for (; i != -1; i = graph_get_next(&iter)) {
233  dom_DFS(gd, dd, n, i, N
234 #ifdef DOM_DEBUG_CHECK
235  , basicblockcount
236 #endif
237  );
238  }
239  }
240 }
241 
242 #ifdef DOM_DEBUG_CHECK
243 int dom_AncestorWithLowestSemi(dominatordata *dd, int v, int basicblockcount) {
244 #else
246 #endif
247  int a,b;
248 
249  _DOM_CHECK_BOUNDS(v, 0, basicblockcount);
250  a = dd->ancestor[v];
251  _DOM_CHECK_BOUNDS(a,0,basicblockcount);
252  if (dd->ancestor[a] != -1) {
254 #ifdef DOM_DEBUG_CHECK
255  , basicblockcount
256 #endif
257  );
258  dd->ancestor[v] = dd->ancestor[a];
259  _DOM_CHECK_BOUNDS(b,0,basicblockcount);
260  _DOM_CHECK_BOUNDS(dd->best[v],0,basicblockcount);
261  _DOM_CHECK_BOUNDS(dd->semi[dd->best[v]],0,basicblockcount);
262  if (dd->dfnum[dd->semi[b]] < dd->dfnum[dd->semi[dd->best[v]]])
263  dd->best[v] = b;
264  }
265  return dd->best[v];
266 }
267 
268 #ifdef DOM_DEBUG_CHECK
269 void dom_Link(dominatordata *dd, int p, int n, int basicblockcount) {
270 #else
271 void dom_Link(dominatordata *dd, int p, int n) {
272 #endif
273  _DOM_CHECK_BOUNDS(n,0,basicblockcount);
274  dd->ancestor[n] = p;
275  dd->best[n] = n;
276 }
277 
278 /*********************************************************/
279 
281 
284  int dfnum;
292  unsigned bucketcount;
293 };
294 
296 
301  unsigned df_counter;
302 };
303 
306  basicblock *itb;
307  basicblock_info *iti;
308 
310 
311  di->jd = jd;
312 
315 
316  for (iti = di->basicblocks; iti != di->basicblocks + jd->basicblockcount; ++iti) {
317  iti->dfnum = -1;
319  iti->bucketcount = 0;
320  }
321 
322  for (itb = jd->basicblocks; itb; itb = itb->next) {
323  di->basicblocks[itb->nr].bb = itb;
324  }
325 
328 
329  di->df_counter = 0;
330 
331  return di;
332 }
333 
335  return di->basicblocks + bb->nr;
336 }
337 
340 ) {
341  basicblock **it;
342 
343  if (node->dfnum == -1) {
344 
345  node->dfnum = di->df_counter;
346  node->parent = parent;
347  di->df_map[di->df_counter] = node;
348  di->df_counter += 1;
349 
350  for (it = node->bb->successors; it != node->bb->successors + node->bb->successorcount; ++it) {
352  di, node,
354  );
355  }
356  }
357 }
358 
360  node->ancestor = parent;
361  node->best = node;
362 }
363 
366 ) {
367  basicblock_info *a, *b;
368 
369  a = node->ancestor;
370 
371  if (a->ancestor != NULL) {
373  node->ancestor = a->ancestor;
374  if (b->semi->dfnum < node->best->semi->dfnum) {
375  node->best = b;
376  }
377  }
378 
379  return node->best;
380 }
381 
383 
385  basicblock_info *node;
386  basicblock_info *semicand;
387  basicblock_info *pred;
388  basicblock **itb;
389  basicblock_info **itii;
390  basicblock_info *v, *y;
391  int i;
392 
393  di = dominator_tree_init(jd);
394 
396 
397  for (i = di->df_counter - 1; i >= 1; --i) {
398  node = di->df_map[i];
399 
400  node->semi = node->parent;
401 
402  for (
403  itb = node->bb->predecessors;
404  itb != node->bb->predecessors + node->bb->predecessorcount;
405  ++itb
406  ) {
407 
408  pred = dominator_tree_get_basicblock(di, *itb);
409 
410  if (pred->dfnum <= node->dfnum) {
411  semicand = pred;
412  } else {
413  semicand = dominator_tree_ancestor_with_lowest_semi(di, pred)->semi;
414  }
415 
416  if (semicand->dfnum < node->semi->dfnum) {
417  node->semi = semicand;
418  }
419  }
420 
421  node->semi->bucket[node->semi->bucketcount] = node;
422  node->semi->bucketcount += 1;
423 
424  dominator_tree_link(di, node->parent, node);
425 
426  for (itii = node->parent->bucket; itii != node->parent->bucket + node->parent->bucketcount; ++itii) {
427  v = *itii;
429  if (y->semi == v->semi) {
430  v->idom = node->parent;
431  } else {
432  v->samedom = y;
433  }
434  }
435 
436  node->parent->bucketcount = 0;
437  }
438 
439  for (i = 1; i < di->df_counter; ++i) {
440  node = di->df_map[i];
441  if (node->samedom) {
442  node->idom = node->samedom->idom;
443  }
444 
445  node->bb->idom = node->idom->bb;
446  node->idom->bb->domsuccessorcount += 1;
447  }
448 }
449 
451  basicblock *bb;
452  /* basicblock number => current number of successors */
453  unsigned *numsuccessors;
454 
455  // Create new dump memory area.
456  DumpMemoryArea dma;
457 
458  /* Allocate memory for successors */
459 
460  for (bb = jd->basicblocks; bb; bb = bb->next) {
461  if (bb->domsuccessorcount > 0) {
462  bb->domsuccessors = (basicblock**) DumpMemory::allocate(sizeof(basicblock*) * bb->domsuccessorcount);
463  }
464  }
465 
466  /* Allocate memory for per basic block counter of successors */
467 
468  numsuccessors = (unsigned*) DumpMemory::allocate(sizeof(unsigned) * jd->basicblockcount);
469  MZERO(numsuccessors, unsigned, jd->basicblockcount);
470 
471  /* Link immediate dominators with successors */
472 
473  for (bb = jd->basicblocks; bb; bb = bb->next) {
474  if (bb->idom) {
475  bb->idom->domsuccessors[numsuccessors[bb->idom->nr]] = bb;
476  numsuccessors[bb->idom->nr] += 1;
477  }
478  }
479 }
480 
482  // Create new dump memory area.
483  DumpMemoryArea dma;
484 
486 
488 
489  return true;
490 }
491 
493 
497 };
498 
500 
503  unsigned count;
504 };
505 
508 
509  for (item = list->first; item; item = item->next) {
510  if (item->bb == bb) return;
511  }
512 
514  item->bb = bb;
515  item->next = list->first;
516  list->first = item;
517  list->count += 1;
518 }
519 
521 
525 };
526 
529 
530  dfi->jd = jd;
531 
534 
535  return dfi;
536 }
537 
539  x = x->idom;
540 
541  while (x != NULL) {
542  if (x == d) {
543  return true;
544  }
545  x = x->idom;
546  }
547 
548  return false;
549 }
550 
552  basicblock **it;
554  dominance_frontier_list s = { NULL, 0 };
555 
556  for (it = b->successors; it != b->successors + b->successorcount; ++it) {
557  if ((*it)->idom != b) {
559  }
560  }
561 
562  for (it = b->domsuccessors; it != b->domsuccessors + b->domsuccessorcount; ++it) {
564  for (itdf = dfi->map[(*it)->nr].first; itdf; itdf = itdf->next) {
565  if (! dominance_frontier_dominates(b, itdf->bb)) {
566  dominance_frontier_list_add(&s, itdf->bb);
567  }
568  }
569  }
570 
571  dfi->map[b->nr] = s;
572 }
573 
575  basicblock *bb;
577  basicblock **itout;
578 
579  for (bb = dfi->jd->basicblocks; bb; bb = bb->next) {
580  if (bb->nr < dfi->jd->basicblockcount) {
581  if (dfi->map[bb->nr].count > 0) {
582  bb->domfrontiercount = dfi->map[bb->nr].count;
583  itout = bb->domfrontier = (basicblock**) DumpMemory::allocate(sizeof(basicblock*) * bb->domfrontiercount);
584  for (itdf = dfi->map[bb->nr].first; itdf; itdf = itdf->next) {
585  *itout = itdf->bb;
586  itout += 1;
587  }
588  }
589  }
590  }
591 }
592 
594  // Create new dump memory area.
595  DumpMemoryArea dma;
596 
600 }
601 
603  graphdata *gd;
604  int i, j;
605  basicblock *bptr, **it;
606  dominatordata *dd;
607  int *itnr;
608  bool found;
609 
610  // Create new dump memory area.
611  DumpMemoryArea dma;
612 
613  fprintf(stderr, "%s/%s: \n", jd->m->clazz->name.begin(), jd->m->name.begin());
614  gd = graph_init(jd->basicblockcount);
615 
616  for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
617  for (it = bptr->successors; it != bptr->successors + bptr->successorcount; ++it) {
618  graph_add_edge(gd, bptr->nr, (*it)->nr);
619  }
620  }
621 
622  dd = compute_Dominators(gd, jd->basicblockcount);
623 
624  for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
625  if (bptr->state >= basicblock::REACHED) {
626  if (bptr->idom == NULL) {
627  if (!(dd->idom[bptr->nr] == -1)) {
628  printf("-- %d %d\n", dd->idom[bptr->nr], bptr->nr);
629  assert(0);
630  }
631  } else {
632  assert(dd->idom[bptr->nr] == bptr->idom->nr);
633  }
634  }
635  }
636 
637  computeDF(gd, dd, jd->basicblockcount, 0);
638 
639  for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
640  if (bptr->state >= basicblock::REACHED) {
641  assert(bptr->domfrontiercount == dd->num_DF[bptr->nr]);
642  for (itnr = dd->DF[bptr->nr]; itnr != dd->DF[bptr->nr] + dd->num_DF[bptr->nr]; ++itnr) {
643  found = false;
644  for (it = bptr->domfrontier; it != bptr->domfrontier + bptr->domfrontiercount; ++it) {
645  if ((*it)->nr == *itnr) {
646  found =true; break;
647  }
648  }
649  assert(found);
650  }
651  }
652  }
653 }
654 
655 
656 /*
657  * These are local overrides for various environment variables in Emacs.
658  * Please do not remove this and leave it at the end of the file, where
659  * Emacs will automagically detect them.
660  * ---------------------------------------------------------------------
661  * Local variables:
662  * mode: c++
663  * indent-tabs-mode: t
664  * c-basic-offset: 4
665  * tab-width: 4
666  * End:
667  */
void dom_DFS(graphdata *gd, dominatordata *dd, int p, int n, int *N)
Definition: dominators.cpp:219
Utf8String name
Definition: method.hpp:71
basicblock_info * idom
Definition: dominators.cpp:289
int graph_get_next(graphiterator *i)
Definition: graph.cpp:104
basicblock * basicblocks
Definition: jit.hpp:141
bool dominance_frontier_dominates(basicblock *d, basicblock *x)
Definition: dominators.cpp:538
Definition: jit.hpp:126
void dominator_tree_link_children(jitdata *jd)
Definition: dominators.cpp:450
#define N(name)
Definition: icmd.cpp:34
basicblock_info ** bucket
Definition: dominators.cpp:291
State state
Definition: jit.hpp:313
dominance_frontier_item * first
Definition: dominators.cpp:502
void dominator_tree_build_intern(jitdata *jd)
Definition: dominators.cpp:382
basicblock * next
Definition: jit.hpp:337
void computeDF(graphdata *gd, dominatordata *dd, int basicblockcount, int n)
Definition: dominators.cpp:153
basicblock_info * parent
Definition: dominators.cpp:285
s4 successorcount
Definition: jit.hpp:331
void graph_add_edge(graphdata *gd, int from, int to)
Definition: graph.cpp:131
void dominator_tree_link(dominator_tree_info *di, basicblock_info *parent, basicblock_info *node)
Definition: dominators.cpp:359
void dominator_tree_validate(jitdata *jd, dominatordata *_dd)
Definition: dominators.cpp:602
int dom_AncestorWithLowestSemi(dominatordata *dd, int v)
Definition: dominators.cpp:245
int graph_get_first_predecessor(graphdata *gd, int b_index, graphiterator *i)
Definition: graph.cpp:99
dominance_frontier_list * map
Definition: dominators.cpp:524
basicblock_info * samedom
Definition: dominators.cpp:290
basicblock_info * best
Definition: dominators.cpp:288
dominance_frontier_item * next
Definition: dominators.cpp:496
#define MZERO(ptr, type, num)
Definition: memory.hpp:105
void dom_Link(dominatordata *dd, int p, int n)
Definition: dominators.cpp:271
#define _DOM_CHECK_BOUNDS(i, l, h)
Definition: dominators.cpp:51
void dominance_frontier_list_add(dominance_frontier_list *list, basicblock *bb)
Definition: dominators.cpp:506
void dominance_frontier_store(dominance_frontier_info *dfi)
Definition: dominators.cpp:574
void dom_Dominators_init(dominatordata *dd, int basicblockcount)
Definition: dominators.cpp:187
Dump memory area.
Definition: dumpmemory.hpp:90
basicblock ** predecessors
Definition: jit.hpp:332
classinfo * clazz
Definition: method.hpp:80
s4 predecessorcount
Definition: jit.hpp:330
Utf8String name
Definition: class.hpp:91
basicblock_info ** df_map
Definition: dominators.cpp:300
MIIterator i
bool dominance_frontier_build(jitdata *jd)
Definition: dominators.cpp:593
basicblock_info * ancestor
Definition: dominators.cpp:287
bool dominator_tree_build(jitdata *jd)
Definition: dominators.cpp:481
int * num_bucket
Definition: dominators.hpp:42
basicblock * bb
Definition: dominators.cpp:283
basicblock_info * semi
Definition: dominators.cpp:286
unsigned bucketcount
Definition: dominators.cpp:292
byte_iterator begin() const
Definition: utf8.hpp:106
methodinfo * m
Definition: jit.hpp:127
static basicblock_info * dominator_tree_get_basicblock(dominator_tree_info *di, basicblock *bb)
Definition: dominators.cpp:334
static void * allocate(size_t size)
Definition: dumpmemory.hpp:251
s4 nr
Definition: jit.hpp:312
s4 basicblockcount
Definition: jit.hpp:144
dominatordata * compute_Dominators(graphdata *gd, int basicblockcount)
Definition: dominators.cpp:71
dominance_frontier_info * dominance_frontier_init(jitdata *jd)
Definition: dominators.cpp:527
basicblock_info * dominator_tree_ancestor_with_lowest_semi(dominator_tree_info *di, basicblock_info *node)
Definition: dominators.cpp:364
basicblock ** successors
Definition: jit.hpp:333
basicblock_info * basicblocks
Definition: dominators.cpp:299
static void dominator_tree_depth_first_search(dominator_tree_info *di, basicblock_info *parent, basicblock_info *node)
Definition: dominators.cpp:338
static dominator_tree_info * dominator_tree_init(jitdata *jd)
Definition: dominators.cpp:304
void dominance_frontier_for_block(dominance_frontier_info *dfi, basicblock *b)
Definition: dominators.cpp:551
#define printf(...)
Definition: ssa2.cpp:40
LoopTreeGraph * parent
graphdata * graph_init(int basicblockcount)
Definition: graph.cpp:60
int graph_get_first_successor(graphdata *gd, int b_index, graphiterator *i)
Definition: graph.cpp:94