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: }