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