Annotation of researchv9/jerq/sgs/comp/cost.c, revision 1.1

1.1     ! root        1: /*     @(#) cost.c: 1.5 3/9/84 */
        !             2: 
        !             3: # include "mfile2.h"
        !             4: 
        !             5: # ifndef CSTORE
        !             6: # define CSTORE(q) 2
        !             7: # endif
        !             8: # ifndef CLOAD
        !             9: # define CLOAD(q) 2
        !            10: # endif
        !            11: # ifndef CCTEST
        !            12: # define CCTEST(q) 1
        !            13: # endif
        !            14: # ifndef DFLT_STRATEGY
        !            15: # define DFLT_STRATEGY LTOR|RTOL
        !            16: # endif
        !            17: 
        !            18:        /* enough regs so there is always a free pair */
        !            19: # define HREG ((1+NRGS)/2+1)
        !            20: 
        !            21: #define LSAVED 30
        !            22: /* stores costs of leaves costed so far */
        !            23: static struct leaf {
        !            24:                int op;
        !            25:                int type;
        !            26:                int cst[NCOSTS];
        !            27: }      leafcosts[LSAVED], *leaf_ptr=leafcosts, *recost_leaf=0;
        !            28:        /* used to identify subtrees */
        !            29: # define NSUBTREES 10
        !            30: int nsubtree;
        !            31: NODE *subtree[NSUBTREES];
        !            32: int subgoal[NSUBTREES];
        !            33: 
        !            34: int strbc[NCOSTS];  /* the strategy done by bcost */
        !            35: SHAPE * lshbc[NCOSTS];  /* left-hand shape */
        !            36: SHAPE * rshbc[NCOSTS];  /* right-hand shape */
        !            37: 
        !            38: commute( p ) NODE *p; {
        !            39:        /* commute p in place */
        !            40:        register NODE *q;
        !            41: #ifndef NODBG
        !            42:        if(odebug) printf("commute: .=%u l=%u r=%u\n",p,p->in.left,p->in.right);
        !            43: #endif
        !            44:        q = p->in.left;
        !            45:        p->in.left = p->in.right;
        !            46:        p->in.right = q;
        !            47:        }
        !            48: 
        !            49: # ifndef NODBG
        !            50: # define GETS(x,y) if( e2debug>1) printf( "    x gets %d\n", y );
        !            51: # define GETSN(x,y) if( e2debug>1) printf( "   cst[%d] gets %d\n", x, y );
        !            52: # else
        !            53: # define GETS(x,y)
        !            54: # define GETSN(x,y)
        !            55: # endif
        !            56: 
        !            57: bcost( p, q )
        !            58: register NODE *p;
        !            59: register OPTAB *q;
        !            60: {
        !            61:        /* return the basic costs of matching q against tree p */
        !            62:        /* sha is set previously by match with a list of legal left
        !            63:        /* and right shapes */
        !            64:        /* bcost updates strbc, lshbc, and rshbc to reflect the
        !            65:        /* strategy, left shape, and right shape, that minimizes the cost
        !            66:        /* for q on p */
        !            67: 
        !            68:        /* j has its address taken, so it can't be in a reg */
        !            69:        int j;
        !            70:        int o, cc, c, s, tc, ttc, n, nn, lnn, lregs, rregs, cs, res;
        !            71:        int il, ir;  /* index into left and right address shapes */
        !            72:        int lsubtree;
        !            73:        NODE *l, *r;
        !            74:        register NODE *pp;
        !            75:        register ix;
        !            76:        SHAPE *sl, *sr;
        !            77: 
        !            78:        o = p->tn.op;
        !            79: 
        !            80:        /* look for the simple cases with register counts */
        !            81:        n = (q->needs&NCOUNT);
        !            82:        if( (q->needs&NPAIR) && n<HREG ) n = HREG;
        !            83: 
        !            84:        /* set up the left and right descendents */
        !            85:        l = getlo( p, o );
        !            86:        r = getro( p, o );
        !            87:        /*
        !            88:         *      If the operator table entry does not have a left shape,
        !            89:         *      but it does have a right shape, then this
        !            90:         *      table entry is for leaves ONLY, referenced to p, not to r
        !            91:         */
        !            92:        if( q->rshape && !q->lshape)
        !            93:                r = p;
        !            94: 
        !            95:        res = q->rewrite;
        !            96: 
        !            97:        /* determine the code generation strategy */
        !            98: 
        !            99:        if( o == COMOP ) cerror( "COMOP in bcost" );
        !           100: 
        !           101:        s = LTOR;  /* default strategy */
        !           102: 
        !           103:        if( optype(o) == BITYPE ) {
        !           104: 
        !           105:                switch( o ) {
        !           106: 
        !           107:                case CALL:
        !           108:                case STCALL:
        !           109:                case FORTCALL:
        !           110: # ifndef LTORARGS
        !           111:                case CM:  /* function arguments */
        !           112: # endif
        !           113:                        s = RTOL;
        !           114:                        break;
        !           115: 
        !           116:                default:
        !           117: # ifdef STACK
        !           118:                        if( asgop(o) ) s = RTOL;
        !           119:                        else s = LTOR;
        !           120: # else
        !           121:                        s = DFLT_STRATEGY;
        !           122: # endif
        !           123:                        break;
        !           124:                }
        !           125:        }
        !           126: 
        !           127: # ifndef NODBG
        !           128:        if(e2debug) {
        !           129:                printf("bcost(%d(%s),%d(%s),%x), s = ",
        !           130:                        p-node, opst[o], q->stinline, opst[q->op], sha[0] );
        !           131:                pstrat(s);
        !           132:                printf( "\n" );
        !           133:                printf( "\tneeds=%d%s%s\n", n,
        !           134:                        (q->needs&LSHARE)?", LSHARE":"",
        !           135:                        (q->needs&RSHARE)?", RSHARE":"" );
        !           136:                printf( "\tshape table: (%d %d %d ... )(%d %d %d ... )\n",
        !           137:                        sha[0][0]-shapes, sha[0][1]-shapes, sha[0][2]-shapes,
        !           138:                        sha[1][0]-shapes, sha[1][1]-shapes, sha[1][2]-shapes
        !           139:                        );
        !           140:                }
        !           141: # endif
        !           142: 
        !           143:        /* triple loop:
        !           144:        /* double loop over the left and right sides */
        !           145:        /* single loop over the number of regs available */
        !           146: 
        !           147:        for( il=0; (sl = sha[0][il]) || il==0; ++il ) {
        !           148:                lregs = lsubtree = nsubtree = 0;
        !           149:                c = q->cost;
        !           150:                lnn = n;
        !           151:                if( sl ) {
        !           152:                        /* list the left subtrees */
        !           153:                        findsub( l, sl );
        !           154:                        if( l->tn.op==REG && sl->op==REG && asgop(q->op)
        !           155:                                && !asgop(o) ) {
        !           156: 
        !           157:                                /* in an expression such as a+b, where a is */
        !           158:                                /* a register var, copy a to a scratch reg */
        !           159:                                /* before using += to do the add */
        !           160:                                /* this test causes that copy, by suggesting */
        !           161:                                /* that the lhs is a subtree, even though it
        !           162:                                /* matches the template exactly */
        !           163: 
        !           164:                                subtree[nsubtree] = l;
        !           165:                                subgoal[nsubtree] = NRGS;
        !           166:                                ++nsubtree;
        !           167:                                }
        !           168:                        lsubtree = nsubtree;
        !           169: 
        !           170:                        /* account for the cost of the shape */
        !           171:                        c += q->lcount * sl->sc;
        !           172: 
        !           173:                        /* count lhs register usage */
        !           174:                        for( lregs=ix=0; ix<lsubtree; ++ix ) {
        !           175:                                if( subgoal[ix] == NRGS ) {
        !           176:                                        lregs += szty(subtree[ix]->tn.type);
        !           177:                                        }
        !           178:                                }
        !           179:                        if( !(q->needs&LSHARE) ) lnn += lregs;
        !           180:                        }
        !           181: 
        !           182: # ifndef NODBG
        !           183:                if( e2debug ) {
        !           184:                        printf( "\tbcost left shape: sl=%d(%s), cost=%d\n",
        !           185:                                sl-shapes, sl?opst[sl->op]:"?", c );
        !           186:                        printf( "\t%d left subtrees\n", nsubtree );
        !           187:                        for( j=0; j<nsubtree; ++j ) {
        !           188:                                printf( "\t\tsubtree %d, goal %d\n",
        !           189:                                        subtree[j]-node, subgoal[j] );
        !           190:                                }
        !           191:                        }
        !           192: # endif
        !           193: 
        !           194:                for( ir=0; (sr = sha[1][ir]) || ir==0; ++ir ) {
        !           195:                        ttc = c;
        !           196:                        nsubtree = lsubtree;
        !           197:                        if( sr ) {
        !           198:                                ttc += q->rcount * sr->sc;
        !           199:                                findsub( r, sr );
        !           200:                                }
        !           201: # ifndef NODBG
        !           202:                        if( e2debug ) {
        !           203:                                printf( "\tbcost rt. shp: sr=%d(%s), cost=%d\n",
        !           204:                                        sr-shapes, sr?opst[sr->op]:"?", ttc );
        !           205:                                printf( "\t%d right subtrees\n",
        !           206:                                        nsubtree-lsubtree );
        !           207:                                for( j=lsubtree; j<nsubtree; ++j ) {
        !           208:                                        printf( "\t\tsubtree %d, goal %d\n",
        !           209:                                                subtree[j]-node, subgoal[j] );
        !           210:                                        }
        !           211:                                }
        !           212: # endif
        !           213: 
        !           214:                        /* figure out the minimum number of regs. possible */
        !           215:                        for( rregs=0,ix=lsubtree; ix<nsubtree; ++ix ) {
        !           216:                                if( subgoal[ix] == NRGS ) {
        !           217:                                        rregs += szty(subtree[ix]->tn.type);
        !           218:                                        }
        !           219:                                }
        !           220: 
        !           221:                        nn = lnn;
        !           222:                        if( q->needs & RSHARE ) nn -= rregs;
        !           223:                        if( nn < lregs ) nn = lregs;
        !           224:                        nn += rregs;
        !           225: 
        !           226: # ifndef NODBG
        !           227:                        if( e2debug ) {
        !           228:                                printf( "%d left, %d right regs, need >= %d\n",
        !           229:                                        lregs, rregs, nn );                             
        !           230:                                }
        !           231: # endif
        !           232: 
        !           233:                        for( j=NRGS; j>=nn; --j ) {
        !           234: # ifndef NODBG
        !           235:                                if( e2debug ) {
        !           236:                                        printf( "\t***  j = %d  ***\n", j );
        !           237:                                        }
        !           238: # endif
        !           239:                                /* exact match: don't fool around */
        !           240:                                if( nsubtree==0 ) {
        !           241:                                        cc = ttc;
        !           242:                                        cs = LTOR;
        !           243:                                        goto distribute;
        !           244:                                        }
        !           245:                                /* general case: grub around */
        !           246:                                /* LTOR means ascending, RTOL means descending*/
        !           247: 
        !           248:                                cc = INFINITY;
        !           249:                                if( s&LTOR ){ /* do it left to right */
        !           250:                                        int j1 = j;
        !           251:                                        tc = ttc;
        !           252:                                        for( ix=0; ix<nsubtree; ++ix ) {
        !           253:                                                pp = subtree[ix];
        !           254:                                                if( subgoal[ix] == NRGS ){
        !           255:                                                        /* shouldn't happen */
        !           256:                                                        if( j1<0 ) tc=INFINITY;
        !           257:                                                        else tc+=pp->tn.cst[j1];
        !           258:                                                        j1 -= szty(pp->tn.type);
        !           259:                                                        }
        !           260:                                                else tc +=
        !           261:                                                        pp->tn.cst[subgoal[ix]];
        !           262:                                                }
        !           263:                                        cc = tc;
        !           264:                                        cs = LTOR;
        !           265:                                        }
        !           266:                                if( s&RTOL ){ /* do it right to left */
        !           267:                                        int j1 = j;
        !           268:                                        tc = ttc;
        !           269:                                        for( ix=nsubtree-1; ix>=0; --ix ) {
        !           270:                                                pp = subtree[ix];
        !           271:                                                if( subgoal[ix] == NRGS ){
        !           272:                                                        /* shouldn't happen */
        !           273:                                                        if( j1<0 ) tc=INFINITY;
        !           274:                                                        else tc+=pp->tn.cst[j1];
        !           275:                                                        j1 -= szty(pp->tn.type);
        !           276:                                                        }
        !           277:                                                else tc +=
        !           278:                                                        pp->tn.cst[subgoal[ix]];
        !           279:                                                }
        !           280:                                        if( tc < cc ){
        !           281:                                                cc = tc;
        !           282:                                                cs = RTOL;
        !           283:                                                }
        !           284:                                        }
        !           285:                                if( cc >= INFINITY ) break; /* done */
        !           286: 
        !           287:                                /* now, cc is the minmal cost with j regs */
        !           288:                                /* update the various cost measures */
        !           289:                                /* everything affects CEFF */
        !           290:                        distribute:
        !           291: # ifndef NODBG
        !           292:                                if( e2debug ) {
        !           293:                                        printf( "\tdistribute %d\n", cc );
        !           294:                                        }
        !           295: # endif
        !           296:                                if( cc < p->tn.cst[CEFF] ) {
        !           297:                                        GETS(EFF,cc);
        !           298:                                        p->tn.cst[CEFF] = cc;
        !           299:                                        strbc[CEFF] = cs;
        !           300:                                        lshbc[CEFF] = sl;
        !           301:                                        rshbc[CEFF] = sr;
        !           302:                                        }
        !           303:                                /* for EFF, only do with NRGS */
        !           304:                                if( p->tn.goal == CEFF ) break;
        !           305:                                if( res == RNULL || res == RNOP ){
        !           306:                                        /* affects only CEFF */
        !           307:                                        cerror( "RNULL/RNOP error" );
        !           308:                                        }
        !           309: 
        !           310:                                if( (p->tn.goal==CCC) && (res&RESCC) ) {
        !           311:                                        /* CC's set */
        !           312:                                        if( cc < p->tn.cst[CCC] ) {
        !           313:                                                GETS(CC,cc);
        !           314:                                                p->tn.cst[CCC] = cc;
        !           315:                                                strbc[CCC] = cs;
        !           316:                                                lshbc[CCC] = sl;
        !           317:                                                rshbc[CCC] = sr;
        !           318:                                                }
        !           319:                                        }
        !           320: 
        !           321: 
        !           322:                                /* now, the register cost */
        !           323:                                tc = cc;
        !           324:                                if( (res&RLEFT) && sl->op != REG ){
        !           325:                                        cc += CLOAD(q);
        !           326:                                        }
        !           327:                                else if( (res&RRIGHT) && sr->op != REG ){
        !           328:                                        cc += CLOAD(q);
        !           329:                                        }
        !           330:                                if( cc < p->tn.cst[j] ) {
        !           331:                                        GETSN(j,cc);
        !           332:                                        p->tn.cst[j] = cc;
        !           333:                                        strbc[j] = cs;
        !           334:                                        lshbc[j] = sl;
        !           335:                                        rshbc[j] = sr;
        !           336:                                        }
        !           337: 
        !           338:                                /* for CC's, only do w. NRGS */
        !           339:                                if( p->tn.goal == CCC ) break;
        !           340: 
        !           341:                                if( j != NRGS ) continue;
        !           342: 
        !           343:                                /* record if lhs is actually a temp */
        !           344:                                /* need only do for NRGS */
        !           345: 
        !           346:                                if( tempok(p) && tc < p->tn.cst[CTEMP] ) {
        !           347:                                        GETS(TEMP,tc);
        !           348:                                        p->tn.cst[CTEMP] = tc;
        !           349:                                        strbc[CTEMP] = cs;
        !           350:                                        lshbc[CTEMP] = sl;
        !           351:                                        rshbc[CTEMP] = sr;
        !           352:                                        }
        !           353:                                }
        !           354:                        }
        !           355:                }
        !           356: 
        !           357:        /* now, some global cleanup */
        !           358:        /* some things are worth updating only once per template */
        !           359: 
        !           360:        if( p->tn.goal == CEFF ) return;  /* done */
        !           361: 
        !           362:        /* set Condition Codes by testing a register */
        !           363:        if( p->tn.goal == CCC ) {
        !           364:                tc = p->tn.cst[NRGS]+CCTEST(q);
        !           365:                if( tc < p->tn.cst[CCC] ) {
        !           366:                        GETS(CC,tc);
        !           367:                        p->tn.cst[CCC] = tc;
        !           368:                        strbc[CCC] = strbc[NRGS];
        !           369:                        lshbc[CCC] = lshbc[NRGS];
        !           370:                        rshbc[CCC] = rshbc[NRGS];
        !           371:                        }
        !           372:                return;
        !           373:                }
        !           374: 
        !           375:        /* put into TEMP by putting into REG, then storing */
        !           376:        /* if the lhs type is OK and we have an assignment op, don't
        !           377:        /* need to store: just use the result from EFF */
        !           378: 
        !           379:        if( asgop(o) && o!=INCR && o!= DECR && lhsok( l ) &&
        !           380:                        p->tn.type == l->tn.type ) {
        !           381:                cc = p->tn.cst[CEFF];
        !           382:                if( cc < p->tn.cst[CTEMP] ) {
        !           383:                        GETS(CTEMP,cc);
        !           384:                        p->tn.cst[CTEMP] = cc;
        !           385:                        strbc[CTEMP] = strbc[CEFF];
        !           386:                        lshbc[CTEMP] = lshbc[CEFF];
        !           387:                        rshbc[CTEMP] = rshbc[CEFF];
        !           388:                }
        !           389:        }
        !           390:        tc = p->tn.cst[NRGS] + CSTORE(q);
        !           391: 
        !           392:        if( tc < p->tn.cst[CTEMP] ) {
        !           393:                GETS(TEMP,tc);
        !           394:                p->tn.cst[CTEMP] = tc;
        !           395:                strbc[CTEMP] = strbc[NRGS];
        !           396:                lshbc[CTEMP] = lshbc[NRGS];
        !           397:                rshbc[CTEMP] = rshbc[NRGS];
        !           398:                }
        !           399: 
        !           400:        /* compute with few regs by storing, then loading */
        !           401: 
        !           402:        tc = p->tn.cst[CTEMP] + CLOAD(q);
        !           403: 
        !           404:        for( j=1; j<NRGS; ++j ) {
        !           405:                if( tc < p->tn.cst[j] ) {
        !           406:                        p->tn.cst[j] = tc;
        !           407:                        GETSN(j,tc);
        !           408:                        strbc[j] = strbc[CTEMP] | STORE;
        !           409:                        lshbc[j] = lshbc[CTEMP];
        !           410:                        rshbc[j] = rshbc[CTEMP];
        !           411:                        }
        !           412:                }
        !           413:        }
        !           414: 
        !           415: lhsok( p )
        !           416: NODE *p;
        !           417: {
        !           418:        /* p appears on the lhs of an assignment op */
        !           419:        /* is it an OK substitute for a TEMP? */
        !           420: 
        !           421:        switch( p->tn.op ) {
        !           422: 
        !           423:        case NAME:
        !           424:        case VAUTO:
        !           425:        case VPARAM:
        !           426:        case TEMP:
        !           427:        case REG:
        !           428:                return( 1 );
        !           429: 
        !           430:        }
        !           431:        return( 0 );
        !           432: }
        !           433: 
        !           434: shpr(sp) register SHAPE *sp; {
        !           435:        if (!sp) return;
        !           436:        if( sp->op < 0 || sp->op > DSIZE ) cerror( "shape op %d\n", sp->op );
        !           437:        printf(" %s", opst[sp->op]);
        !           438:        shpr(sp->sl);
        !           439:        shpr(sp->sr);
        !           440:        }
        !           441: 
        !           442: pstrat( s ) {
        !           443:        /* print a nice version of the strategy s */
        !           444:        register i, flag;
        !           445:        static char *stratnames[] = {
        !           446:                "STORE",
        !           447:                "LTOR",
        !           448:                "RTOL",
        !           449:                0 };
        !           450:        flag = 0;
        !           451:        for( i=0; stratnames[i]; ++i ){
        !           452:                if( s & (1<<i) ) {
        !           453:                        if( flag ) putchar( '|' );
        !           454:                        printf( "%s", stratnames[i] );
        !           455:                        flag = 1;
        !           456:                        }
        !           457:                }
        !           458:        if( !flag ) printf( "0" );
        !           459:        }
        !           460: 
        !           461: insout( p, i )
        !           462: NODE *p;
        !           463: {
        !           464:        OPTAB *q;
        !           465:        int c, o, j;
        !           466: 
        !           467:        /* generate the actual instructions */
        !           468:        /* if the cost is infinite, try rewriting */
        !           469: 
        !           470:        c = p->in.cst[i];
        !           471:        o = p->tn.op;
        !           472: 
        !           473: #ifndef NODBG
        !           474:        if( odebug>1 ) printf( "insout(%d,%d), cost %d\n", p-node,i,c );
        !           475: #endif
        !           476:        if( c >= INFINITY ){
        !           477:                cerror( "missing table entry, op %s", opst[p->tn.op] );
        !           478:        }
        !           479: 
        !           480:        /* handle COMOP specially */
        !           481:        if( o == COMOP ) {
        !           482:                q = match( p, (OPTAB *)0 );  /* had better match */
        !           483:                if( !q ) cerror( "COMOP match fails" );
        !           484:                bprt( p, q, i );
        !           485:                return;
        !           486:        }
        !           487: 
        !           488:        /* want to force bcost to do some work */
        !           489:        /* this is because the strbc, etc., arrays, set by bcost, are used
        !           490:        /* by bprt */
        !           491: 
        !           492:        for( j=0; j<NCOSTS; ++j ) ++p->in.cst[j];
        !           493:        for( q=0; q = match( p, q ); ){
        !           494:                if( i != CEFF ) {
        !           495:                        if( q->rewrite & RLEFT ) restrip( sha[0] );
        !           496:                        if( q->rewrite & RRIGHT ) restrip( sha[1] );
        !           497:                }
        !           498:                bcost( p, q );
        !           499:                if( p->tn.cst[i] == c ) {  /* we have found it */
        !           500:                        if( strbc[i]&STORE ) bprt( p, q, CTEMP );
        !           501:                        else bprt( p, q, i );
        !           502:                        return;
        !           503:                }
        !           504:        }
        !           505: 
        !           506:        /* commuting must be in order here */
        !           507:        /* if fast flag is on, we can only fail, but it's ok to try */
        !           508: 
        !           509:        if( o != PLUS  &&  o != MUL  &&  o != AND  &&  o != OR  &&  o != ER ) {
        !           510:                e2print( p );
        !           511:                cerror( "commute??, op[%d] == %s", o, opst[o] );
        !           512:        }
        !           513:        commute( p );  /* this is the payoff; don't need to commute back */
        !           514:        for( q=0; q = match( p, q ); ){
        !           515:                if( i != CEFF ) {
        !           516:                        if( q->rewrite & RLEFT ) restrip( sha[0] );
        !           517:                        if( q->rewrite & RRIGHT ) restrip( sha[1] );
        !           518:                }
        !           519:                bcost( p, q );
        !           520:                if( p->tn.cst[i] == c ) { /* we found it */
        !           521:                        bprt( p, q, i );
        !           522:                        return;
        !           523:                }
        !           524:        }
        !           525: 
        !           526:        cerror( "insout returns without a match" );
        !           527:        /* NOTREACHED */
        !           528: 
        !           529: }
        !           530: 
        !           531: bprt( p, q, i )
        !           532: NODE *p;
        !           533: OPTAB *q;
        !           534: {
        !           535:        /* this routine is called to print out the actual instructions */
        !           536:        /* it is called with a tree node p, a template q, and a goal i */
        !           537:        /* bprt calls bcost, and then captures the left and right shapes */
        !           538:        /* it then uses findsub to determine the preconditions and goals */
        !           539:        /* a local copy of this information must be made, since bprt can be
        !           540:        /* called recursively */
        !           541:        /* then, bprt calls insout to output the instructions that establish
        !           542:        /* the preconditions.  Finally, it can output its own instruction */
        !           543: 
        !           544:        int j, j1, s, o, k;
        !           545:        NODE *l, *r;
        !           546:        SHAPE *ls, *rs;
        !           547:        int nn;
        !           548:        int mygoal[NSUBTREES];
        !           549:        NODE *mysubs[NSUBTREES];
        !           550: 
        !           551:        /* sets j as well */
        !           552:        if( i < NRGS ) j = i;
        !           553:        else j = NRGS;
        !           554:        l = getl( p );
        !           555:        r = getr( p );
        !           556:        if (q->rshape && !q->lshape)
        !           557:                r = p;
        !           558:        s = strbc[i];
        !           559:        ls = lshbc[i];
        !           560:        rs = rshbc[i];
        !           561:        o = p->tn.op;
        !           562: # ifndef NODBG
        !           563:        if( odebug>1 ) {
        !           564:                printf( "       matches %d, ls = %d(%s), rs = %d(%s),  s= ",
        !           565:                        q->stinline, ls-shapes, ls?opst[ls->op]:"SHNL",
        !           566:                        rs-shapes, rs?opst[rs->op]:"SHNL" );
        !           567:                pstrat( s );
        !           568:                printf( "\n" );
        !           569:                }
        !           570: # endif
        !           571: 
        !           572:        /* handle COMOP differently; this has more to do with the register
        !           573:        /* allocation than the ordering */
        !           574: 
        !           575:        if( o == COMOP ) {
        !           576:                insout( l, CEFF );
        !           577:                insout( r, i );
        !           578:                goto generate;
        !           579:        }
        !           580: 
        !           581:        nsubtree = 0;
        !           582:        if(rs && (s&RTOL) ) findsub( r, rs );
        !           583:        if( ls ) {
        !           584:                findsub( l, ls );
        !           585:                if( l->tn.op==REG && ls->op==REG && asgop(q->op) &&
        !           586:                                !asgop(o) ) {
        !           587:                        /* we must arrange to copy a reg variable on the lhs
        !           588:                        /* of a binary op, in some cases (cf. bcost) */
        !           589:                        subtree[nsubtree] = l;
        !           590:                        subgoal[nsubtree] = NRGS;
        !           591:                        ++nsubtree;
        !           592:                        }
        !           593:                }
        !           594:        if(rs && (s&LTOR) ) findsub( r, rs );
        !           595:        nn = nsubtree;
        !           596: 
        !           597:        /* make a local copy */
        !           598:        for( k=0; k<nn; ++k ) {
        !           599:                mygoal[k] = subgoal[k];
        !           600:                mysubs[k] = subtree[k];
        !           601:                }
        !           602: 
        !           603: # ifndef NODBG
        !           604:        if( odebug>1 ) {  /* subtree matches are: */
        !           605:                printf( "\t\t%d matches\n", nn );
        !           606:                for( k=0; k<nn; ++k ) {
        !           607:                        printf( "\t\tnode %d, goal %d\n",mysubs[k]-node,
        !           608:                                mygoal[k] );
        !           609:                        }
        !           610:                }
        !           611: # endif
        !           612: 
        !           613:        /* do the subtrees */
        !           614:        /* someday, rewrite the temps right here and now */
        !           615: 
        !           616:        j1 = j;
        !           617:        for( k=0; k<nn; ++k ) {
        !           618: # ifndef NODBG
        !           619:                if( odebug>2 )
        !           620:                        printf( "\t\tcalling insout(%d,%d)\n", mysubs[k]-node,
        !           621:                                        j1 );
        !           622: # endif
        !           623:                if( mygoal[k] == NRGS ) {
        !           624:                        insout( mysubs[k], j1 );
        !           625:                        j1 -= szty( mysubs[k]->tn.type );
        !           626:                        }
        !           627:                else {
        !           628:                        insout( mysubs[k], mygoal[k] );
        !           629:                        }               
        !           630:                }
        !           631:        /* put onto the instruction string the info about the instruction */
        !           632:     generate:
        !           633:        if( nins >= NINS ) cerror( "too many instructions generated" );
        !           634:        inst[nins].p = p;
        !           635:        inst[nins].q = q;
        !           636:        inst[nins].goal = i;
        !           637:        /* a special case: REG op= xxx, should be done as early as possible */
        !           638:        if( asgop(o) && p->in.left->tn.op == REG && o != INCR && o != DECR
        !           639:                        && i!=CEFF && i!=CCC && !istreg(p->in.left->tn.rval)){
        !           640:                /* "istreg" guards against rewriting returns, switches, etc. */
        !           641:                inst[nins].goal = CTEMP;
        !           642:        }
        !           643:        ++nins;
        !           644: }
        !           645: 
        !           646: findsub( p, s )
        !           647: NODE *p;
        !           648: SHAPE *s;
        !           649: {
        !           650:        /* account for the costs of matching the shape s with the tree j */
        !           651: 
        !           652:        if( !s )
        !           653:                return;
        !           654: 
        !           655: # ifndef NODBG
        !           656:        if( e2debug>1 ) {
        !           657:                printf( "\t\tfindsub( %d, %d )\n", p-node, s-shapes );
        !           658:                }
        !           659: # endif
        !           660: 
        !           661:        switch( s->op ) {
        !           662: 
        !           663:        case TEMP:
        !           664:                /* leave j unchanged */
        !           665:                if( p->tn.op == TEMP ) return;
        !           666:                subtree[nsubtree] = p;
        !           667:                subgoal[nsubtree] = CTEMP;
        !           668:                ++nsubtree;
        !           669:                return;
        !           670: 
        !           671:        case FREE:
        !           672:                subtree[nsubtree] = p;
        !           673:                subgoal[nsubtree] = CEFF;
        !           674:                ++nsubtree;
        !           675:                return;
        !           676: 
        !           677:        case CCODES:
        !           678:                subtree[nsubtree] = p;
        !           679:                subgoal[nsubtree] = CCC;
        !           680:                ++nsubtree;
        !           681:                return;
        !           682: 
        !           683:        case REG:
        !           684:                if( p->tn.op == REG ) return;  /* exact match */
        !           685: 
        !           686:                /* in general, look beneath */
        !           687:                /* also, look here if a REG and rcst is 1 */
        !           688: 
        !           689:                subtree[nsubtree] = p;
        !           690:                subgoal[nsubtree] = NRGS;
        !           691:                ++nsubtree;
        !           692:                return;
        !           693:                }
        !           694: 
        !           695:        if( s->op == p->tn.op ) {
        !           696: 
        !           697:                /* look at subtrees */
        !           698:                if( s->sl ) findsub( getl(p), s->sl );
        !           699:                if( s->sr ) findsub( getr(p), s->sr );
        !           700:                return;
        !           701:                }
        !           702:        }
        !           703: 
        !           704: costs( p ) register NODE *p; {
        !           705:        register OPTAB *q;
        !           706:        int i, o, ty;
        !           707:        register *pc;
        !           708: 
        !           709:        /* compute the costs for p */
        !           710:        /* the goal is either NRGS (into a reg. or temp), CCC, or CEFF */
        !           711: 
        !           712:        /* in a stack machine, this will probably look very different.
        !           713:        /* it is possible that seting szty() to be 0 will deal with the
        !           714:        /* stack machine problems; if not, we will need to put some special
        !           715:        /* code in here under control of ifdef STACK
        !           716:        /* the stack machine issue is that the "register" use on the left does
        !           717:        /* not limit the computations on the right, and conversely */
        !           718:     again:
        !           719:        ty = optype( o = p->tn.op );
        !           720:        if (ty == LTYPE && get_leaf(p) ) return(0);
        !           721:        pc = p->in.cst;
        !           722:        for( i=0; i<NCOSTS; ++i ) {
        !           723:                pc[i] = INFINITY;
        !           724:                strbc[i] = 0;
        !           725:                lshbc[i] = rshbc[i] = (SHAPE *)0;
        !           726:        }
        !           727: 
        !           728: # ifndef NODBG
        !           729:        if( udebug ) {
        !           730:                printf( "costs( %d, %d ), op = %s\n", p-node,
        !           731:                        p->tn.goal, opst[o] );
        !           732:                }
        !           733: # endif
        !           734: 
        !           735:        if( ty != LTYPE ) if( costs( p->in.left ) ) return(1);
        !           736:        if( ty == BITYPE ) if( costs( p->in.right ) ) return(1);
        !           737: 
        !           738:        pc = p->in.cst;
        !           739: 
        !           740:        /* now, compute the costs based on matches */
        !           741:        /* handle COMOP specially */
        !           742:        if( o == COMOP ) {
        !           743:                int cc = p->in.left->in.cst[CEFF];
        !           744:                for( i=NRGS; i<NCOSTS; ++i ) {
        !           745:                        pc[i] = cc + p->in.right->in.cst[i];
        !           746:                        if( pc[i] > INFINITY ) pc[i] = INFINITY;
        !           747:                }
        !           748:                return(0);
        !           749:        }
        !           750: 
        !           751:        for( q=0; q = match(p,q); ){
        !           752:                if( p->tn.goal != CEFF ) {
        !           753:                        if( q->rewrite & RLEFT ) restrip( sha[0] );
        !           754:                        if( q->rewrite & RRIGHT ) restrip( sha[1] );
        !           755:                }
        !           756:                bcost( p, q );
        !           757: # ifndef NODBG
        !           758:                if( udebug ) {
        !           759:                        printf( "bcost( %d, %d )\n", p-node, q->stinline);
        !           760:                        e222print( 1, p, "T" );
        !           761:                }
        !           762: # endif
        !           763:        }
        !           764: 
        !           765: #ifndef NOCOMMUTE
        !           766:        /* don't commute if we are trying to be fast */
        !           767:        if( !fast && (o==PLUS||o==MUL||o==AND||o==OR||o==ER) ){
        !           768: # ifndef NODBG
        !           769:                if( udebug ) {
        !           770:                        printf( "COMMUTE %d *******\n", p-node );
        !           771:                }
        !           772: # endif
        !           773:                commute( p );
        !           774:                for( q=0; q = match(p,q); ){
        !           775:                if( p->tn.goal != CEFF ) {
        !           776:                        if( q->rewrite & RLEFT ) restrip( sha[0] );
        !           777:                        if( q->rewrite & RRIGHT ) restrip( sha[1] );
        !           778:                }
        !           779:                        bcost( p, q );
        !           780: # ifndef NODBG
        !           781:                        if( udebug ) {
        !           782:                                printf( "bcost( %d, %d )\n", p-node, q->stinline);
        !           783:                                e222print( 1, p, "T" );
        !           784:                        }
        !           785: # endif
        !           786:                }
        !           787:                commute( p );
        !           788: # ifndef NODBG
        !           789:                if( udebug ) {
        !           790:                        printf( "END OF COMMUTE %d *******\n", p-node );
        !           791:                }
        !           792: # endif
        !           793:                }
        !           794: 
        !           795: /*     END OF COMMUTE CODE *****  */
        !           796: # endif
        !           797: 
        !           798:        /* here is a big worry; when do we do this rewriting?
        !           799:        /* if we do it too early, we may miss some neat possibilities */
        !           800:        /* if we do it too late, we may have miscomputed some earlier things */
        !           801: 
        !           802:        if( pc[p->tn.goal]>=INFINITY ){
        !           803:                if( p->fn.type == TSTRUCT ) return(0);
        !           804:                if( optype( o ) == LTYPE ) return( 0 );
        !           805:                if( rewass( p ) ) return( 1 );  /* major rewrite */
        !           806:                goto again;  /* minor rewrite: restart here */
        !           807:                }
        !           808:        if (ty == LTYPE)
        !           809:                save_leaf(p);
        !           810:        return( 0 );
        !           811:        }
        !           812: static get_leaf(p)
        !           813:        register NODE *p;
        !           814:        {
        !           815:        register struct leaf *lf;
        !           816:                        /*see if this leaf/type pair is in the tables*/
        !           817:        /* multiple flavored ICON's don't save properly */
        !           818:        if ( p->tn.op == ICON ) return(0)        !           819:        recost_leaf=0;
        !           820:        for (lf=leafcosts;lf < leaf_ptr; lf++){
        !           821:                if (lf->op == p->tn.op && lf->type == p->tn.type)
        !           822:                        {
        !           823:                        /*if the saved cost was infinite, we will have
        !           824:                          to recost the leaf anyway*/
        !           825:                        if (lf->cst[p->tn.goal] >= INFINITY)
        !           826:                                {
        !           827:                                recost_leaf = lf;
        !           828:                                return(0);
        !           829:                                }
        !           830:                        /*else, load the costs and leave*/
        !           831:                        memcpy(p->tn.cst,lf->cst,sizeof(int)*NCOSTS);
        !           832:                        return(1);
        !           833:                        }
        !           834:                } /*end for*/
        !           835:        return(0);
        !           836:        } /*end get_leaf*/
        !           837: 
        !           838: static save_leaf(p)
        !           839:        register NODE *p;
        !           840:        {
        !           841:                        /*save the costs of this leaf for future reference.
        !           842:                          if recost_leaf is non-zero, it is already in the
        !           843:                          table*/
        !           844:        register struct leaf *lf;
        !           845:        if ( p->tn.op == ICON )
        !           846:        {
        !           847:                /* ICONs have too many flavors to save by op */
        !           848:                recost_leaf=0;
        !           849:                return;
        !           850:        }
        !           851:        if ( !recost_leaf && (leaf_ptr >= leafcosts + LSAVED) ) return;
        !           852:        lf = recost_leaf ? recost_leaf : leaf_ptr++;
        !           853:        lf->op = p->tn.op;
        !           854:        lf->type = p->tn.type;
        !           855:        memcpy(lf->cst,p->tn.cst,sizeof(int)*NCOSTS);
        !           856:        recost_leaf=0;
        !           857: }
        !           858: 

unix.superglobalmegacorp.com

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