Annotation of cci/usr/src/lib/c2/c22.c, revision 1.1.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.