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