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