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