Annotation of researchv10no/cmd/ccom/common/allo.c, revision 1.1.1.1

1.1       root        1: /*     @(#) allo.c: 1.6 2/23/84        */
                      2: 
                      3: # include "mfile2.h"
                      4: 
                      5: extern NODE resc[];
                      6: 
                      7: extern int busy[];
                      8: 
                      9: # define TBUSY 0100
                     10: 
                     11: allo( p, q )
                     12: register NODE *p; 
                     13: register struct optab *q; 
                     14: {
                     15:        register n, i, j;
                     16:        register NODE *presc;
                     17: 
                     18:        n = q->needs;
                     19:        i = 0;
                     20:        /* This code assumes a double reg counts 1 */
                     21:        while( n & NCOUNT )
                     22:        {
                     23:                if( n&NPAIR ) 
                     24:                {
                     25:                        j = freepair( p, n&NMASK );
                     26:                        busy[j] |= TBUSY;
                     27:                        busy[j+1] |= TBUSY;
                     28:                }
                     29:                else 
                     30:                {
                     31:                        j = freereg( p, n&NMASK );
                     32:                        busy[j] |= TBUSY;
                     33:                }
                     34:                n -= NREG;
                     35:                presc = &resc[i];
                     36:                presc->in.op = REG;
                     37:                presc->tn.rval = j;
                     38:                presc->tn.type = p->tn.type;
                     39:                presc->tn.lval = 0;
                     40:                presc->in.name = (char *) 0;
                     41:                ++i;
                     42:        }
                     43: 
                     44:        /* turn off "temporarily busy" bit */
                     45:        for( j=0; j<NRGS; ++j )
                     46:        {
                     47:                busy[j] &= ~TBUSY;
                     48:        }
                     49: #ifndef NODBG
                     50:        if( rdebug > 1 )
                     51:        {
                     52:                printf( "allo( %d, %d ), %o", p-node, q->stinline, q->needs );
                     53:                for( j=0; j<i; ++j )
                     54:                {
                     55:                        if( resc[j].tn.op == REG )
                     56:                                printf( ", REG(%d)", resc[j].tn.rval );
                     57:                        else
                     58:                                printf( ", TEMP(%ld)", resc[j].tn.lval );
                     59:                }
                     60:                putchar( '\n' );
                     61:                prbusy( "busy:" );
                     62:        }
                     63: #endif
                     64: }
                     65: 
                     66: # ifdef STACK
                     67: /* for stack machines, totally disable the register allocation */
                     68: freereg( p, n )
                     69: NODE *p; 
                     70: {
                     71:        return( 0 );
                     72: }
                     73: 
                     74: freepair( p, n )
                     75: NODE *p; 
                     76: {
                     77:        cerror( "pairs on a stack machine?" );
                     78: }
                     79: 
                     80: rbusy( r, t )
                     81: TWORD t; 
                     82: {
                     83: }
                     84: rfree( r, t )
                     85: TWORD t; 
                     86: {
                     87: }
                     88: 
                     89: regrcl( p )
                     90: NODE *p; 
                     91: {
                     92: }
                     93: # else
                     94: freepair( p, n )
                     95: register NODE *p; 
                     96: register n;
                     97: {
                     98:        /* allocate a register pair */
                     99:        /* p gives the type */
                    100: 
                    101: #ifdef MYPAIR
                    102:        return (mypair(p, n));
                    103: #else
                    104:        register j;
                    105: 
                    106:        if( callop(p->in.op) )
                    107:        {
                    108:                j = callreg(p);
                    109:                if( j&1 ) cerror( "callreg returns bad pair" );
                    110:                if( usable( p, n, j ) ) return( j );
                    111:                /* have allocated callreg first */
                    112:        }
                    113:        if( n&NMASK )
                    114:        {
                    115: #ifdef ODDPAIR                 /* if pair may start on odd reg. */
                    116:                for( j=0; j<NRGS; j++ )
                    117: #else
                    118:                for( j=0; j<NRGS; j+=2 )
                    119: #endif
                    120:                        if( usable(p,n,j) && usable(p,n,j+1))
                    121:                                return( j );
                    122:        }
                    123:        cerror( "freepair allocation fails, op %s", opst[p->tn.op] );
                    124:        /* NOTREACHED */
                    125: #endif
                    126: }
                    127: 
                    128: freereg( p, n )
                    129: register NODE *p; 
                    130: register n;
                    131: {
                    132:        /* allocate a register */
                    133:        /* p gives the type */
                    134: 
                    135:        register j;
                    136:        register int t = optype( p->tn.op );
                    137: 
                    138:        if( callop(p->in.op) )
                    139:        {
                    140:                j = callreg(p);
                    141:                if( usable( p, n, j ) ) return( j );
                    142:                /* have allocated callreg first */
                    143:        }
                    144:        if( n&NMASK )
                    145:        {
                    146:                if( (n&LPREF) && (j = shared( getlt( p, t ) ) ) >= 0 &&
                    147:                   usable( p, n, j ) ) return( j );
                    148:                if( (n&RPREF) && (j = shared( getrt( p, t ) ) ) >= 0 &&
                    149:                   usable( p, n, j ) ) return( j );
                    150:                for( j=0; j<NRGS; ++j ) if( usable(p,n,j) ) return( j );
                    151:        }
                    152:        cerror( "freereg allocation fails, op %s", opst[p->tn.op] );
                    153:        /* NOTREACHED */
                    154: }
                    155: 
                    156: shared( p )
                    157: register NODE *p; 
                    158: {
                    159:        /* simple, at present */
                    160:        /* try to find a single register to share */
                    161:        register r, o;
                    162: #ifndef NODBG
                    163:        if( rdebug ) 
                    164:        {
                    165:                printf( "shared called on:\n" );
                    166:                e2print( p );
                    167:        }
                    168: #endif
                    169:        if( (o=p->tn.op) == REG ) 
                    170:        {
                    171:                r = p->tn.rval;
                    172:                if (r >= NRGS) return ( -1 );
                    173: #ifndef NODBG
                    174:                if( rdebug ) 
                    175:                {
                    176:                        printf( "preference for %s\n", rnames[r] );
                    177:                }
                    178: #endif
                    179:                return( r );
                    180:        }
                    181:        /* we look for shared regs under unary-like ops */
                    182:        switch( optype( o ) ) 
                    183:        {
                    184: 
                    185:        case BITYPE:
                    186:                /* look for simple cases */
                    187:                /* look only on the left */
                    188:        case UTYPE:
                    189:                return( shared( p->in.left ) );
                    190:        }
                    191:        return( -1 );
                    192: }
                    193: 
                    194: usable( p, n, r )
                    195: register NODE *p; 
                    196: register n,r;
                    197: {
                    198:        /* decide if register r is usable in tree p to satisfy need n */
                    199:        /* this does not concern itself with pairs */
                    200: 
                    201:        if( r>= NRGS || (busy[r] & TBUSY) ) return( 0 );
                    202:        if( busy[r] > 1 ) 
                    203:        {
                    204:                /*
                    205:                ** uerror( "register %d too busy", r );
                    206:                */
                    207:                return( 0 );
                    208:        }
                    209:        if( busy[r] == 0 ) {
                    210:                return(1);
                    211:        }
                    212: 
                    213:        /* busy[r] is 1: is there chance for sharing */
                    214:        return( shareit( p, r, n ) );
                    215: 
                    216: }
                    217: 
                    218: shareit( p, r, n )
                    219: register NODE *p; 
                    220: register r;
                    221: int n;
                    222: {
                    223:        /* can we make register r available by sharing from p
                    224:        ** given that the need is n 
                    225:        */
                    226:        register NODE *sub;
                    227:        register int t = optype(p->tn.op);
                    228:        
                    229:        sub = getlt( p, t );
                    230:        if( (n&LSHARE) && ushare( sub, r ) )  {
                    231:                return 1;
                    232:        }
                    233:        sub = getrt( p, t );
                    234:        if( (n&RSHARE) && ushare( sub, r ) ) {
                    235:                return(1);
                    236:        }
                    237:        return(0);
                    238: }
                    239: 
                    240: ushare( p, r )
                    241: register NODE *p; 
                    242: register r;
                    243: {
                    244:        /* can we find register r to share in p */
                    245:        if( p->in.op == REG ) 
                    246:        {
                    247:                if( szty( p->tn.type ) == 2 && r==(p->tn.rval+1) ) return( 1 );
                    248:                return( r == p->tn.rval );
                    249:        }
                    250:        switch( optype( p->tn.op ) )
                    251:        {
                    252:        case BITYPE:
                    253:                if( ushare( p->in.right, r ) ) return( 1 );
                    254:        case UTYPE:
                    255:                if( ushare( p->in.left, r ) ) return( 1 );
                    256:        }
                    257:        return(0);
                    258: }
                    259: 
                    260: regrcl( p )
                    261: register NODE *p; 
                    262: {
                    263:        /* free registers in the tree (or fragment) p */
                    264:        register r;
                    265:        if( !p ) return;
                    266:        r = p->tn.rval;
                    267:        if( p->in.op == REG ) rfree( r, p->in.type );
                    268:        switch( optype( p->tn.op ) )
                    269:        {
                    270:        case BITYPE:
                    271:                regrcl( p->in.right );
                    272:                /* explict assignment to regs not accounted for */
                    273:                if( asgop(p->tn.op) && p->in.left->tn.op == REG ) break;
                    274:        case UTYPE:
                    275:                regrcl( p->in.left );
                    276:        }
                    277: }
                    278: 
                    279: rfree( r, t )
                    280: register TWORD t; 
                    281: register r;
                    282: {
                    283:        /* mark register r free, if it is legal to do so */
                    284:        /* t is the type */
                    285: 
                    286: #ifndef NODBG
                    287:        if( rdebug )
                    288:        {
                    289:                printf( "rfree( %s, ", rnames[r] );
                    290:                t2print( t );
                    291:                printf( " )\n" );
                    292:        }
                    293: #endif
                    294:        if( istreg(r) )
                    295:        {
                    296:                if( --busy[r] < 0 ) cerror( "register overfreed");
                    297:                if( szty( t ) > 1 )
                    298:                {
                    299:                        if( !istreg(r+1) ) cerror( "big register" );
                    300:                        if( --busy[r+1] < 0 ) cerror( "register overfreed" );
                    301:                }
                    302:        }
                    303: }
                    304: 
                    305: prbusy( s )
                    306: char *s;
                    307: {
                    308:        /* print out the busy[] array */
                    309:        int i;
                    310:        printf( "%s [", s );
                    311:        for( i=0; i<NRGS-1; ++i ) printf( "%d,", busy[i] );
                    312:        printf( "%d]\n", busy[NRGS-1] );
                    313: }
                    314: 
                    315: # endif
                    316: 
                    317: rwprint( rw )
                    318: register rw;
                    319: {
                    320:        /* print rewriting rule */
                    321:        register i, flag;
                    322:        static char * rwnames[] = 
                    323:        {
                    324:                "RLEFT",
                    325:                "RRIGHT",
                    326:                "RESC1",
                    327:                "RESC2",
                    328:                "RESC3",
                    329:                "RESCC",
                    330:                "RNOP",
                    331:                0,
                    332:        };
                    333:        if( rw == RNULL )
                    334:        {
                    335:                printf( "RNULL" );
                    336:                return;
                    337:        }
                    338:        flag = 0;
                    339:        for( i=0; rwnames[i]; ++i )
                    340:        {
                    341:                if( rw & (1<<i) )
                    342:                {
                    343:                        if( flag ) printf( "|" );
                    344:                        ++flag;
                    345:                        printf( rwnames[i] );
                    346:                }
                    347:        }
                    348:        if( !flag ) printf( "?%o", rw );
                    349: }
                    350: 
                    351: reclaim( p, rw, goal )
                    352: register NODE *p; 
                    353: register rw, goal;
                    354: {
                    355:        register NODE *q;
                    356:        register o;
                    357: 
                    358:        /* get back stuff */
                    359: #ifndef NODBG
                    360:        if( rdebug )
                    361:        {
                    362:                printf( "reclaim( %d, ", p-node );
                    363:                rwprint( rw );
                    364:                printf( ", " );
                    365:                prgoal( goal );
                    366:                printf( " )\n" );
                    367:        }
                    368: #endif
                    369:        if( !p ) return;
                    370:        /* special cases... */
                    371:        if( (o=p->tn.op) == COMOP )
                    372:        {
                    373:                /* LHS has already been freed; don't free again */
                    374:                regrcl( p->in.right );
                    375:        }
                    376:        else regrcl( p );
                    377:        if( (o==FREE && rw==RNULL) || rw==RNOP ) return;
                    378:        if( callop(o) )
                    379:        {
                    380:                /* check that all scratch regs are free */
                    381:                callchk(p);  /* ordinarily, this is the same as allchk() */
                    382:        }
                    383:        if( rw == RNULL || (goal&FOREFF) )
                    384:        {
                    385:                /* totally clobber, leave nothing */
                    386:                tfree(p);
                    387:                return;
                    388:        }
                    389:        /* handle condition codes specially */
                    390:        if( (goal & FORCC) && (rw&RESCC)) 
                    391:        {
                    392:                /* result is CC register */
                    393:                tfree(p);
                    394:                p->in.op = CCODES;
                    395:                p->tn.lval = 0;
                    396:                p->tn.rval = 0;
                    397:                return;
                    398:        }
                    399:        q = 0;
                    400:        if( rw&RLEFT) q = getl( p );
                    401:        else if( rw&RRIGHT ) q = getr( p );
                    402:        else if( rw&RESC1 ) q = &resc[0];
                    403:        else if( rw&RESC2 ) q = &resc[1];
                    404:        else if( rw&RESC3 ) q = &resc[2];
                    405:        else 
                    406:        {
                    407:                cerror( "illegal reclaim, op %s", opst[p->tn.op]);
                    408:        }
                    409:        if( o == STARG ) p = p->in.left;  /* STARGs are still STARGS */
                    410:        q = tcopy(q, 1);
                    411:        tfree(p);
                    412:        *p = *q;  /* make the result replace the original */
                    413:        q->in.op = FREE;
                    414: }
                    415: 
                    416: NODE *
                    417: tcopy( p, busyregs )
                    418: register NODE *p;
                    419: int busyregs; 
                    420: {
                    421:        /* make a fresh copy of p */
                    422:        register NODE *q;
                    423:        register r;
                    424: 
                    425:        q=talloc();
                    426:        *q = *p;
                    427:        r = p->tn.rval;
                    428:        if( p->in.op == REG && busyregs) rbusy( r, p->in.type );
                    429:        switch( optype(q->in.op) )
                    430:        {
                    431:        case BITYPE:
                    432:                q->in.right = tcopy(p->in.right, busyregs);
                    433:        case UTYPE:
                    434:                q->in.left = tcopy(p->in.left, busyregs);
                    435:        }
                    436:        return(q);
                    437: }

unix.superglobalmegacorp.com

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