1 /* $Id: cf_idom.c,v 1.4 1994/06/24 10:20:17 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
6 /* C O N T R O L F L O W
12 #include "../share/types.h"
13 #include "../share/debug.h"
14 #include "../share/lset.h"
15 #include "../share/alloc.h"
19 /* The algorithm for finding dominators in a flowgraph
20 * that is used here, was developed by Thomas Lengauer
21 * and Robert E. Tarjan of Stanford University.
22 * The algorithm is described in their article:
23 * A Fast Algorithm for Finding Dominators
25 * which was published in:
26 * ACM Transactions on Programming Languages and Systems,
27 * Vol. 1, No. 1, July 1979, Pages 121-141.
31 #define UNREACHABLE(b) (b->B_SEMI == (short) 0)
34 bblock_p *vertex; /* dynamically allocated array */
40 /* Depth First Search */
46 vertex[dfs_nr] = v->B_LABEL = v;
47 v->B_ANCESTOR = (bblock_p) 0;
48 for (i = Lfirst(v->b_succ); i != (Lindex) 0; i = Lnext(i,v->b_succ)) {
49 w = (bblock_p) Lelem(i);
62 if (v->B_ANCESTOR->B_ANCESTOR != (bblock_p) 0) {
63 compress(v->B_ANCESTOR);
64 if (v->B_ANCESTOR->B_LABEL->B_SEMI < v->B_LABEL->B_SEMI) {
65 v->B_LABEL = v->B_ANCESTOR->B_LABEL;
67 v->B_ANCESTOR = v->B_ANCESTOR->B_ANCESTOR;
73 STATIC bblock_p eval(v)
76 if (v->B_ANCESTOR == (bblock_p) 0) {
86 STATIC linkblocks(v,w)
98 /* Compute the immediate dominator of every basic
99 * block in the control flow graph rooted by r.
107 vertex = (bblock_p *) newmap(n);
108 /* allocate vertex (dynamic array). All remaining
109 * initializations were done by the routine
110 * nextblock of get.c.
113 for (i = dfs_nr; i > 1; i--) {
115 for (ind = Lfirst(w->b_pred); ind != (Lindex) 0;
116 ind = Lnext(ind,w->b_pred)) {
117 v = (bblock_p) Lelem(ind);
118 if (UNREACHABLE(v)) continue;
120 if (u->B_SEMI < w->B_SEMI) {
121 w->B_SEMI = u->B_SEMI;
124 Ladd(w,&(vertex[w->B_SEMI]->B_BUCKET));
125 linkblocks(w->B_PARENT,w);
126 for (ind = Lfirst(w->B_PARENT->B_BUCKET); ind != (Lindex) 0;
128 next = Lnext(ind,w->B_PARENT->B_BUCKET);
129 v = (bblock_p) Lelem(ind);
130 Lremove(v,&w->B_PARENT->B_BUCKET);
132 v->b_idom = (u->B_SEMI < v->B_SEMI ? u : w->B_PARENT);
135 for (i = 2; i <= dfs_nr; i++) {
137 if (w->b_idom != vertex[w->B_SEMI]) {
138 w->b_idom = w->b_idom->b_idom;
141 r->b_idom = (bblock_p) 0;
142 oldmap(vertex,n); /* release memory for dynamic array vertex */