Annotation of researchv10no/cmd/c2/c20.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.