1*1495Sbill # 2*1495Sbill static char sccsid[] = "@(#)c20.c 4.1 10/17/80"; 3*1495Sbill /* char C20[] = {"@(#)c20.c 1.33 80/08/08 10:01:02"}; /* sccs ident */ 4*1495Sbill /* 5*1495Sbill * C object code improver 6*1495Sbill */ 7*1495Sbill 8*1495Sbill #include "c2.h" 9*1495Sbill #include <stdio.h> 10*1495Sbill #include <ctype.h> 11*1495Sbill 12*1495Sbill char _sibuf[BUFSIZ], _sobuf[BUFSIZ]; 13*1495Sbill int ioflag; 14*1495Sbill int isn = 2000000; 15*1495Sbill struct optab *oplook(); 16*1495Sbill struct optab *getline(); 17*1495Sbill int lgensym[10] = 18*1495Sbill {100000,200000,300000,400000,500000,600000,700000,800000,900000,1000000}; 19*1495Sbill 20*1495Sbill struct node * 21*1495Sbill alloc(an) 22*1495Sbill { 23*1495Sbill register int n; 24*1495Sbill register char *p; 25*1495Sbill 26*1495Sbill n = an; 27*1495Sbill n++; 28*1495Sbill n &= ~01; 29*1495Sbill if (lasta+n >= lastr) { 30*1495Sbill if (sbrk(2000) == -1) { 31*1495Sbill fprintf(stderr, "Optimizer: out of space\n"); 32*1495Sbill exit(1); 33*1495Sbill } 34*1495Sbill lastr += 2000; 35*1495Sbill } 36*1495Sbill p = lasta; 37*1495Sbill lasta += n; 38*1495Sbill return(p); 39*1495Sbill } 40*1495Sbill 41*1495Sbill main(argc, argv) 42*1495Sbill char **argv; 43*1495Sbill { 44*1495Sbill register int niter, maxiter, isend; 45*1495Sbill int nflag,infound; 46*1495Sbill 47*1495Sbill nflag = 0; infound=0; argc--; argv++; 48*1495Sbill while (argc>0) {/* get flags */ 49*1495Sbill if (**argv=='+') debug++; 50*1495Sbill else if (**argv=='-') { 51*1495Sbill if ((*argv)[1]=='i') ioflag++; else nflag++; 52*1495Sbill } else if (infound==0) { 53*1495Sbill if (freopen(*argv, "r", stdin) ==NULL) { 54*1495Sbill fprintf(stderr,"C2: can't find %s\n", *argv); 55*1495Sbill exit(1); 56*1495Sbill } 57*1495Sbill setbuf(stdin,_sibuf); ++infound; 58*1495Sbill } else if (freopen(*argv, "w", stdout) ==NULL) { 59*1495Sbill fprintf(stderr,"C2: can't create %s\n", *argv); 60*1495Sbill exit(1); 61*1495Sbill } 62*1495Sbill setbuf(stdout,_sobuf); 63*1495Sbill argc--; argv++; 64*1495Sbill } 65*1495Sbill lasta = lastr = sbrk(2); 66*1495Sbill opsetup(); 67*1495Sbill lasta = firstr = lastr = alloc(0); 68*1495Sbill maxiter = 0; 69*1495Sbill do { 70*1495Sbill isend = input(); 71*1495Sbill niter = 0; 72*1495Sbill bmove(); 73*1495Sbill do { 74*1495Sbill refcount(); 75*1495Sbill do { 76*1495Sbill iterate(); 77*1495Sbill clearreg(); 78*1495Sbill niter++; 79*1495Sbill } while (nchange); 80*1495Sbill comjump(); 81*1495Sbill rmove(); 82*1495Sbill } while (nchange || jumpsw()); 83*1495Sbill addsob(); 84*1495Sbill output(); 85*1495Sbill if (niter > maxiter) 86*1495Sbill maxiter = niter; 87*1495Sbill lasta = firstr; 88*1495Sbill } while (isend); 89*1495Sbill if (nflag) { 90*1495Sbill fprintf(stderr,"%d iterations\n", maxiter); 91*1495Sbill fprintf(stderr,"%d jumps to jumps\n", nbrbr); 92*1495Sbill fprintf(stderr,"%d inst. after jumps\n", iaftbr); 93*1495Sbill fprintf(stderr,"%d jumps to .+1\n", njp1); 94*1495Sbill fprintf(stderr,"%d redundant labels\n", nrlab); 95*1495Sbill fprintf(stderr,"%d cross-jumps\n", nxjump); 96*1495Sbill fprintf(stderr,"%d code motions\n", ncmot); 97*1495Sbill fprintf(stderr,"%d branches reversed\n", nrevbr); 98*1495Sbill fprintf(stderr,"%d redundant moves\n", redunm); 99*1495Sbill fprintf(stderr,"%d simplified addresses\n", nsaddr); 100*1495Sbill fprintf(stderr,"%d loops inverted\n", loopiv); 101*1495Sbill fprintf(stderr,"%d redundant jumps\n", nredunj); 102*1495Sbill fprintf(stderr,"%d common seqs before jmp's\n", ncomj); 103*1495Sbill fprintf(stderr,"%d skips over jumps\n", nskip); 104*1495Sbill fprintf(stderr,"%d sob's added\n", nsob); 105*1495Sbill fprintf(stderr,"%d redundant tst's\n", nrtst); 106*1495Sbill fprintf(stderr,"%d jump on bit\n", nbj); 107*1495Sbill fprintf(stderr,"%d field operations\n", nfield); 108*1495Sbill fprintf(stderr,"%dK core\n", ((unsigned)lastr+01777) >> 10); 109*1495Sbill } 110*1495Sbill putc('\n',stdout); 111*1495Sbill fflush(stdout); exit(0); 112*1495Sbill } 113*1495Sbill 114*1495Sbill input() 115*1495Sbill { 116*1495Sbill register struct node *p, *lastp; 117*1495Sbill struct optab *op; register char *cp1; 118*1495Sbill static struct optab F77JSW = {".long", T(JSW,1)}; 119*1495Sbill 120*1495Sbill lastp = &first; 121*1495Sbill for (;;) { 122*1495Sbill top: 123*1495Sbill op = getline(); 124*1495Sbill if (debug && op==0) fprintf(stderr,"? %s\n",line); 125*1495Sbill switch (op->opcode&0377) { 126*1495Sbill 127*1495Sbill case LABEL: 128*1495Sbill p = alloc(sizeof first); 129*1495Sbill if (isdigit(line[0]) && (p->labno=locdef(line)) || 130*1495Sbill (line[0] == 'L') && (p->labno=getnum(line+1))) { 131*1495Sbill p->combop = LABEL; 132*1495Sbill if (isn<=p->labno) isn=1+p->labno; 133*1495Sbill p->code = 0; 134*1495Sbill } else { 135*1495Sbill p->combop = DLABEL; 136*1495Sbill p->labno = 0; 137*1495Sbill p->code = copy(line); 138*1495Sbill } 139*1495Sbill break; 140*1495Sbill 141*1495Sbill case LGEN: 142*1495Sbill if (*curlp!='L' && !locuse(curlp)) goto std; 143*1495Sbill op= &F77JSW; 144*1495Sbill case JBR: 145*1495Sbill if (op->opcode==T(JBR,RET) || op->opcode==T(JBR,RSB)) goto std; 146*1495Sbill case CBR: 147*1495Sbill case JMP: 148*1495Sbill case JSW: 149*1495Sbill case SOBGEQ: case SOBGTR: case AOBLEQ: case AOBLSS: case ACB: 150*1495Sbill p = alloc(sizeof first); 151*1495Sbill p->combop = op->opcode; p->code=0; cp1=curlp; 152*1495Sbill if ((!isdigit(*cp1) || 0==(p->labno=locuse(cp1))) && 153*1495Sbill (*cp1!='L' || 0==(p->labno = getnum(cp1+1)))) {/* jbs, etc.? */ 154*1495Sbill while (*cp1++); while (*--cp1!=',' && cp1!=curlp); 155*1495Sbill if (cp1==curlp || 156*1495Sbill (!isdigit(*++cp1) || 0==(p->labno=locuse(cp1))) && 157*1495Sbill (*cp1!='L' || 0==(p->labno=getnum(cp1+1)))) 158*1495Sbill p->labno = 0; 159*1495Sbill else *--cp1=0; 160*1495Sbill p->code = copy(curlp); 161*1495Sbill } 162*1495Sbill if (isn<=p->labno) isn=1+p->labno; 163*1495Sbill break; 164*1495Sbill 165*1495Sbill case MOVA: 166*1495Sbill p=alloc(sizeof first); 167*1495Sbill p->combop=op->opcode; p->code=0; cp1=curlp+1; 168*1495Sbill if (cp1[-1]=='L' || isdigit(cp1[-1])) { 169*1495Sbill while (*cp1++!=','); *--cp1=0; 170*1495Sbill if (0!=(p->labno=locuse(curlp)) || 171*1495Sbill 0!=(p->labno=getnum(curlp+1))) p->code=copy(cp1+1); 172*1495Sbill else {*cp1=','; p->code=copy(curlp);} 173*1495Sbill } else {p->code=copy(--cp1); p->labno=0;} 174*1495Sbill break; 175*1495Sbill 176*1495Sbill case SET: 177*1495Sbill case COMM: 178*1495Sbill case LCOMM: 179*1495Sbill printf("%s\n",line); goto top; 180*1495Sbill 181*1495Sbill case BSS: 182*1495Sbill case DATA: 183*1495Sbill for (;;) { 184*1495Sbill printf("%s%c",line,(op->opcode==LABEL ? ':' : '\n')); 185*1495Sbill if (op->opcode==TEXT) goto top; 186*1495Sbill if (END==(op=getline())->opcode) {/* dangling .data is bad for you */ 187*1495Sbill printf(".text\n"); 188*1495Sbill break; 189*1495Sbill } 190*1495Sbill } 191*1495Sbill 192*1495Sbill std: 193*1495Sbill default: 194*1495Sbill p = alloc(sizeof first); 195*1495Sbill p->combop = op->opcode; 196*1495Sbill p->labno = 0; 197*1495Sbill p->code = copy(curlp); 198*1495Sbill break; 199*1495Sbill 200*1495Sbill } 201*1495Sbill p->forw = 0; 202*1495Sbill p->back = lastp; 203*1495Sbill p->pop = op; 204*1495Sbill lastp->forw = p; 205*1495Sbill lastp = p; 206*1495Sbill p->ref = 0; 207*1495Sbill if (p->op==CASE) { 208*1495Sbill char *lp; int ncase; 209*1495Sbill lp=curlp; while (*lp++); while (*--lp!='$'); ncase=getnum(lp+1); 210*1495Sbill if (LABEL!=(getline())->opcode) abort(-2); 211*1495Sbill do { 212*1495Sbill if (WGEN!=(getline())->opcode) abort(-3); 213*1495Sbill p = alloc(sizeof first); p->combop = JSW; p->code = 0; 214*1495Sbill lp=curlp; while(*lp++!='-'); *--lp=0; p->labno=getnum(curlp+1); 215*1495Sbill if (isn<=p->labno) isn=1+p->labno; 216*1495Sbill p->forw = 0; p->back = lastp; lastp->forw = p; lastp = p; 217*1495Sbill p->ref = 0; p->pop=0; 218*1495Sbill } while (--ncase>=0); 219*1495Sbill } 220*1495Sbill if (op->opcode==EROU) 221*1495Sbill return(1); 222*1495Sbill if (op->opcode==END) 223*1495Sbill return(0); 224*1495Sbill } 225*1495Sbill } 226*1495Sbill 227*1495Sbill struct optab * 228*1495Sbill getline() 229*1495Sbill { 230*1495Sbill register char *lp; 231*1495Sbill register c; 232*1495Sbill static struct optab OPLABEL={"",LABEL}; 233*1495Sbill static struct optab OPEND={"",END}; 234*1495Sbill 235*1495Sbill lp = line; 236*1495Sbill while (EOF!=(c=getchar()) && isspace(c)); 237*1495Sbill while (EOF!=c) { 238*1495Sbill if (c==':') { 239*1495Sbill *lp++ = 0; 240*1495Sbill return(&OPLABEL); 241*1495Sbill } 242*1495Sbill if (c=='\n') { 243*1495Sbill *lp++ = 0; 244*1495Sbill return(oplook()); 245*1495Sbill } 246*1495Sbill *lp++ = c; 247*1495Sbill c = getchar(); 248*1495Sbill } 249*1495Sbill *lp++ = 0; 250*1495Sbill return(&OPEND); 251*1495Sbill } 252*1495Sbill 253*1495Sbill long 254*1495Sbill getnum(p) 255*1495Sbill register char *p; 256*1495Sbill { 257*1495Sbill register c; int neg; register long n; 258*1495Sbill 259*1495Sbill n = 0; neg=0; if (*p=='-') {++neg; ++p;} 260*1495Sbill while (isdigit(c = *p++)) { 261*1495Sbill c -= '0'; n *= 10; if (neg) n -= c; else n += c; 262*1495Sbill } 263*1495Sbill if (*--p != 0) 264*1495Sbill return(0); 265*1495Sbill return(n); 266*1495Sbill } 267*1495Sbill 268*1495Sbill locuse(p) 269*1495Sbill register char *p; 270*1495Sbill { 271*1495Sbill register c; int neg; register long n; 272*1495Sbill 273*1495Sbill if (!isdigit(p[0]) || p[1] != 'f' && p[1] != 'b' || p[2]) return(0); 274*1495Sbill return (lgensym[p[0] - '0'] - (p[1] == 'b')); 275*1495Sbill } 276*1495Sbill 277*1495Sbill locdef(p) 278*1495Sbill register char *p; 279*1495Sbill { 280*1495Sbill 281*1495Sbill if (!isdigit(p[0]) || p[1]) return(0); 282*1495Sbill return (lgensym[p[0] - '0']++); 283*1495Sbill } 284*1495Sbill 285*1495Sbill output() 286*1495Sbill { 287*1495Sbill register struct node *t; 288*1495Sbill int casebas; 289*1495Sbill 290*1495Sbill t = &first; 291*1495Sbill while (t = t->forw) switch (t->op) { 292*1495Sbill 293*1495Sbill case END: 294*1495Sbill fflush(stdout); 295*1495Sbill return; 296*1495Sbill 297*1495Sbill case LABEL: 298*1495Sbill printf("L%d:", t->labno); 299*1495Sbill continue; 300*1495Sbill 301*1495Sbill case DLABEL: 302*1495Sbill printf("%s:", t->code); 303*1495Sbill continue; 304*1495Sbill 305*1495Sbill case CASE: 306*1495Sbill casebas=0; 307*1495Sbill 308*1495Sbill default: std: 309*1495Sbill if (t->pop==0) {/* must find it */ 310*1495Sbill register struct optab *p; 311*1495Sbill for (p=optab; p->opstring[0]; ++p) 312*1495Sbill if (p->opcode==t->combop) {t->pop=p; break;} 313*1495Sbill } 314*1495Sbill printf("%s", t->pop->opstring); 315*1495Sbill if (t->code) printf("\t%s", t->code); 316*1495Sbill if (t->labno!=0) printf("%cL%d\n", 317*1495Sbill (t->code ? ',' : '\t'), 318*1495Sbill t->labno); 319*1495Sbill else printf("\n"); 320*1495Sbill continue; 321*1495Sbill 322*1495Sbill case MOVA: 323*1495Sbill if (t->labno==0) goto std; 324*1495Sbill printf("mova%c\tL%d,%s\n","bwlq"[t->subop-BYTE],t->labno,t->code); 325*1495Sbill continue; 326*1495Sbill 327*1495Sbill case JSW: 328*1495Sbill if (t->subop!=0) {/* F77JSW */ 329*1495Sbill printf(".long\tL%d\n",t->labno); continue; 330*1495Sbill } 331*1495Sbill if (casebas==0) printf("L%d:\n",casebas=isn++); 332*1495Sbill printf(".word L%d-L%d\n", t->labno, casebas); 333*1495Sbill continue; 334*1495Sbill 335*1495Sbill } 336*1495Sbill } 337*1495Sbill 338*1495Sbill char * 339*1495Sbill copy(ap) 340*1495Sbill char *ap; 341*1495Sbill { 342*1495Sbill register char *p, *np; 343*1495Sbill char *onp; 344*1495Sbill register n; 345*1495Sbill int na; 346*1495Sbill 347*1495Sbill na = nargs(); 348*1495Sbill p = ap; 349*1495Sbill n = 0; 350*1495Sbill if (*p==0) 351*1495Sbill return(0); 352*1495Sbill do 353*1495Sbill n++; 354*1495Sbill while (*p++); 355*1495Sbill if (na>1) { 356*1495Sbill p = (&ap)[1]; 357*1495Sbill while (*p++) 358*1495Sbill n++; 359*1495Sbill } 360*1495Sbill onp = np = alloc(n); 361*1495Sbill p = ap; 362*1495Sbill while (*np++ = *p++); 363*1495Sbill if (na>1) { 364*1495Sbill p = (&ap)[1]; 365*1495Sbill np--; 366*1495Sbill while (*np++ = *p++); 367*1495Sbill } 368*1495Sbill return(onp); 369*1495Sbill } 370*1495Sbill 371*1495Sbill #define OPHS 560 372*1495Sbill struct optab *ophash[OPHS]; 373*1495Sbill 374*1495Sbill opsetup() 375*1495Sbill { 376*1495Sbill register struct optab *optp, **ophp; 377*1495Sbill register int i,t; 378*1495Sbill 379*1495Sbill for(i=NREG+5;--i>=0;) regs[i]=alloc(20); 380*1495Sbill for (optp = optab; optp->opstring[0]; optp++) { 381*1495Sbill t=7; i=0; while (--t>=0) i+= i+optp->opstring[t]; 382*1495Sbill ophp = &ophash[i % OPHS]; 383*1495Sbill while (*ophp++) { 384*1495Sbill /* fprintf(stderr,"\ncollision: %d %s %s", 385*1495Sbill /* ophp-1-ophash,optp->opstring,(*(ophp-1))->opstring); 386*1495Sbill */ 387*1495Sbill if (ophp > &ophash[OPHS]) 388*1495Sbill ophp = ophash; 389*1495Sbill } 390*1495Sbill *--ophp = optp; 391*1495Sbill } 392*1495Sbill } 393*1495Sbill 394*1495Sbill struct optab * 395*1495Sbill oplook() 396*1495Sbill { 397*1495Sbill register struct optab *optp,**ophp; 398*1495Sbill register char *p,*p2; 399*1495Sbill register int t; 400*1495Sbill char tempop[20]; 401*1495Sbill static struct optab OPNULL={"",0}; 402*1495Sbill 403*1495Sbill for (p=line, p2=tempop; *p && !isspace(*p); *p2++= *p++); *p2=0; p2=p; 404*1495Sbill while (isspace(*p2)) ++p2; curlp=p2; 405*1495Sbill t=0; while(--p>=line) t += t+*p; ophp = &ophash[t % OPHS]; 406*1495Sbill while (optp = *ophp) { 407*1495Sbill if (equstr(tempop,optp->opstring)) return(optp); 408*1495Sbill if ((++ophp) >= &ophash[OPHS]) ophp = ophash; 409*1495Sbill } 410*1495Sbill curlp = line; 411*1495Sbill return(&OPNULL); 412*1495Sbill } 413*1495Sbill 414*1495Sbill refcount() 415*1495Sbill { 416*1495Sbill register struct node *p, *lp; 417*1495Sbill struct node *labhash[LABHS]; 418*1495Sbill register struct node **hp; 419*1495Sbill 420*1495Sbill for (hp = labhash; hp < &labhash[LABHS];) 421*1495Sbill *hp++ = 0; 422*1495Sbill for (p = first.forw; p!=0; p = p->forw) 423*1495Sbill if (p->op==LABEL) { 424*1495Sbill labhash[p->labno % LABHS] = p; 425*1495Sbill p->refc = 0; 426*1495Sbill } 427*1495Sbill for (p = first.forw; p!=0; p = p->forw) { 428*1495Sbill if (p->combop==JBR || p->op==CBR || p->op==JSW || p->op==JMP 429*1495Sbill || p->op==SOBGEQ || p->op==SOBGTR || p->op==AOBLEQ || p->op==AOBLSS 430*1495Sbill || p->op==ACB || (p->op==MOVA && p->labno!=0)) { 431*1495Sbill p->ref = 0; 432*1495Sbill lp = labhash[p->labno % LABHS]; 433*1495Sbill if (lp==0 || p->labno!=lp->labno) 434*1495Sbill for (lp = first.forw; lp!=0; lp = lp->forw) { 435*1495Sbill if (lp->op==LABEL && p->labno==lp->labno) 436*1495Sbill break; 437*1495Sbill } 438*1495Sbill if (lp) { 439*1495Sbill hp = nonlab(lp)->back; 440*1495Sbill if (hp!=lp) { 441*1495Sbill p->labno = hp->labno; 442*1495Sbill lp = hp; 443*1495Sbill } 444*1495Sbill p->ref = lp; 445*1495Sbill lp->refc++; 446*1495Sbill } 447*1495Sbill } 448*1495Sbill } 449*1495Sbill for (p = first.forw; p!=0; p = p->forw) 450*1495Sbill if (p->op==LABEL && p->refc==0 451*1495Sbill && (lp = nonlab(p))->op && lp->op!=JSW) 452*1495Sbill decref(p); 453*1495Sbill } 454*1495Sbill 455*1495Sbill iterate() 456*1495Sbill { 457*1495Sbill register struct node *p, *rp, *p1; 458*1495Sbill 459*1495Sbill nchange = 0; 460*1495Sbill for (p = first.forw; p!=0; p = p->forw) { 461*1495Sbill if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) { 462*1495Sbill rp = nonlab(p->ref); 463*1495Sbill if (rp->op==JBR && rp->labno && p->labno!=rp->labno) { 464*1495Sbill nbrbr++; 465*1495Sbill p->labno = rp->labno; 466*1495Sbill decref(p->ref); 467*1495Sbill rp->ref->refc++; 468*1495Sbill p->ref = rp->ref; 469*1495Sbill nchange++; 470*1495Sbill } 471*1495Sbill } 472*1495Sbill #ifndef COPYCODE 473*1495Sbill if (p->op==CBR && (p1 = p->forw)->combop==JBR) {/* combop: RET problems */ 474*1495Sbill #else 475*1495Sbill if (p->op==CBR && (p1 = p->forw)->combop==JBR && 476*1495Sbill p->ref) {/* combop: RET problems */ 477*1495Sbill #endif 478*1495Sbill rp = p->ref; 479*1495Sbill do 480*1495Sbill rp = rp->back; 481*1495Sbill while (rp->op==LABEL); 482*1495Sbill if (rp==p1) { 483*1495Sbill decref(p->ref); 484*1495Sbill p->ref = p1->ref; 485*1495Sbill p->labno = p1->labno; 486*1495Sbill #ifdef COPYCODE 487*1495Sbill if (p->labno == 0) 488*1495Sbill p->code = p1->code; 489*1495Sbill #endif 490*1495Sbill p1->forw->back = p; 491*1495Sbill p->forw = p1->forw; 492*1495Sbill p->subop = revbr[p->subop]; 493*1495Sbill p->pop=0; 494*1495Sbill nchange++; 495*1495Sbill nskip++; 496*1495Sbill } 497*1495Sbill } 498*1495Sbill if (p->op==JBR || p->op==JMP) { 499*1495Sbill while (p->forw && p->forw->op!=LABEL && p->forw->op!=DLABEL 500*1495Sbill && p->forw->op!=EROU && p->forw->op!=END 501*1495Sbill && p->forw->op!=ALIGN 502*1495Sbill && p->forw->op!=0 && p->forw->op!=DATA) { 503*1495Sbill nchange++; 504*1495Sbill iaftbr++; 505*1495Sbill if (p->forw->ref) 506*1495Sbill decref(p->forw->ref); 507*1495Sbill p->forw = p->forw->forw; 508*1495Sbill p->forw->back = p; 509*1495Sbill } 510*1495Sbill rp = p->forw; 511*1495Sbill while (rp && rp->op==LABEL) { 512*1495Sbill if (p->ref == rp) { 513*1495Sbill p->back->forw = p->forw; 514*1495Sbill p->forw->back = p->back; 515*1495Sbill p = p->back; 516*1495Sbill decref(rp); 517*1495Sbill nchange++; 518*1495Sbill njp1++; 519*1495Sbill break; 520*1495Sbill } 521*1495Sbill rp = rp->forw; 522*1495Sbill } 523*1495Sbill xjump(p); 524*1495Sbill p = codemove(p); 525*1495Sbill } 526*1495Sbill } 527*1495Sbill } 528*1495Sbill 529*1495Sbill xjump(p1) 530*1495Sbill register struct node *p1; 531*1495Sbill { 532*1495Sbill register struct node *p2, *p3; 533*1495Sbill int nxj; 534*1495Sbill 535*1495Sbill nxj = 0; 536*1495Sbill if ((p2 = p1->ref)==0) 537*1495Sbill return(0); 538*1495Sbill for (;;) { 539*1495Sbill while ((p1 = p1->back) && p1->op==LABEL); 540*1495Sbill while ((p2 = p2->back) && p2->op==LABEL); 541*1495Sbill if (!equop(p1, p2) || p1==p2) 542*1495Sbill return(nxj); 543*1495Sbill p3 = insertl(p2); 544*1495Sbill p1->combop = JBR; 545*1495Sbill p1->pop=0; 546*1495Sbill p1->ref = p3; 547*1495Sbill p1->labno = p3->labno; 548*1495Sbill p1->code = 0; 549*1495Sbill nxj++; 550*1495Sbill nxjump++; 551*1495Sbill nchange++; 552*1495Sbill } 553*1495Sbill } 554*1495Sbill 555*1495Sbill struct node * 556*1495Sbill insertl(op) 557*1495Sbill register struct node *op; 558*1495Sbill { 559*1495Sbill register struct node *lp; 560*1495Sbill 561*1495Sbill if (op->op == LABEL) { 562*1495Sbill op->refc++; 563*1495Sbill return(op); 564*1495Sbill } 565*1495Sbill if (op->back->op == LABEL) { 566*1495Sbill op = op->back; 567*1495Sbill op->refc++; 568*1495Sbill return(op); 569*1495Sbill } 570*1495Sbill lp = alloc(sizeof first); 571*1495Sbill lp->combop = LABEL; 572*1495Sbill lp->labno = isn++; 573*1495Sbill lp->ref = 0; 574*1495Sbill lp->code = 0; 575*1495Sbill lp->refc = 1; 576*1495Sbill lp->back = op->back; 577*1495Sbill lp->forw = op; 578*1495Sbill op->back->forw = lp; 579*1495Sbill op->back = lp; 580*1495Sbill return(lp); 581*1495Sbill } 582*1495Sbill 583*1495Sbill struct node * 584*1495Sbill codemove(ap) 585*1495Sbill struct node *ap; 586*1495Sbill { 587*1495Sbill register struct node *p1, *p2, *p3; 588*1495Sbill struct node *t, *tl; 589*1495Sbill int n; 590*1495Sbill 591*1495Sbill p1 = ap; 592*1495Sbill /* last clause to avoid infinite loop on partial compiler droppings: 593*1495Sbill L183: jbr L179 594*1495Sbill L191: jbr L179 595*1495Sbill casel r0,$0,$1 596*1495Sbill L193: .word L183-L193 597*1495Sbill .word L191-L193 598*1495Sbill L179: ret 599*1495Sbill */ 600*1495Sbill if (p1->op!=JBR || (p2 = p1->ref)==0 || p2==p1->forw) 601*1495Sbill return(p1); 602*1495Sbill while (p2->op == LABEL) 603*1495Sbill if ((p2 = p2->back) == 0) 604*1495Sbill return(p1); 605*1495Sbill if (p2->op!=JBR && p2->op!=JMP) 606*1495Sbill goto ivloop; 607*1495Sbill p2 = p2->forw; 608*1495Sbill p3 = p1->ref; 609*1495Sbill while (p3) { 610*1495Sbill if (p3->op==JBR || p3->op==JMP) { 611*1495Sbill if (p1==p3) 612*1495Sbill return(p1); 613*1495Sbill ncmot++; 614*1495Sbill nchange++; 615*1495Sbill p1->back->forw = p2; 616*1495Sbill p1->forw->back = p3; 617*1495Sbill p2->back->forw = p3->forw; 618*1495Sbill p3->forw->back = p2->back; 619*1495Sbill p2->back = p1->back; 620*1495Sbill p3->forw = p1->forw; 621*1495Sbill decref(p1->ref); 622*1495Sbill return(p2); 623*1495Sbill } else 624*1495Sbill p3 = p3->forw; 625*1495Sbill } 626*1495Sbill return(p1); 627*1495Sbill ivloop: 628*1495Sbill if (p1->forw->op!=LABEL) 629*1495Sbill return(p1); 630*1495Sbill p3 = p2 = p2->forw; 631*1495Sbill n = 16; 632*1495Sbill do { 633*1495Sbill if ((p3 = p3->forw) == 0 || p3==p1 || --n==0) 634*1495Sbill return(p1); 635*1495Sbill } while (p3->op!=CBR || p3->labno!=p1->forw->labno); 636*1495Sbill do 637*1495Sbill if ((p1 = p1->back) == 0) 638*1495Sbill return(ap); 639*1495Sbill while (p1!=p3); 640*1495Sbill p1 = ap; 641*1495Sbill tl = insertl(p1); 642*1495Sbill p3->subop = revbr[p3->subop]; 643*1495Sbill p3->pop=0; 644*1495Sbill decref(p3->ref); 645*1495Sbill p2->back->forw = p1; 646*1495Sbill p3->forw->back = p1; 647*1495Sbill p1->back->forw = p2; 648*1495Sbill p1->forw->back = p3; 649*1495Sbill t = p1->back; 650*1495Sbill p1->back = p2->back; 651*1495Sbill p2->back = t; 652*1495Sbill t = p1->forw; 653*1495Sbill p1->forw = p3->forw; 654*1495Sbill p3->forw = t; 655*1495Sbill p2 = insertl(p1->forw); 656*1495Sbill p3->labno = p2->labno; 657*1495Sbill #ifdef COPYCODE 658*1495Sbill if (p3->labno == 0) 659*1495Sbill p3->code = p2->code; 660*1495Sbill #endif 661*1495Sbill p3->ref = p2; 662*1495Sbill decref(tl); 663*1495Sbill if (tl->refc<=0) 664*1495Sbill nrlab--; 665*1495Sbill loopiv++; 666*1495Sbill nchange++; 667*1495Sbill return(p3); 668*1495Sbill } 669*1495Sbill 670*1495Sbill comjump() 671*1495Sbill { 672*1495Sbill register struct node *p1, *p2, *p3; 673*1495Sbill 674*1495Sbill for (p1 = first.forw; p1!=0; p1 = p1->forw) 675*1495Sbill if (p1->op==JBR && ((p2 = p1->ref) && p2->refc > 1 676*1495Sbill || p1->subop==RET || p1->subop==RSB)) 677*1495Sbill for (p3 = p1->forw; p3!=0; p3 = p3->forw) 678*1495Sbill if (p3->op==JBR && p3->ref == p2) 679*1495Sbill backjmp(p1, p3); 680*1495Sbill } 681*1495Sbill 682*1495Sbill backjmp(ap1, ap2) 683*1495Sbill struct node *ap1, *ap2; 684*1495Sbill { 685*1495Sbill register struct node *p1, *p2, *p3; 686*1495Sbill 687*1495Sbill p1 = ap1; 688*1495Sbill p2 = ap2; 689*1495Sbill for(;;) { 690*1495Sbill while ((p1 = p1->back) && p1->op==LABEL); 691*1495Sbill p2 = p2->back; 692*1495Sbill if (equop(p1, p2)) { 693*1495Sbill p3 = insertl(p1); 694*1495Sbill p2->back->forw = p2->forw; 695*1495Sbill p2->forw->back = p2->back; 696*1495Sbill p2 = p2->forw; 697*1495Sbill decref(p2->ref); 698*1495Sbill p2->combop = JBR; /* to handle RET */ 699*1495Sbill p2->pop=0; 700*1495Sbill p2->labno = p3->labno; 701*1495Sbill #ifdef COPYCODE 702*1495Sbill p2->code = 0; 703*1495Sbill #endif 704*1495Sbill p2->ref = p3; 705*1495Sbill nchange++; 706*1495Sbill ncomj++; 707*1495Sbill } else 708*1495Sbill return; 709*1495Sbill } 710*1495Sbill } 711