|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)3.loop.c 4.1 (Berkeley) 2/11/83";
3: #endif not lint
4:
5: #include <stdio.h>
6: #include "def.h"
7: #include "3.def.h"
8:
9: #define ARCCOUNT(v) REACH(v)
10:
11:
12: fixhd(v,hd,head)
13: VERT v,hd,*head;
14: {
15: VERT w,newhd;
16: int i;
17: head[v] = hd;
18: newhd = (NTYPE(v) == ITERVX) ? v : hd;
19: for (i = 0; i < CHILDNUM(v); ++i)
20: for (w = LCHILD(v,i); DEFINED(w); w = RSIB(w))
21: fixhd(w,newhd,head);
22: }
23:
24: getloop()
25: {
26: cntarcs();
27: fixloop(START);
28: }
29:
30:
31: cntarcs() /* count arcs entering each node */
32: {
33: VERT w,v;
34: int i;
35: for (v = 0; v < nodenum; ++v)
36: ARCCOUNT(v) = 0;
37: for (v = 0; v < nodenum; ++v)
38: for (i = 0; i < ARCNUM(v); ++i)
39: {
40: w = ARC(v,i);
41: if (!DEFINED(w)) continue;
42: ++ARCCOUNT(w);
43: }
44: }
45:
46:
47: fixloop(v) /* find WHILE loops */
48: VERT v;
49: {
50: int recvar;
51: if (NTYPE(v) == LOOPVX)
52: {
53: ASSERT(DEFINED(ARC(v,0)),fixloop);
54: NXT(ARC(v,0)) = ARC(v,0);
55: if (!getwh(v))
56: getun(v);
57: }
58: else if (NTYPE(v) == IFVX && arbcase)
59: getswitch(v);
60: else if (NTYPE(v)==DOVX)
61: {
62: ASSERT(DEFINED(ARC(v,0)),fixloop);
63: NXT(ARC(v,0))=ARC(v,0);
64: }
65: RECURSE(fixloop,v,recvar);
66: }
67:
68:
69: getwh(v)
70: VERT v;
71: {
72: VERT vchild, vgrand,vgreat;
73: ASSERT(NTYPE(v) == LOOPVX,getwh);
74: vchild = LCHILD(v,0);
75: ASSERT(DEFINED(vchild),getwh);
76: ASSERT(NTYPE(vchild) == ITERVX,getwh);
77: vgrand = LCHILD(vchild,0);
78: if (!DEFINED(vgrand) || !IFTHEN(vgrand) )
79: return(FALSE);
80: vgreat = LCHILD(vgrand,THEN);
81: if (DEFINED(vgreat) && NTYPE(vgreat) == GOVX && ARC(vgreat,0) == BRK(vchild))
82: {
83: /* turn into WHILE */
84: NTYPE(v) = WHIVX;
85: NEG(vgrand) = !NEG(vgrand);
86: LPRED(vchild) = vgrand;
87: LCHILD(vchild,0) = RSIB(vgrand);
88: RSIB(vgrand) = UNDEFINED;
89: return(TRUE);
90: }
91: return(FALSE);
92: }
93:
94:
95:
96: getun(v) /* change loop to REPEAT UNTIL if possible */
97: VERT v;
98: {
99: VERT vchild, vgrand, vgreat, before, ch;
100: ASSERT(NTYPE(v) == LOOPVX,getun);
101: vchild = LCHILD(v,0);
102: ASSERT(DEFINED(vchild), getun);
103: if (ARCCOUNT(vchild) > 2)
104: return(FALSE); /* loop can be iterated without passing through predicate of UNTIL */
105: vgrand = ARC(vchild,0);
106: if (!DEFINED(vgrand))
107: return(FALSE);
108: for (ch = vgrand,before = UNDEFINED; DEFINED(RSIB(ch)); ch = RSIB(ch))
109: before = ch;
110: if (!IFTHEN(ch))
111: return(FALSE);
112: vgreat = LCHILD(ch,THEN);
113: if (DEFINED(vgreat) && NTYPE(vgreat) == GOVX && ARC(vgreat,0) == BRK(vchild))
114: {
115: /* create UNTIL node */
116: NTYPE(v) = UNTVX;
117: NXT(vchild) = ch;
118: LPRED(vchild)=ch;
119: RSIB(before) = UNDEFINED;
120: return(TRUE);
121: }
122: return(FALSE);
123: }
124:
125:
126: #define FORMCASE(w) (DEFINED(w) && !DEFINED(RSIB(w)) && NTYPE(w) == IFVX && ARCCOUNT(w) == 1)
127:
128: getswitch(v)
129: VERT v;
130: {
131: VERT ch, grand, temp;
132: /* must be of form if ... else if ... else if ... */
133: if (NTYPE(v) != IFVX) return(FALSE);
134: ch = LCHILD(v,ELSE);
135: if (!FORMCASE(ch)) return(FALSE);
136: grand = LCHILD(ch,ELSE);
137: if (!FORMCASE(grand)) return(FALSE);
138:
139: temp = create(SWCHVX,0);
140: exchange(&graph[temp],&graph[v]); /* want arcs to enter switch, not first case*/
141: BEGCOM(v) = UNDEFINED;
142: RSIB(v) = RSIB(temp); /* statements which followed IFVX should follow switch */
143: EXP(v) = UNDEFINED;
144: LCHILD(v,0) = temp;
145: NTYPE(temp) = ACASVX;
146: for (ch = LCHILD(temp,ELSE); FORMCASE(ch); )
147: {
148: LCHILD(temp,ELSE) = UNDEFINED;
149: RSIB(temp) = ch;
150: NTYPE(ch) = ACASVX;
151: temp = ch;
152: ch = LCHILD(temp,ELSE);
153: }
154: ASSERT(!DEFINED(RSIB(temp)),getswitch);
155: return(TRUE);
156: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.