11495Sbill # 2*1508Sbill static char sccsid[] = "@(#)c20.c 4.2 10/18/80"; 3*1508Sbill /* char C20[] = {"@(#)c20.c 1.35 80/08/26 14:13:40"}; /* sccs ident */ 41495Sbill /* 51495Sbill * C object code improver 61495Sbill */ 71495Sbill 81495Sbill #include "c2.h" 91495Sbill #include <stdio.h> 101495Sbill #include <ctype.h> 111495Sbill 121495Sbill char _sibuf[BUFSIZ], _sobuf[BUFSIZ]; 131495Sbill int ioflag; 14*1508Sbill long isn = 2000000; 151495Sbill struct optab *oplook(); 161495Sbill struct optab *getline(); 17*1508Sbill long lgensym[10] = 18*1508Sbill {100000L,200000L,300000L,400000L,500000L,600000L,700000L,800000L,900000L,1000000L}; 191495Sbill 201495Sbill struct node * 211495Sbill alloc(an) 221495Sbill { 231495Sbill register int n; 241495Sbill register char *p; 251495Sbill 261495Sbill n = an; 27*1508Sbill n+=sizeof(char *)-1; 28*1508Sbill n &= ~(sizeof(char *)-1); 291495Sbill n++; 301495Sbill n &= ~01; 311495Sbill if (lasta+n >= lastr) { 321495Sbill if (sbrk(2000) == -1) { 331495Sbill fprintf(stderr, "Optimizer: out of space\n"); 341495Sbill exit(1); 351495Sbill } 361495Sbill lastr += 2000; 371495Sbill } 381495Sbill p = lasta; 391495Sbill lasta += n; 401495Sbill return(p); 411495Sbill } 421495Sbill 431495Sbill main(argc, argv) 441495Sbill char **argv; 451495Sbill { 461495Sbill register int niter, maxiter, isend; 471495Sbill int nflag,infound; 481495Sbill 491495Sbill nflag = 0; infound=0; argc--; argv++; 501495Sbill while (argc>0) {/* get flags */ 511495Sbill if (**argv=='+') debug++; 521495Sbill else if (**argv=='-') { 531495Sbill if ((*argv)[1]=='i') ioflag++; else nflag++; 541495Sbill } else if (infound==0) { 551495Sbill if (freopen(*argv, "r", stdin) ==NULL) { 561495Sbill fprintf(stderr,"C2: can't find %s\n", *argv); 571495Sbill exit(1); 581495Sbill } 591495Sbill setbuf(stdin,_sibuf); ++infound; 601495Sbill } else if (freopen(*argv, "w", stdout) ==NULL) { 611495Sbill fprintf(stderr,"C2: can't create %s\n", *argv); 621495Sbill exit(1); 631495Sbill } 641495Sbill setbuf(stdout,_sobuf); 651495Sbill argc--; argv++; 661495Sbill } 671495Sbill lasta = lastr = sbrk(2); 681495Sbill opsetup(); 691495Sbill lasta = firstr = lastr = alloc(0); 701495Sbill maxiter = 0; 711495Sbill do { 721495Sbill isend = input(); 731495Sbill niter = 0; 741495Sbill bmove(); 751495Sbill do { 761495Sbill refcount(); 771495Sbill do { 781495Sbill iterate(); 791495Sbill clearreg(); 801495Sbill niter++; 811495Sbill } while (nchange); 821495Sbill comjump(); 831495Sbill rmove(); 841495Sbill } while (nchange || jumpsw()); 851495Sbill addsob(); 861495Sbill output(); 871495Sbill if (niter > maxiter) 881495Sbill maxiter = niter; 891495Sbill lasta = firstr; 901495Sbill } while (isend); 911495Sbill if (nflag) { 921495Sbill fprintf(stderr,"%d iterations\n", maxiter); 931495Sbill fprintf(stderr,"%d jumps to jumps\n", nbrbr); 941495Sbill fprintf(stderr,"%d inst. after jumps\n", iaftbr); 951495Sbill fprintf(stderr,"%d jumps to .+1\n", njp1); 961495Sbill fprintf(stderr,"%d redundant labels\n", nrlab); 971495Sbill fprintf(stderr,"%d cross-jumps\n", nxjump); 981495Sbill fprintf(stderr,"%d code motions\n", ncmot); 991495Sbill fprintf(stderr,"%d branches reversed\n", nrevbr); 1001495Sbill fprintf(stderr,"%d redundant moves\n", redunm); 1011495Sbill fprintf(stderr,"%d simplified addresses\n", nsaddr); 1021495Sbill fprintf(stderr,"%d loops inverted\n", loopiv); 1031495Sbill fprintf(stderr,"%d redundant jumps\n", nredunj); 1041495Sbill fprintf(stderr,"%d common seqs before jmp's\n", ncomj); 1051495Sbill fprintf(stderr,"%d skips over jumps\n", nskip); 1061495Sbill fprintf(stderr,"%d sob's added\n", nsob); 1071495Sbill fprintf(stderr,"%d redundant tst's\n", nrtst); 1081495Sbill fprintf(stderr,"%d jump on bit\n", nbj); 1091495Sbill fprintf(stderr,"%d field operations\n", nfield); 1101495Sbill fprintf(stderr,"%dK core\n", ((unsigned)lastr+01777) >> 10); 1111495Sbill } 1121495Sbill putc('\n',stdout); 1131495Sbill fflush(stdout); exit(0); 1141495Sbill } 1151495Sbill 1161495Sbill input() 1171495Sbill { 1181495Sbill register struct node *p, *lastp; 1191495Sbill struct optab *op; register char *cp1; 1201495Sbill static struct optab F77JSW = {".long", T(JSW,1)}; 1211495Sbill 1221495Sbill lastp = &first; 1231495Sbill for (;;) { 1241495Sbill top: 1251495Sbill op = getline(); 1261495Sbill if (debug && op==0) fprintf(stderr,"? %s\n",line); 1271495Sbill switch (op->opcode&0377) { 1281495Sbill 1291495Sbill case LABEL: 1301495Sbill p = alloc(sizeof first); 1311495Sbill if (isdigit(line[0]) && (p->labno=locdef(line)) || 1321495Sbill (line[0] == 'L') && (p->labno=getnum(line+1))) { 1331495Sbill p->combop = LABEL; 134*1508Sbill if (p->labno<100000L && isn<=p->labno) isn=1+p->labno; 1351495Sbill p->code = 0; 1361495Sbill } else { 1371495Sbill p->combop = DLABEL; 1381495Sbill p->labno = 0; 1391495Sbill p->code = copy(line); 1401495Sbill } 1411495Sbill break; 1421495Sbill 1431495Sbill case LGEN: 1441495Sbill if (*curlp!='L' && !locuse(curlp)) goto std; 1451495Sbill op= &F77JSW; 1461495Sbill case JBR: 1471495Sbill if (op->opcode==T(JBR,RET) || op->opcode==T(JBR,RSB)) goto std; 1481495Sbill case CBR: 1491495Sbill case JMP: 1501495Sbill case JSW: 1511495Sbill case SOBGEQ: case SOBGTR: case AOBLEQ: case AOBLSS: case ACB: 1521495Sbill p = alloc(sizeof first); 1531495Sbill p->combop = op->opcode; p->code=0; cp1=curlp; 1541495Sbill if ((!isdigit(*cp1) || 0==(p->labno=locuse(cp1))) && 1551495Sbill (*cp1!='L' || 0==(p->labno = getnum(cp1+1)))) {/* jbs, etc.? */ 1561495Sbill while (*cp1++); while (*--cp1!=',' && cp1!=curlp); 1571495Sbill if (cp1==curlp || 1581495Sbill (!isdigit(*++cp1) || 0==(p->labno=locuse(cp1))) && 1591495Sbill (*cp1!='L' || 0==(p->labno=getnum(cp1+1)))) 1601495Sbill p->labno = 0; 1611495Sbill else *--cp1=0; 1621495Sbill p->code = copy(curlp); 1631495Sbill } 1641495Sbill if (isn<=p->labno) isn=1+p->labno; 1651495Sbill break; 1661495Sbill 1671495Sbill case MOVA: 1681495Sbill p=alloc(sizeof first); 1691495Sbill p->combop=op->opcode; p->code=0; cp1=curlp+1; 1701495Sbill if (cp1[-1]=='L' || isdigit(cp1[-1])) { 1711495Sbill while (*cp1++!=','); *--cp1=0; 1721495Sbill if (0!=(p->labno=locuse(curlp)) || 1731495Sbill 0!=(p->labno=getnum(curlp+1))) p->code=copy(cp1+1); 1741495Sbill else {*cp1=','; p->code=copy(curlp);} 1751495Sbill } else {p->code=copy(--cp1); p->labno=0;} 1761495Sbill break; 1771495Sbill 1781495Sbill case SET: 1791495Sbill case COMM: 1801495Sbill case LCOMM: 1811495Sbill printf("%s\n",line); goto top; 1821495Sbill 1831495Sbill case BSS: 1841495Sbill case DATA: 1851495Sbill for (;;) { 1861495Sbill printf("%s%c",line,(op->opcode==LABEL ? ':' : '\n')); 1871495Sbill if (op->opcode==TEXT) goto top; 1881495Sbill if (END==(op=getline())->opcode) {/* dangling .data is bad for you */ 1891495Sbill printf(".text\n"); 1901495Sbill break; 1911495Sbill } 1921495Sbill } 1931495Sbill 1941495Sbill std: 1951495Sbill default: 1961495Sbill p = alloc(sizeof first); 1971495Sbill p->combop = op->opcode; 1981495Sbill p->labno = 0; 1991495Sbill p->code = copy(curlp); 2001495Sbill break; 2011495Sbill 2021495Sbill } 2031495Sbill p->forw = 0; 2041495Sbill p->back = lastp; 2051495Sbill p->pop = op; 2061495Sbill lastp->forw = p; 2071495Sbill lastp = p; 2081495Sbill p->ref = 0; 2091495Sbill if (p->op==CASE) { 2101495Sbill char *lp; int ncase; 2111495Sbill lp=curlp; while (*lp++); while (*--lp!='$'); ncase=getnum(lp+1); 2121495Sbill if (LABEL!=(getline())->opcode) abort(-2); 2131495Sbill do { 2141495Sbill if (WGEN!=(getline())->opcode) abort(-3); 2151495Sbill p = alloc(sizeof first); p->combop = JSW; p->code = 0; 2161495Sbill lp=curlp; while(*lp++!='-'); *--lp=0; p->labno=getnum(curlp+1); 2171495Sbill if (isn<=p->labno) isn=1+p->labno; 2181495Sbill p->forw = 0; p->back = lastp; lastp->forw = p; lastp = p; 2191495Sbill p->ref = 0; p->pop=0; 2201495Sbill } while (--ncase>=0); 2211495Sbill } 2221495Sbill if (op->opcode==EROU) 2231495Sbill return(1); 2241495Sbill if (op->opcode==END) 2251495Sbill return(0); 2261495Sbill } 2271495Sbill } 2281495Sbill 2291495Sbill struct optab * 2301495Sbill getline() 2311495Sbill { 2321495Sbill register char *lp; 2331495Sbill register c; 2341495Sbill static struct optab OPLABEL={"",LABEL}; 2351495Sbill static struct optab OPEND={"",END}; 2361495Sbill 2371495Sbill lp = line; 2381495Sbill while (EOF!=(c=getchar()) && isspace(c)); 2391495Sbill while (EOF!=c) { 2401495Sbill if (c==':') { 2411495Sbill *lp++ = 0; 2421495Sbill return(&OPLABEL); 2431495Sbill } 2441495Sbill if (c=='\n') { 2451495Sbill *lp++ = 0; 2461495Sbill return(oplook()); 2471495Sbill } 2481495Sbill *lp++ = c; 2491495Sbill c = getchar(); 2501495Sbill } 2511495Sbill *lp++ = 0; 2521495Sbill return(&OPEND); 2531495Sbill } 2541495Sbill 2551495Sbill long 2561495Sbill getnum(p) 2571495Sbill register char *p; 2581495Sbill { 2591495Sbill register c; int neg; register long n; 2601495Sbill 2611495Sbill n = 0; neg=0; if (*p=='-') {++neg; ++p;} 2621495Sbill while (isdigit(c = *p++)) { 2631495Sbill c -= '0'; n *= 10; if (neg) n -= c; else n += c; 2641495Sbill } 2651495Sbill if (*--p != 0) 2661495Sbill return(0); 2671495Sbill return(n); 2681495Sbill } 2691495Sbill 2701495Sbill locuse(p) 2711495Sbill register char *p; 2721495Sbill { 2731495Sbill register c; int neg; register long n; 2741495Sbill 2751495Sbill if (!isdigit(p[0]) || p[1] != 'f' && p[1] != 'b' || p[2]) return(0); 2761495Sbill return (lgensym[p[0] - '0'] - (p[1] == 'b')); 2771495Sbill } 2781495Sbill 2791495Sbill locdef(p) 2801495Sbill register char *p; 2811495Sbill { 2821495Sbill 2831495Sbill if (!isdigit(p[0]) || p[1]) return(0); 2841495Sbill return (lgensym[p[0] - '0']++); 2851495Sbill } 2861495Sbill 2871495Sbill output() 2881495Sbill { 2891495Sbill register struct node *t; 2901495Sbill int casebas; 2911495Sbill 2921495Sbill t = &first; 2931495Sbill while (t = t->forw) switch (t->op) { 2941495Sbill 2951495Sbill case END: 2961495Sbill fflush(stdout); 2971495Sbill return; 2981495Sbill 2991495Sbill case LABEL: 3001495Sbill printf("L%d:", t->labno); 3011495Sbill continue; 3021495Sbill 3031495Sbill case DLABEL: 3041495Sbill printf("%s:", t->code); 3051495Sbill continue; 3061495Sbill 3071495Sbill case CASE: 3081495Sbill casebas=0; 3091495Sbill 3101495Sbill default: std: 3111495Sbill if (t->pop==0) {/* must find it */ 3121495Sbill register struct optab *p; 3131495Sbill for (p=optab; p->opstring[0]; ++p) 3141495Sbill if (p->opcode==t->combop) {t->pop=p; break;} 3151495Sbill } 3161495Sbill printf("%s", t->pop->opstring); 3171495Sbill if (t->code) printf("\t%s", t->code); 3181495Sbill if (t->labno!=0) printf("%cL%d\n", 3191495Sbill (t->code ? ',' : '\t'), 3201495Sbill t->labno); 3211495Sbill else printf("\n"); 3221495Sbill continue; 3231495Sbill 3241495Sbill case MOVA: 3251495Sbill if (t->labno==0) goto std; 3261495Sbill printf("mova%c\tL%d,%s\n","bwlq"[t->subop-BYTE],t->labno,t->code); 3271495Sbill continue; 3281495Sbill 3291495Sbill case JSW: 3301495Sbill if (t->subop!=0) {/* F77JSW */ 3311495Sbill printf(".long\tL%d\n",t->labno); continue; 3321495Sbill } 3331495Sbill if (casebas==0) printf("L%d:\n",casebas=isn++); 3341495Sbill printf(".word L%d-L%d\n", t->labno, casebas); 3351495Sbill continue; 3361495Sbill 3371495Sbill } 3381495Sbill } 3391495Sbill 3401495Sbill char * 3411495Sbill copy(ap) 3421495Sbill char *ap; 3431495Sbill { 3441495Sbill register char *p, *np; 3451495Sbill char *onp; 3461495Sbill register n; 3471495Sbill int na; 3481495Sbill 3491495Sbill na = nargs(); 3501495Sbill p = ap; 3511495Sbill n = 0; 3521495Sbill if (*p==0) 3531495Sbill return(0); 3541495Sbill do 3551495Sbill n++; 3561495Sbill while (*p++); 3571495Sbill if (na>1) { 3581495Sbill p = (&ap)[1]; 3591495Sbill while (*p++) 3601495Sbill n++; 3611495Sbill } 3621495Sbill onp = np = alloc(n); 3631495Sbill p = ap; 3641495Sbill while (*np++ = *p++); 3651495Sbill if (na>1) { 3661495Sbill p = (&ap)[1]; 3671495Sbill np--; 3681495Sbill while (*np++ = *p++); 3691495Sbill } 3701495Sbill return(onp); 3711495Sbill } 3721495Sbill 3731495Sbill #define OPHS 560 3741495Sbill struct optab *ophash[OPHS]; 3751495Sbill 3761495Sbill opsetup() 3771495Sbill { 3781495Sbill register struct optab *optp, **ophp; 3791495Sbill register int i,t; 3801495Sbill 3811495Sbill for(i=NREG+5;--i>=0;) regs[i]=alloc(20); 3821495Sbill for (optp = optab; optp->opstring[0]; optp++) { 3831495Sbill t=7; i=0; while (--t>=0) i+= i+optp->opstring[t]; 3841495Sbill ophp = &ophash[i % OPHS]; 3851495Sbill while (*ophp++) { 3861495Sbill /* fprintf(stderr,"\ncollision: %d %s %s", 3871495Sbill /* ophp-1-ophash,optp->opstring,(*(ophp-1))->opstring); 3881495Sbill */ 3891495Sbill if (ophp > &ophash[OPHS]) 3901495Sbill ophp = ophash; 3911495Sbill } 3921495Sbill *--ophp = optp; 3931495Sbill } 3941495Sbill } 3951495Sbill 3961495Sbill struct optab * 3971495Sbill oplook() 3981495Sbill { 3991495Sbill register struct optab *optp,**ophp; 4001495Sbill register char *p,*p2; 4011495Sbill register int t; 4021495Sbill char tempop[20]; 4031495Sbill static struct optab OPNULL={"",0}; 4041495Sbill 4051495Sbill for (p=line, p2=tempop; *p && !isspace(*p); *p2++= *p++); *p2=0; p2=p; 4061495Sbill while (isspace(*p2)) ++p2; curlp=p2; 4071495Sbill t=0; while(--p>=line) t += t+*p; ophp = &ophash[t % OPHS]; 4081495Sbill while (optp = *ophp) { 4091495Sbill if (equstr(tempop,optp->opstring)) return(optp); 4101495Sbill if ((++ophp) >= &ophash[OPHS]) ophp = ophash; 4111495Sbill } 4121495Sbill curlp = line; 4131495Sbill return(&OPNULL); 4141495Sbill } 4151495Sbill 4161495Sbill refcount() 4171495Sbill { 4181495Sbill register struct node *p, *lp; 4191495Sbill struct node *labhash[LABHS]; 4201495Sbill register struct node **hp; 4211495Sbill 4221495Sbill for (hp = labhash; hp < &labhash[LABHS];) 4231495Sbill *hp++ = 0; 4241495Sbill for (p = first.forw; p!=0; p = p->forw) 4251495Sbill if (p->op==LABEL) { 4261495Sbill labhash[p->labno % LABHS] = p; 4271495Sbill p->refc = 0; 4281495Sbill } 4291495Sbill for (p = first.forw; p!=0; p = p->forw) { 4301495Sbill if (p->combop==JBR || p->op==CBR || p->op==JSW || p->op==JMP 4311495Sbill || p->op==SOBGEQ || p->op==SOBGTR || p->op==AOBLEQ || p->op==AOBLSS 4321495Sbill || p->op==ACB || (p->op==MOVA && p->labno!=0)) { 4331495Sbill p->ref = 0; 4341495Sbill lp = labhash[p->labno % LABHS]; 4351495Sbill if (lp==0 || p->labno!=lp->labno) 4361495Sbill for (lp = first.forw; lp!=0; lp = lp->forw) { 4371495Sbill if (lp->op==LABEL && p->labno==lp->labno) 4381495Sbill break; 4391495Sbill } 4401495Sbill if (lp) { 4411495Sbill hp = nonlab(lp)->back; 4421495Sbill if (hp!=lp) { 4431495Sbill p->labno = hp->labno; 4441495Sbill lp = hp; 4451495Sbill } 4461495Sbill p->ref = lp; 4471495Sbill lp->refc++; 4481495Sbill } 4491495Sbill } 4501495Sbill } 4511495Sbill for (p = first.forw; p!=0; p = p->forw) 4521495Sbill if (p->op==LABEL && p->refc==0 4531495Sbill && (lp = nonlab(p))->op && lp->op!=JSW) 4541495Sbill decref(p); 4551495Sbill } 4561495Sbill 4571495Sbill iterate() 4581495Sbill { 4591495Sbill register struct node *p, *rp, *p1; 4601495Sbill 4611495Sbill nchange = 0; 4621495Sbill for (p = first.forw; p!=0; p = p->forw) { 4631495Sbill if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) { 4641495Sbill rp = nonlab(p->ref); 4651495Sbill if (rp->op==JBR && rp->labno && p->labno!=rp->labno) { 4661495Sbill nbrbr++; 4671495Sbill p->labno = rp->labno; 4681495Sbill decref(p->ref); 4691495Sbill rp->ref->refc++; 4701495Sbill p->ref = rp->ref; 4711495Sbill nchange++; 4721495Sbill } 4731495Sbill } 4741495Sbill #ifndef COPYCODE 4751495Sbill if (p->op==CBR && (p1 = p->forw)->combop==JBR) {/* combop: RET problems */ 4761495Sbill #else 4771495Sbill if (p->op==CBR && (p1 = p->forw)->combop==JBR && 4781495Sbill p->ref) {/* combop: RET problems */ 4791495Sbill #endif 4801495Sbill rp = p->ref; 4811495Sbill do 4821495Sbill rp = rp->back; 4831495Sbill while (rp->op==LABEL); 4841495Sbill if (rp==p1) { 4851495Sbill decref(p->ref); 4861495Sbill p->ref = p1->ref; 4871495Sbill p->labno = p1->labno; 4881495Sbill #ifdef COPYCODE 4891495Sbill if (p->labno == 0) 4901495Sbill p->code = p1->code; 4911495Sbill #endif 4921495Sbill p1->forw->back = p; 4931495Sbill p->forw = p1->forw; 4941495Sbill p->subop = revbr[p->subop]; 4951495Sbill p->pop=0; 4961495Sbill nchange++; 4971495Sbill nskip++; 4981495Sbill } 4991495Sbill } 5001495Sbill if (p->op==JBR || p->op==JMP) { 5011495Sbill while (p->forw && p->forw->op!=LABEL && p->forw->op!=DLABEL 5021495Sbill && p->forw->op!=EROU && p->forw->op!=END 5031495Sbill && p->forw->op!=ALIGN 5041495Sbill && p->forw->op!=0 && p->forw->op!=DATA) { 5051495Sbill nchange++; 5061495Sbill iaftbr++; 5071495Sbill if (p->forw->ref) 5081495Sbill decref(p->forw->ref); 5091495Sbill p->forw = p->forw->forw; 5101495Sbill p->forw->back = p; 5111495Sbill } 5121495Sbill rp = p->forw; 5131495Sbill while (rp && rp->op==LABEL) { 5141495Sbill if (p->ref == rp) { 5151495Sbill p->back->forw = p->forw; 5161495Sbill p->forw->back = p->back; 5171495Sbill p = p->back; 5181495Sbill decref(rp); 5191495Sbill nchange++; 5201495Sbill njp1++; 5211495Sbill break; 5221495Sbill } 5231495Sbill rp = rp->forw; 5241495Sbill } 5251495Sbill xjump(p); 5261495Sbill p = codemove(p); 5271495Sbill } 5281495Sbill } 5291495Sbill } 5301495Sbill 5311495Sbill xjump(p1) 5321495Sbill register struct node *p1; 5331495Sbill { 5341495Sbill register struct node *p2, *p3; 5351495Sbill int nxj; 5361495Sbill 5371495Sbill nxj = 0; 5381495Sbill if ((p2 = p1->ref)==0) 5391495Sbill return(0); 5401495Sbill for (;;) { 5411495Sbill while ((p1 = p1->back) && p1->op==LABEL); 5421495Sbill while ((p2 = p2->back) && p2->op==LABEL); 5431495Sbill if (!equop(p1, p2) || p1==p2) 5441495Sbill return(nxj); 5451495Sbill p3 = insertl(p2); 5461495Sbill p1->combop = JBR; 5471495Sbill p1->pop=0; 5481495Sbill p1->ref = p3; 5491495Sbill p1->labno = p3->labno; 5501495Sbill p1->code = 0; 5511495Sbill nxj++; 5521495Sbill nxjump++; 5531495Sbill nchange++; 5541495Sbill } 5551495Sbill } 5561495Sbill 5571495Sbill struct node * 5581495Sbill insertl(op) 5591495Sbill register struct node *op; 5601495Sbill { 5611495Sbill register struct node *lp; 5621495Sbill 5631495Sbill if (op->op == LABEL) { 5641495Sbill op->refc++; 5651495Sbill return(op); 5661495Sbill } 5671495Sbill if (op->back->op == LABEL) { 5681495Sbill op = op->back; 5691495Sbill op->refc++; 5701495Sbill return(op); 5711495Sbill } 5721495Sbill lp = alloc(sizeof first); 5731495Sbill lp->combop = LABEL; 5741495Sbill lp->labno = isn++; 5751495Sbill lp->ref = 0; 5761495Sbill lp->code = 0; 5771495Sbill lp->refc = 1; 5781495Sbill lp->back = op->back; 5791495Sbill lp->forw = op; 5801495Sbill op->back->forw = lp; 5811495Sbill op->back = lp; 5821495Sbill return(lp); 5831495Sbill } 5841495Sbill 5851495Sbill struct node * 5861495Sbill codemove(ap) 5871495Sbill struct node *ap; 5881495Sbill { 5891495Sbill register struct node *p1, *p2, *p3; 5901495Sbill struct node *t, *tl; 5911495Sbill int n; 5921495Sbill 5931495Sbill p1 = ap; 5941495Sbill /* last clause to avoid infinite loop on partial compiler droppings: 5951495Sbill L183: jbr L179 5961495Sbill L191: jbr L179 5971495Sbill casel r0,$0,$1 5981495Sbill L193: .word L183-L193 5991495Sbill .word L191-L193 6001495Sbill L179: ret 6011495Sbill */ 6021495Sbill if (p1->op!=JBR || (p2 = p1->ref)==0 || p2==p1->forw) 6031495Sbill return(p1); 6041495Sbill while (p2->op == LABEL) 6051495Sbill if ((p2 = p2->back) == 0) 6061495Sbill return(p1); 6071495Sbill if (p2->op!=JBR && p2->op!=JMP) 6081495Sbill goto ivloop; 6091495Sbill p2 = p2->forw; 6101495Sbill p3 = p1->ref; 6111495Sbill while (p3) { 6121495Sbill if (p3->op==JBR || p3->op==JMP) { 6131495Sbill if (p1==p3) 6141495Sbill return(p1); 6151495Sbill ncmot++; 6161495Sbill nchange++; 6171495Sbill p1->back->forw = p2; 6181495Sbill p1->forw->back = p3; 6191495Sbill p2->back->forw = p3->forw; 6201495Sbill p3->forw->back = p2->back; 6211495Sbill p2->back = p1->back; 6221495Sbill p3->forw = p1->forw; 6231495Sbill decref(p1->ref); 6241495Sbill return(p2); 6251495Sbill } else 6261495Sbill p3 = p3->forw; 6271495Sbill } 6281495Sbill return(p1); 6291495Sbill ivloop: 6301495Sbill if (p1->forw->op!=LABEL) 6311495Sbill return(p1); 6321495Sbill p3 = p2 = p2->forw; 6331495Sbill n = 16; 6341495Sbill do { 6351495Sbill if ((p3 = p3->forw) == 0 || p3==p1 || --n==0) 6361495Sbill return(p1); 6371495Sbill } while (p3->op!=CBR || p3->labno!=p1->forw->labno); 6381495Sbill do 6391495Sbill if ((p1 = p1->back) == 0) 6401495Sbill return(ap); 6411495Sbill while (p1!=p3); 6421495Sbill p1 = ap; 6431495Sbill tl = insertl(p1); 6441495Sbill p3->subop = revbr[p3->subop]; 6451495Sbill p3->pop=0; 6461495Sbill decref(p3->ref); 6471495Sbill p2->back->forw = p1; 6481495Sbill p3->forw->back = p1; 6491495Sbill p1->back->forw = p2; 6501495Sbill p1->forw->back = p3; 6511495Sbill t = p1->back; 6521495Sbill p1->back = p2->back; 6531495Sbill p2->back = t; 6541495Sbill t = p1->forw; 6551495Sbill p1->forw = p3->forw; 6561495Sbill p3->forw = t; 6571495Sbill p2 = insertl(p1->forw); 6581495Sbill p3->labno = p2->labno; 6591495Sbill #ifdef COPYCODE 6601495Sbill if (p3->labno == 0) 6611495Sbill p3->code = p2->code; 6621495Sbill #endif 6631495Sbill p3->ref = p2; 6641495Sbill decref(tl); 6651495Sbill if (tl->refc<=0) 6661495Sbill nrlab--; 6671495Sbill loopiv++; 6681495Sbill nchange++; 6691495Sbill return(p3); 6701495Sbill } 6711495Sbill 6721495Sbill comjump() 6731495Sbill { 6741495Sbill register struct node *p1, *p2, *p3; 6751495Sbill 6761495Sbill for (p1 = first.forw; p1!=0; p1 = p1->forw) 6771495Sbill if (p1->op==JBR && ((p2 = p1->ref) && p2->refc > 1 6781495Sbill || p1->subop==RET || p1->subop==RSB)) 6791495Sbill for (p3 = p1->forw; p3!=0; p3 = p3->forw) 6801495Sbill if (p3->op==JBR && p3->ref == p2) 6811495Sbill backjmp(p1, p3); 6821495Sbill } 6831495Sbill 6841495Sbill backjmp(ap1, ap2) 6851495Sbill struct node *ap1, *ap2; 6861495Sbill { 6871495Sbill register struct node *p1, *p2, *p3; 6881495Sbill 6891495Sbill p1 = ap1; 6901495Sbill p2 = ap2; 6911495Sbill for(;;) { 6921495Sbill while ((p1 = p1->back) && p1->op==LABEL); 6931495Sbill p2 = p2->back; 6941495Sbill if (equop(p1, p2)) { 6951495Sbill p3 = insertl(p1); 6961495Sbill p2->back->forw = p2->forw; 6971495Sbill p2->forw->back = p2->back; 6981495Sbill p2 = p2->forw; 6991495Sbill decref(p2->ref); 7001495Sbill p2->combop = JBR; /* to handle RET */ 7011495Sbill p2->pop=0; 7021495Sbill p2->labno = p3->labno; 7031495Sbill #ifdef COPYCODE 7041495Sbill p2->code = 0; 7051495Sbill #endif 7061495Sbill p2->ref = p3; 7071495Sbill nchange++; 7081495Sbill ncomj++; 7091495Sbill } else 7101495Sbill return; 7111495Sbill } 7121495Sbill } 713