|
|
1.1 root 1: #include <stdio.h>
2: #
3: /* depth-first search used to identify back edges, unreachable nodes;
4: each node v entered by back edge replaced by
5: LOOPVX ->ITERVX -> v,
6: so that back edges entering v now enter the ITERVX,
7: and other edges entering v now enter the LOOPVX.
8: Nodes are numbered according to depth-first search:
9: before numbering- ntobef[v] = i => node numbered v is i'th
10: node in order of first visit during the search;
11: after numbering- ntoaft[v] = i => node numbered v is i'th
12: node visited in order of last visit during the search.
13: Also, in this case after[i] = v.
14: */
15:
16: #include "def.h"
17: #include "2.def.h"
18:
19: #define MAXINS 3 /* spacing needed between numbers generated during depth first search */
20:
21: int *status;
22: int befcount, aftcount;
23: /* following defines used to mark back edges and nodes entered by back edges */
24: #define UNPROCESSED 0
25: #define STACKED 1
26: #define FINISHED 2
27: #define MARK(v) {REACH(v) = 1; } /* mark node v */
28: #define UNMARK(v) {REACH(v) = 0; }
29: #define MARKED(v) (REACH(v))
30: #define MKEDGE(e) {if (e >= -1) e = -(e+3); } /* mark edge e */
31: #define UNMKEDGE(e) {if (e < -1) e = -(e+3); }
32: #define BACKEDGE(e) (e < -1)
33:
34:
35: dfs(v) /* depth first search */
36: VERT v;
37: {
38: int i; VERT w;
39: accessnum = 0;
40: status = challoc(sizeof(*status) * nodenum);
41: for (w = 0; w < nodenum; ++w)
42: {
43: status[w] = UNPROCESSED;
44: UNMARK(w);
45: }
46: search(v);
47: chreach();
48: chfree(status, sizeof(*status) * nodenum);
49: addloop();
50: after = challoc(sizeof(*after) * accessnum);
51: for (i = 0; i < accessnum; ++i)
52: after[i] = UNDEFINED;
53: ntoaft = challoc(sizeof(*ntoaft) * nodenum);
54: ntobef = challoc(sizeof(*ntobef) * nodenum);
55: for (w = 0; w < nodenum; ++w)
56: ntobef[w] = ntoaft[w] = UNDEFINED;
57: befcount = 0;
58: aftcount = 0;
59: repsearch(v);
60: }
61:
62:
63: search(v)
64: /* using depth first search, mark back edges using MKEDGE, and nodes entered by back
65: edges using MARK */
66: VERT v;
67: {
68: VERT adj; int i;
69: status[v] = STACKED;
70: for(i = 0; i < ARCNUM(v); ++i)
71: {
72: adj = ARC(v,i);
73: if (!DEFINED(adj)) continue;
74: else if (status[adj] == UNPROCESSED)
75: search(adj);
76: else if (status[adj] == STACKED)
77: {
78: MARK(adj); /* mark adj as entered by back edge */
79: MKEDGE(ARC(v,i)); /* mark edge ARC(v,i) as being back edge */
80: }
81: }
82: status[v] = FINISHED;
83: ++accessnum;
84: }
85:
86: chreach() /* look for unreachable nodes */
87: {
88: VERT v;
89: LOGICAL unreach;
90: unreach = FALSE;
91: for (v = 0; v < nodenum; ++v)
92: if (status[v] == UNPROCESSED && NTYPE(v) != FMTVX
93: && NTYPE(v) != STOPVX && NTYPE(v) != RETVX)
94: {
95: unreach = TRUE;
96: if (debug)
97: fprintf(stderr,"node %d unreachable\n",v);
98: }
99: if (unreach)
100: error(": unreachable statements - ","will be ignored","");
101: }
102:
103:
104: addloop() /* add LOOPVX, ITERVX at nodes entered by back edges, and adjust edges */
105: {
106: VERT v, adj;
107: int j, oldnum;
108: for (v = 0, oldnum = nodenum; v < oldnum; ++v) /* insloop increases nodenum */
109: if (MARKED(v))
110: {
111: UNMARK(v); /* remove mark indicating v entered by back edge */
112: if (NTYPE(v) != ITERVX) /* DO loops already have ITERVX */
113: insloop(v); /* add LOOPVX, ITERVX since v entered by back edge*/
114: }
115: /* arcs which used to enter v now enter LOOPVX; must make back edges enter ITERVX */
116: for (v = 0; v < nodenum; ++v)
117: for (j = 0; j < ARCNUM(v); ++j)
118: {
119: if (BACKEDGE(ARC(v,j)))
120: {
121: UNMKEDGE(ARC(v,j)); /* return edge to normal value */
122: adj = ARC(v,j);
123: if (NTYPE(adj) == ITERVX) continue;
124: ASSERT(NTYPE(adj) == LOOPVX,addloop);
125: ARC(v,j) = ARC(adj,0); /* change arc to point to ITERVX */
126: ASSERT(NTYPE(ARC(v,j)) == ITERVX,addloop);
127: }
128: }
129: }
130:
131: insloop(v) /* insert LOOPVX, ITERVX at node number v */
132: VERT v;
133: {
134: VERT loo, iter;
135: loo = create(LOOPVX, 1);
136: iter = create(ITERVX,1);
137: accessnum += 2;
138: /* want LOOPVX to take on node number v, so that arcs other than back arcs
139: entering v will enter the LOOPVX automatically */
140: exchange(&graph[v], &graph[loo]);
141: exchange(&v, &loo);
142: ARC(loo,0) = iter;
143: ARC(iter,0) = v;
144: FATH(iter) = UNDEFINED; /* will be defined later along with FATH for DOVX */
145: }
146:
147: exchange(p1,p2) /* exchange values of p1,p2 */
148: int *p1,*p2;
149: {
150: int temp;
151: temp = *p1;
152: *p1 = *p2;
153: *p2 = temp;
154: }
155:
156:
157: repsearch(v) /* repeat df search in order to fill in after, ntoaft, ntobef tables */
158: VERT v;
159: {
160: VERT adj; int i,temp;
161: ntobef[v] = befcount;
162: ++befcount;
163: for(i = 0; i < ARCNUM(v); ++i)
164: {
165: adj = ARC(v,i);
166: if (DEFINED(adj) && ntobef[adj] == UNDEFINED)
167: repsearch(adj);
168: }
169: ++aftcount;
170: temp = accessnum - aftcount;
171: after[temp] = v;
172: ntoaft[v] = temp;
173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.