Annotation of cci/usr/src/lib/c2/c22.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * C object code improver-- third part
        !             3:  */
        !             4: 
        !             5: #include "c2.h"
        !             6: #include <stdio.h>
        !             7: #include <ctype.h>
        !             8: 
        !             9: #define NUSE 6
        !            10: struct node *uses[NUSE]; /* for backwards flow analysis */
        !            11: char *lastrand; /* last operand of instruction */
        !            12: char *findcon();
        !            13: 
        !            14: ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
        !            15:        register int log;
        !            16:        if (n==0 || n&(n-1)) return(-1); log=0;
        !            17:        for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}
        !            18: }
        !            19: 
        !            20: equop(p1, p2)
        !            21: register struct node *p1, *p2;
        !            22: {
        !            23:        register char *cp1, *cp2;
        !            24: 
        !            25:        if (p1->op != p2->op || p1->subop != p2->subop)
        !            26:                return(0);
        !            27:        if (p1->op>0 && p1->op<MOV)
        !            28:                return(0);
        !            29:        if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
        !            30:        cp1 = p1->code;
        !            31:        cp2 = p2->code;
        !            32:        if (cp1==0 && cp2==0)
        !            33:                return(1);
        !            34:        if (cp1==0 || cp2==0)
        !            35:                return(0);
        !            36:        while (*cp1 == *cp2++)
        !            37:                if (*cp1++ == 0)
        !            38:                        return(1);
        !            39:        return(0);
        !            40: }
        !            41: 
        !            42: delnode(p) register struct node *p; {
        !            43:        p->back->forw = p->forw;
        !            44:        p->forw->back = p->back;
        !            45: }
        !            46: 
        !            47: decref(p)
        !            48: register struct node *p;
        !            49: {
        !            50:        if (p && --p->refc <= 0) {
        !            51:                nrlab++; nchange++;
        !            52:                delnode(p);
        !            53:        }
        !            54: }
        !            55: 
        !            56: struct node *
        !            57: nonlab(ap)
        !            58: struct node *ap;
        !            59: {
        !            60:        register struct node *p;
        !            61: 
        !            62:        p = ap;
        !            63:        while (p && p->op==LABEL)
        !            64:                p = p->forw;
        !            65:        return(p);
        !            66: }
        !            67: 
        !            68: clearuse() {
        !            69:        register struct node **i;
        !            70:        for (i=uses+NUSE; i>uses;) *--i=0;
        !            71: }
        !            72: 
        !            73: clearreg() {
        !            74:        register char **i;
        !            75:        for (i=regs+NREG; i>regs;){ **--i=0; **i=0; }
        !            76:        conloc[0] = 0; ccloc[0] = 0;
        !            77: }
        !            78: 
        !            79: savereg(ai, s, type)
        !            80: register char *s;
        !            81: {
        !            82:        register char *p, *sp;
        !            83: 
        !            84:        sp = p = regs[ai];
        !            85:        /* if any indexing, must be parameter or local */
        !            86:        /* indirection (as in "*-4(fp)") is ok, however */
        !            87:        *p++ = type;
        !            88:        while (*p++ = *s)
        !            89:                if (*s=='[' || *s++=='(' && *s!='f') {*sp = 0; return;}
        !            90: }
        !            91: 
        !            92: dest(s,type, ccflg)
        !            93: register char *s;
        !            94: {
        !            95:        register int i;
        !            96: 
        !            97:        if ((i = isreg(s)) >= 0) {
        !            98:                *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
        !            99:        }
        !           100:        for (i=NREG; --i>=0;)
        !           101:                if (regs[i][1]=='*' && equstr(s, regs[i]+2))
        !           102:                        *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
        !           103:        while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
        !           104:                *(short *)(regs[i]) = 0;
        !           105:        if (!natural(s)) {/* wild store, everything except constants vanishes */
        !           106:                for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
        !           107:                conloc[0] = 0; ccloc[0] = 0;
        !           108:        } else if(ccflg)setcc(s,type); /* natural destinations set condition codes */
        !           109: }
        !           110: 
        !           111: splitrand(p) struct node *p; {
        !           112: /* separate operands at commas, set up 'regs' and 'lastrand' */
        !           113: register char *p1, *p2; register char **preg;
        !           114: 
        !           115:        preg=regs+RT1;
        !           116:        if (p1=p->code) while (*p1) {
        !           117:                lastrand=p2= *preg++;
        !           118:                while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
        !           119:                *p2=0;
        !           120:        }
        !           121:        while (preg<(regs+RT1+5)) *(*preg++)=0;
        !           122: }
        !           123: 
        !           124: compat(have, want) {
        !           125:        register int hsrc, hdst;
        !           126: 
        !           127:        if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
        !           128:        hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
        !           129:        if (want>=QUAD) return(hdst==want && hsrc==want);
        !           130:        return(hsrc==want && hdst>=want && hdst<QUAD);
        !           131: }
        !           132: 
        !           133: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
        !           134: 
        !           135: findrand(as, type)
        !           136: char *as;
        !           137: {
        !           138:        register char **i;
        !           139:        for (i = regs+NREG; --i>=regs;) {
        !           140:                if (**i && equstr(*i+1, as) && compat(**i,type))
        !           141:                        return(i-regs);
        !           142:        }
        !           143:        return(-1);
        !           144: }
        !           145: 
        !           146: isreg(s)
        !           147: register char *s;
        !           148: {
        !           149:        if (*s++!='r' || !isdigit(*s++)) return(-1);
        !           150:        if (*s==0) return(*--s-'0');
        !           151:        if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
        !           152:        return(-1);
        !           153: }
        !           154: 
        !           155: /*
        !           156: check()
        !           157: {
        !           158:        register struct node *p, *lp;
        !           159: 
        !           160:        lp = &first;
        !           161:        for (p=first.forw; p!=0; p = p->forw) {
        !           162:                if (p->back != lp)
        !           163:                        abort(-1);
        !           164:                lp = p;
        !           165:        }
        !           166: }
        !           167: */
        !           168: 
        !           169: newcode(p) struct node *p; {
        !           170:        register char *p1,*p2,**preg;
        !           171: 
        !           172:        preg=regs+RT1; p2=line;
        !           173:        while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
        !           174:        *--p2=0;
        !           175:        p->code=copy(line);
        !           176: }
        !           177: 
        !           178: repladdr(p)
        !           179: struct node *p;
        !           180: {
        !           181:        register r;
        !           182:        register char *p1;
        !           183:        register char **preg;
        !           184:        register int nrepl;
        !           185: 
        !           186:        preg=regs+RT1; nrepl=0;
        !           187:        while (lastrand!=(p1= *preg++))
        !           188:                if (0<=(r=findrand(p1,p->subop))) {
        !           189:                        *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
        !           190:                        nchange++; nrepl++; nsaddr++;
        !           191:                }
        !           192:        if (nrepl) newcode(p);
        !           193: }
        !           194: 
        !           195: /* conditional branches which are never/always taken */
        !           196: reduncbr(p)
        !           197: register struct node *p;
        !           198: {
        !           199:        register struct node *p1;
        !           200:        register char *ap1, *ap2;
        !           201: 
        !           202:        p1 = p->back;
        !           203:        if (p1->op==CMP) {
        !           204:                splitrand(p1);
        !           205:                ap1 = findcon(regs[RT1], p1->subop);
        !           206:                ap2 = findcon(regs[RT2], p1->subop);
        !           207:        } else {
        !           208:                if(!ccloc[0])
        !           209:                        return;
        !           210:                ap1 = findcon(ccloc+1, ccloc[0]);
        !           211:                ap2 = "$0";
        !           212:        }
        !           213:        switch (compare(p->subop, ap1, ap2)) {
        !           214:        case 0:         /* branch never taken */
        !           215:                delnode(p);
        !           216:                nredunj++;
        !           217:                nchange++;
        !           218:                decref(p->ref);
        !           219:                if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
        !           220:                        delnode(p1);
        !           221:                        nrtst++;
        !           222:                }
        !           223:                break;
        !           224:        case 1:         /* branch always taken */
        !           225:                p->op = JBR;
        !           226:                p->subop = 0;
        !           227:                p->pop = 0;
        !           228:                nchange++;
        !           229:        }
        !           230: }
        !           231: 
        !           232: /* a jump to a redundant compare (start of a 'for') */
        !           233: redunbr(p)
        !           234: register struct node *p;
        !           235: {
        !           236:        register struct node *p1;
        !           237:        register char *ap1, *ap2;
        !           238: 
        !           239:        if ((p1 = p->ref) == 0)
        !           240:                return;
        !           241:        p1 = nonlab(p1);
        !           242:        if (p1->op==TST || p1->op==CMP)
        !           243:                splitrand(p1);
        !           244:        else
        !           245:                return;
        !           246:        if (p1->forw->op==CBR) {
        !           247:                ap1 = findcon(regs[RT1], p1->subop);
        !           248:                if (p1->op==TST)
        !           249:                        ap2 = "$0";
        !           250:                else
        !           251:                        ap2 = findcon(regs[RT2], p1->subop);
        !           252:                p1 = p1->forw;
        !           253:                if (compare(p1->subop, ap1, ap2) > 0) {
        !           254:                        nredunj++;
        !           255:                        nchange++;
        !           256:                        decref(p->ref);
        !           257:                        p->ref = p1->ref;
        !           258:                        p->labno = p1->labno;
        !           259: #ifdef COPYCODE
        !           260:                        if (p->labno == 0)
        !           261:                                p->code = p1->code;
        !           262:                        if (p->ref)
        !           263: #endif
        !           264:                                p->ref->refc++;
        !           265:                }
        !           266:        } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
        !           267:                        equtype(ccloc[0],p1->subop)) {
        !           268:                p1=insertl(p1->forw); decref(p->ref); p->ref=p1; 
        !           269:                nrtst++; nchange++;
        !           270:        }
        !           271: }
        !           272: 
        !           273: char *
        !           274: findcon(p, type)
        !           275:        register char *p;
        !           276: {
        !           277:        register r;
        !           278: 
        !           279:        if (*p=='$')
        !           280:                return(p);
        !           281:        if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
        !           282:                return(regs[r]+1);
        !           283:        if (equstr(p, conloc))
        !           284:                return(conval+1);
        !           285:        return(p);
        !           286: }
        !           287: 
        !           288: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
        !           289: compare(op, acp1, acp2)
        !           290: char *acp1, *acp2;
        !           291: {
        !           292:        register char *cp1, *cp2;
        !           293:        register n1, n2, sign;
        !           294: 
        !           295:        cp1 = acp1;
        !           296:        cp2 = acp2;
        !           297:        if (*cp1++ != '$' || *cp2++ != '$')
        !           298:                return(-1);
        !           299:        n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
        !           300:        while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
        !           301:        n1 *= sign;
        !           302:        n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
        !           303:        while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
        !           304:        n2 *= sign;
        !           305:        if (*cp1=='+')
        !           306:                cp1++;
        !           307:        if (*cp2=='+')
        !           308:                cp2++;
        !           309:        do {
        !           310:                if (*cp1++ != *cp2)
        !           311:                        return(-1);
        !           312:        } while (*cp2++);
        !           313:        switch(op) {
        !           314: 
        !           315:        case JEQ:
        !           316:                return(n1 == n2);
        !           317:        case JNE:
        !           318:                return(n1 != n2);
        !           319:        case JLE:
        !           320:                return(n1 <= n2);
        !           321:        case JGE:
        !           322:                return(n1 >= n2);
        !           323:        case JLT:
        !           324:                return(n1 < n2);
        !           325:        case JGT:
        !           326:                return(n1 > n2);
        !           327:        case JLO:
        !           328:                return((unsigned)n1 < (unsigned)n2);
        !           329:        case JHI:
        !           330:                return((unsigned)n1 > (unsigned)n2);
        !           331:        case JLOS:
        !           332:                return((unsigned)n1 <= (unsigned)n2);
        !           333:        case JHIS:
        !           334:                return((unsigned)n1 >= (unsigned)n2);
        !           335:        }
        !           336:        return(-1);
        !           337: }
        !           338: 
        !           339: setcon(cv, cl, type)
        !           340: register char *cv, *cl;
        !           341: {
        !           342:        register char *p;
        !           343: 
        !           344:        if (*cv != '$')
        !           345:                return;
        !           346:        if (!natural(cl))
        !           347:                return;
        !           348:        p = conloc;
        !           349:        while (*p++ = *cl++);
        !           350:        p = conval;
        !           351:        *p++ = type;
        !           352:        while (*p++ = *cv++);
        !           353: }
        !           354: 
        !           355: equstr(p1, p2)
        !           356: register char *p1, *p2;
        !           357: {
        !           358:        do {
        !           359:                if (*p1++ != *p2)
        !           360:                        return(0);
        !           361:        } while (*p2++);
        !           362:        return(1);
        !           363: }
        !           364: 
        !           365: setcc(ap,type)
        !           366: char *ap;
        !           367: {
        !           368:        register char *p, *p1;
        !           369: 
        !           370:        p = ap;
        !           371:        if (!natural(p)) {
        !           372:                ccloc[0] = 0;
        !           373:                return;
        !           374:        }
        !           375:        p1 = ccloc;
        !           376:        *p1++ = type;
        !           377:        while (*p1++ = *p++);
        !           378: }
        !           379: 
        !           380: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
        !           381:        while (*p) if (*p++=='[') return(1);
        !           382:        return(0);
        !           383: }
        !           384: 
        !           385: natural(p)
        !           386: register char *p;
        !           387: {/* 1->simple local, parameter, global, or register; 0->otherwise */
        !           388: 
        !           389:        if (*p=='*' || *p=='(' || *p=='$')
        !           390:                return(0);
        !           391:        while (*p++);
        !           392:        p--;
        !           393:        if (*--p==']' || *p==')' && *(p-2)!='f')
        !           394:                return(0);
        !           395:        return(1);
        !           396: }
        !           397: 
        !           398: /*
        !           399: ** Tell if an argument is most likely static.
        !           400: */
        !           401: 
        !           402: isstatic(cp)
        !           403: register char  *cp;
        !           404: {
        !           405:        if (*cp == '_' || *cp == 'L' || (*cp++ == 'v' && *cp == '.'))
        !           406:                return (1);
        !           407:        return (0);
        !           408: }

unix.superglobalmegacorp.com

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