1: #ifndef lint
   2: static  char sccsid[] = "@(#)c20.c	4.10 (Berkeley) 8/22/85";
   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, *np;
 392:     char *onp;
 393:     register n;
 394:     int na;
 395: 
 396:     na = nargs();
 397:     p = ap;
 398:     n = 0;
 399:     if (*p==0)
 400:         return(0);
 401:     do
 402:         n++;
 403:     while (*p++);
 404:     if (na>1) {
 405:         p = (&ap)[1];
 406:         while (*p++)
 407:             n++;
 408:     }
 409:     onp = np = (char *) alloc(n);
 410:     p = ap;
 411:     while (*np++ = *p++);
 412:     if (na>1) {
 413:         p = (&ap)[1];
 414:         np--;
 415:         while (*np++ = *p++);
 416:     }
 417:     return(onp);
 418: }
 419: 
 420: #define OPHS    560
 421: struct optab *ophash[OPHS];
 422: 
 423: opsetup()
 424: {
 425:     register struct optab *optp, **ophp;
 426:     register int i,t;
 427: 
 428:     for(i=NREG+5;--i>=0;) regs[i] = malloc(C2_ASIZE);
 429:     for (optp = optab; optp->opstring[0]; optp++) {
 430:         t=7; i=0; while (--t>=0) i+= i+optp->opstring[t];
 431:         ophp = &ophash[i % OPHS];
 432:         while (*ophp++) {
 433: /*			fprintf(stderr,"\ncollision: %d %s %s",
 434: /*				ophp-1-ophash,optp->opstring,(*(ophp-1))->opstring);
 435: */
 436:             if (ophp >= &ophash[OPHS])
 437:                 ophp = ophash;
 438:         }
 439:         *--ophp = optp;
 440:     }
 441: }
 442: 
 443: struct optab *
 444: oplook()
 445: {
 446:     register struct optab *optp,**ophp;
 447:     register char *p,*p2;
 448:     register int t;
 449:     char tempop[20];
 450:     static struct optab OPNULL={"",0};
 451: 
 452:     for (p=line, p2=tempop; *p && !isspace(*p); *p2++= *p++); *p2=0; p2=p;
 453:     while (isspace(*p2)) ++p2; curlp=p2;
 454:     t=0; while(--p>=line) t += t+*p; ophp = &ophash[t % OPHS];
 455:     while (optp = *ophp) {
 456:         if (equstr(tempop,optp->opstring)) return(optp);
 457:         if ((++ophp) >= &ophash[OPHS]) ophp = ophash;
 458:     }
 459:     curlp = line;
 460:     return(&OPNULL);
 461: }
 462: 
 463: refcount()
 464: {
 465:     register struct node *p, *lp, *tp;
 466:     struct node *labhash[LABHS];
 467:     register struct node **hp;
 468: 
 469:     for (hp = labhash; hp < &labhash[LABHS];)
 470:         *hp++ = 0;
 471:     for (p = first.forw; p!=0; p = p->forw)
 472:         if (p->op==LABEL) {
 473:             labhash[p->labno % LABHS] = p;
 474:             p->refc = 0;
 475:         }
 476:     for (p = first.forw; p!=0; p = p->forw) {
 477:         if (p->combop==JBR || p->op==CBR || p->op==JSW || p->op==JMP
 478:           || p->op==SOBGEQ || p->op==SOBGTR || p->op==AOBLEQ || p->op==AOBLSS
 479:           || p->op==ACB || (p->op==MOVA && p->labno!=0)) {
 480:             p->ref = 0;
 481:             lp = labhash[p->labno % LABHS];
 482:             if (lp==0 || p->labno!=lp->labno)
 483:             for (lp = first.forw; lp!=0; lp = lp->forw) {
 484:                 if (lp->op==LABEL && p->labno==lp->labno)
 485:                     break;
 486:             }
 487:             if (lp) {
 488:                 tp = nonlab(lp)->back;
 489:                 if (tp!=lp) {
 490:                     p->labno = tp->labno;
 491:                     lp = tp;
 492:                 }
 493:                 p->ref = lp;
 494:                 lp->refc++;
 495:             }
 496:         }
 497:     }
 498:     for (p = first.forw; p!=0; p = p->forw)
 499:         if (p->op==LABEL && p->refc==0
 500:          && (lp = nonlab(p))->op && lp->op!=JSW)
 501:             decref(p);
 502: }
 503: 
 504: iterate()
 505: {
 506:     register struct node *p, *rp, *p1;
 507: 
 508:     nchange = 0;
 509:     for (p = first.forw; p!=0; p = p->forw) {
 510:         if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) {
 511:             rp = nonlab(p->ref);
 512:             if (rp->op==JBR && rp->labno && p->labno!=rp->labno) {
 513:                 nbrbr++;
 514:                 p->labno = rp->labno;
 515:                 decref(p->ref);
 516:                 rp->ref->refc++;
 517:                 p->ref = rp->ref;
 518:                 nchange++;
 519:             }
 520:         }
 521: #ifndef COPYCODE
 522:         if (p->op==CBR && (p1 = p->forw)->combop==JBR) {/* combop: RET problems */
 523: #else
 524:         if (p->op==CBR && (p1 = p->forw)->combop==JBR &&
 525:             p->ref) {/* combop: RET problems */
 526: #endif
 527:             rp = p->ref;
 528:             do
 529:                 rp = rp->back;
 530:             while (rp->op==LABEL);
 531:             if (rp==p1) {
 532:                 decref(p->ref);
 533:                 p->ref = p1->ref;
 534:                 p->labno = p1->labno;
 535: #ifdef COPYCODE
 536:                 if (p->labno == 0)
 537:                     p->code = p1->code;
 538: #endif
 539:                 p1->forw->back = p;
 540:                 p->forw = p1->forw;
 541:                 p->subop = revbr[p->subop];
 542:                 p->pop=0;
 543:                 nchange++;
 544:                 nskip++;
 545:             }
 546:         }
 547:         if (p->op==JBR || p->op==JMP) {
 548:             while (p->forw && p->forw->op!=LABEL && p->forw->op!=DLABEL
 549:                 && p->forw->op!=EROU && p->forw->op!=END
 550:                 && p->forw->op!=ALIGN
 551:                 && p->forw->op!=0 && p->forw->op!=DATA) {
 552:                 nchange++;
 553:                 iaftbr++;
 554:                 if (p->forw->ref)
 555:                     decref(p->forw->ref);
 556:                 p->forw = p->forw->forw;
 557:                 p->forw->back = p;
 558:             }
 559:             rp = p->forw;
 560:             while (rp && rp->op==LABEL) {
 561:                 if (p->ref == rp) {
 562:                     p->back->forw = p->forw;
 563:                     p->forw->back = p->back;
 564:                     p = p->back;
 565:                     decref(rp);
 566:                     nchange++;
 567:                     njp1++;
 568:                     break;
 569:                 }
 570:                 rp = rp->forw;
 571:             }
 572:             xjump(p);
 573:             p = codemove(p);
 574:         }
 575:     }
 576: }
 577: 
 578: xjump(p1)
 579: register struct node *p1;
 580: {
 581:     register struct node *p2, *p3;
 582: 
 583:     if ((p2 = p1->ref)==0)
 584:         return;
 585:     for (;;) {
 586:         while ((p1 = p1->back) && p1->op==LABEL);
 587:         while ((p2 = p2->back) && p2->op==LABEL);
 588:         if (!equop(p1, p2) || p1==p2)
 589:             return;
 590:         p3 = insertl(p2);
 591:         p1->combop = JBR;
 592:         p1->pop=0;
 593:         p1->ref = p3;
 594:         p1->labno = p3->labno;
 595:         p1->code = 0;
 596:         nxjump++;
 597:         nchange++;
 598:     }
 599: }
 600: 
 601: struct node *
 602: insertl(np)
 603: register struct node *np;
 604: {
 605:     register struct node *lp;
 606: 
 607:     if (np->op == LABEL) {
 608:         np->refc++;
 609:         return(np);
 610:     }
 611:     if (np->back->op == LABEL) {
 612:         np = np->back;
 613:         np->refc++;
 614:         return(np);
 615:     }
 616:     lp = alloc(sizeof first);
 617:     lp->combop = LABEL;
 618:     lp->labno = isn++;
 619:     lp->ref = 0;
 620:     lp->code = 0;
 621:     lp->refc = 1;
 622:     lp->back = np->back;
 623:     lp->forw = np;
 624:     np->back->forw = lp;
 625:     np->back = lp;
 626:     return(lp);
 627: }
 628: 
 629: struct node *
 630: codemove(ap)
 631: struct node *ap;
 632: {
 633:     register struct node *p1, *p2, *p3;
 634:     struct node *t, *tl;
 635:     int n;
 636: 
 637:     p1 = ap;
 638: /* last clause to avoid infinite loop on partial compiler droppings:
 639: 	L183:	jbr L179
 640: 	L191:	jbr L179
 641: 			casel r0,$0,$1
 642: 	L193:	.word L183-L193
 643: 			.word L191-L193
 644: 	L179:	ret
 645: */
 646:     if (p1->op!=JBR || (p2 = p1->ref)==0 || p2==p1->forw)
 647:         return(p1);
 648:     while (p2->op == LABEL)
 649:         if ((p2 = p2->back) == 0)
 650:             return(p1);
 651:     if (p2->op!=JBR && p2->op!=JMP)
 652:         goto ivloop;
 653:     p2 = p2->forw;
 654:     p3 = p1->ref;
 655:     while (p3) {
 656:         if (p3->op==JBR || p3->op==JMP) {
 657:             if (p1==p3)
 658:                 return(p1);
 659:             ncmot++;
 660:             nchange++;
 661:             p1->back->forw = p2;
 662:             p1->forw->back = p3;
 663:             p2->back->forw = p3->forw;
 664:             p3->forw->back = p2->back;
 665:             p2->back = p1->back;
 666:             p3->forw = p1->forw;
 667:             decref(p1->ref);
 668:             return(p2);
 669:         } else
 670:             p3 = p3->forw;
 671:     }
 672:     return(p1);
 673: ivloop:
 674:     if (p1->forw->op!=LABEL)
 675:         return(p1);
 676:     p3 = p2 = p2->forw;
 677:     n = 16;
 678:     do {
 679:         if ((p3 = p3->forw) == 0 || p3==p1 || --n==0)
 680:             return(p1);
 681:     } while (p3->op!=CBR || p3->labno!=p1->forw->labno);
 682:     do
 683:         if ((p1 = p1->back) == 0)
 684:             return(ap);
 685:     while (p1!=p3);
 686:     p1 = ap;
 687:     tl = insertl(p1);
 688:     p3->subop = revbr[p3->subop];
 689:     p3->pop=0;
 690:     decref(p3->ref);
 691:     p2->back->forw = p1;
 692:     p3->forw->back = p1;
 693:     p1->back->forw = p2;
 694:     p1->forw->back = p3;
 695:     t = p1->back;
 696:     p1->back = p2->back;
 697:     p2->back = t;
 698:     t = p1->forw;
 699:     p1->forw = p3->forw;
 700:     p3->forw = t;
 701:     p2 = insertl(p1->forw);
 702:     p3->labno = p2->labno;
 703: #ifdef COPYCODE
 704:     if (p3->labno == 0)
 705:         p3->code = p2->code;
 706: #endif
 707:     p3->ref = p2;
 708:     decref(tl);
 709:     if (tl->refc<=0)
 710:         nrlab--;
 711:     loopiv++;
 712:     nchange++;
 713:     return(p3);
 714: }
 715: 
 716: comjump()
 717: {
 718:     register struct node *p1, *p2, *p3;
 719: 
 720:     for (p1 = first.forw; p1!=0; p1 = p1->forw)
 721:         if (p1->op==JBR && ((p2 = p1->ref) && p2->refc > 1
 722:                 || p1->subop==RET || p1->subop==RSB))
 723:             for (p3 = p1->forw; p3!=0; p3 = p3->forw)
 724:                 if (p3->op==JBR && p3->ref == p2)
 725:                     backjmp(p1, p3);
 726: }
 727: 
 728: backjmp(ap1, ap2)
 729: struct node *ap1, *ap2;
 730: {
 731:     register struct node *p1, *p2, *p3;
 732: 
 733:     p1 = ap1;
 734:     p2 = ap2;
 735:     for(;;) {
 736:         while ((p1 = p1->back) && p1->op==LABEL);
 737:         p2 = p2->back;
 738:         if (equop(p1, p2)) {
 739:             p3 = insertl(p1);
 740:             p2->back->forw = p2->forw;
 741:             p2->forw->back = p2->back;
 742:             p2 = p2->forw;
 743:             decref(p2->ref);
 744:             p2->combop = JBR; /* to handle RET */
 745:             p2->pop=0;
 746:             p2->labno = p3->labno;
 747: #ifdef COPYCODE
 748:             p2->code = 0;
 749: #endif
 750:             p2->ref = p3;
 751:             nchange++;
 752:             ncomj++;
 753:         } else
 754:             return;
 755:     }
 756: }

