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