Annotation of researchv10no/cmd/ccom/common/cost.c, revision 1.1

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

unix.superglobalmegacorp.com

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