Defined functions

backjmp defined in line 728; used 1 times
codemove defined in line 629; used 2 times
comjump defined in line 716; used 1 times
copy defined in line 387; used 12 times
getline defined in line 258; used 5 times
getnum defined in line 284; used 20 times
input defined in line 139; used 1 times
  • in line 96
insertl defined in line 601; used 7 times
iterate defined in line 504; used 1 times
locdef defined in line 306; used 1 times
locuse defined in line 299; used 4 times
main defined in line 67; never used
oplook defined in line 443; used 2 times
opsetup defined in line 423; used 1 times
  • in line 92
output defined in line 314; used 1 times
refcount defined in line 463; used 2 times
xalloc defined in line 40; used 3 times
xjump defined in line 578; used 1 times

Defined variables

currentb defined in line 16; used 5 times
fflag defined in line 23; used 2 times
firstr defined in line 15; used 1 times
  • in line 47
ioflag defined in line 22; used 1 times
  • in line 77
isn defined in line 25; used 8 times
lasta defined in line 18; used 8 times
lastr defined in line 19; used 3 times
lgensym defined in line 30; used 2 times
ncore defined in line 20; used 2 times
newa defined in line 17; used 6 times
ophash defined in line 421; used 6 times
sccsid defined in line 2; never used

Defined macros

ALLOCSIZE defined in line 33; used 3 times
OPHS defined in line 420; used 5 times
Last modified: 1985-08-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2825
Valid CSS Valid XHTML 1.0 Strict