Annotation of researchv9/jerq/sgs/comp/allo.c, revision 1.1.1.1

1.1       root        1: /*     @(#) allo.c: 1.7 6/26/84        */
                      2: 
                      3: # include "mfile2.h"
                      4: 
                      5: NODE resc[NRGS];
                      6: 
                      7: int busy[NRGS];
                      8: 
                      9: # define TBUSY 0100
                     10: 
                     11: allo0()
                     12: {
                     13:        /* free everything */
                     14:        register i;
                     15: 
                     16:        for( i=0; i<NRGS; ++i )
                     17:        {
                     18:                busy[i] = 0;
                     19:        }
                     20: }
                     21: 
                     22: allo( p, q )
                     23: register NODE *p; 
                     24: register struct optab *q; 
                     25: {
                     26:        register n, i, j;
                     27:        register NODE *presc;
                     28: 
                     29:        n = q->needs;
                     30:        i = 0;
                     31:        /* This code assumes a double reg counts 1 */
                     32:        while( n & NCOUNT )
                     33:        {
                     34:                if( n&NPAIR ) 
                     35:                {
                     36:                        j = freepair( p, n&NMASK );
                     37:                        busy[j] |= TBUSY;
                     38:                        busy[j+1] |= TBUSY;
                     39: #if defined(M32B) && defined(IMPREGAL)
                     40:                        radbl();        /* inform optimizer double reg used */
                     41: #endif
                     42:                }
                     43:                else 
                     44:                {
                     45:                        j = freereg( p, n&NMASK );
                     46:                        busy[j] |= TBUSY;
                     47:                }
                     48:                n -= NREG;
                     49:                presc = &resc[i];
                     50:                presc->in.op = REG;
                     51:                presc->tn.rval = j;
                     52:                presc->tn.type = p->tn.type;
                     53:                presc->tn.lval = 0;
                     54:                presc->in.name = (char *) 0;
                     55:                ++i;
                     56:        }
                     57: 
                     58:        /* turn off "temporarily busy" bit */
                     59:        for( j=0; j<NRGS; ++j )
                     60:        {
                     61:                busy[j] &= ~TBUSY;
                     62:        }
                     63: #ifndef NODBG
                     64:        if( rdebug > 1 )
                     65:        {
                     66:                printf( "allo( %d, %d ), %o", p-node, q->stinline, q->needs );
                     67:                for( j=0; j<i; ++j )
                     68:                {
                     69:                        if( resc[j].tn.op == REG )
                     70:                                printf( ", REG(%d)", resc[j].tn.rval );
                     71:                        else
                     72:                                printf( ", TEMP(%ld)", resc[j].tn.lval );
                     73:                }
                     74:                putchar( '\n' );
                     75:                prbusy( "busy:" );
                     76:        }
                     77: #endif
                     78: }
                     79: 
                     80: int tmpoff;  /* offset of next temp to be allocated */
                     81: 
                     82: int rdebug = 0;
                     83: 
                     84: freetemp( k )
                     85: register k;
                     86: {
                     87:        /* allocate k integers worth of temp space
                     88:        ** we also make the convention that, if the number of words is more than 1,
                     89:        ** it must be aligned for storing doubles... 
                     90:        */
                     91: 
                     92: # ifndef BACKTEMP
                     93:        int t;
                     94: 
                     95:        if( k>1 )
                     96:        {
                     97:                SETOFF( tmpoff, ALDOUBLE );
                     98:        }
                     99: 
                    100:        t = tmpoff;
                    101:        tmpoff += k*SZINT;
                    102:        if( tmpoff > maxtemp ) maxtemp = tmpoff;
                    103:        return(t);
                    104: 
                    105: # else
                    106:        tmpoff += k*SZINT;
                    107:        if( k>1 ) 
                    108:        {
                    109:                SETOFF( tmpoff, ALDOUBLE );
                    110:        }
                    111:        if( tmpoff > maxtemp ) maxtemp = tmpoff;
                    112:        return( -tmpoff );
                    113: # endif
                    114: }
                    115: 
                    116: # ifdef STACK
                    117: /* for stack machines, totally disable the register allocation */
                    118: freereg( p, n )
                    119: NODE *p; 
                    120: {
                    121:        return( 0 );
                    122: }
                    123: 
                    124: freepair( p, n )
                    125: NODE *p; 
                    126: {
                    127:        cerror( "pairs on a stack machine?" );
                    128: }
                    129: 
                    130: rbusy( r, t )
                    131: TWORD t; 
                    132: {
                    133: }
                    134: rfree( r, t )
                    135: TWORD t; 
                    136: {
                    137: }
                    138: 
                    139: regrcl( p )
                    140: NODE *p; 
                    141: {
                    142: }
                    143: # else
                    144: freepair( p, n )
                    145: register NODE *p; 
                    146: register n;
                    147: {
                    148:        /* allocate a register pair */
                    149:        /* p gives the type */
                    150: 
                    151: #ifdef MYPAIR
                    152:        return (mypair(p, n));
                    153: #else
                    154:        register j;
                    155: 
                    156:        if( callop(p->in.op) )
                    157:        {
                    158:                j = callreg(p);
                    159:                if( j&1 ) cerror( "callreg returns bad pair" );
                    160:                if( usable( p, n, j ) ) return( j );
                    161:                /* have allocated callreg first */
                    162:        }
                    163:        if( n&NMASK )
                    164:        {
                    165: #ifdef ODDPAIR                 /* if pair may start on odd reg. */
                    166:                for( j=0; j<NRGS; j++ )
                    167: #else
                    168:                for( j=0; j<NRGS; j+=2 )
                    169: #endif
                    170:                        if( usable(p,n,j) && usable(p,n,j+1))
                    171:                                return( j );
                    172:        }
                    173:        cerror( "allocation fails, op %s", opst[p->tn.op] );
                    174:        /* NOTREACHED */
                    175: #endif
                    176: }
                    177: 
                    178: freereg( p, n )
                    179: register NODE *p; 
                    180: register n;
                    181: {
                    182:        /* allocate a register */
                    183:        /* p gives the type */
                    184: 
                    185:        register j;
                    186:        register int t = optype( p->tn.op );
                    187: 
                    188:        if( callop(p->in.op) )
                    189:        {
                    190:                j = callreg(p);
                    191:                if( usable( p, n, j ) ) return( j );
                    192:                /* have allocated callreg first */
                    193:        }
                    194:        if( n&NMASK )
                    195:        {
                    196:                if( (n&LPREF) && (j = shared( getlt( p, t ) ) ) >= 0 &&
                    197:                   usable( p, n, j ) ) return( j );
                    198:                if( (n&RPREF) && (j = shared( getrt( p, t ) ) ) >= 0 &&
                    199:                   usable( p, n, j ) ) return( j );
                    200:                for( j=0; j<NRGS; ++j ) if( usable(p,n,j) ) return( j );
                    201:        }
                    202:        cerror( "allocation fails, op %s", opst[p->tn.op] );
                    203:        /* NOTREACHED */
                    204: }
                    205: 
                    206: shared( p )
                    207: register NODE *p; 
                    208: {
                    209:        /* simple, at present */
                    210:        /* try to find a single register to share */
                    211:        register r, o;
                    212: #ifndef NODBG
                    213:        if( rdebug ) 
                    214:        {
                    215:                printf( "shared called on:\n" );
                    216:                e2print( p );
                    217:        }
                    218: #endif
                    219:        if( (o=p->tn.op) == REG ) 
                    220:        {
                    221:                r = p->tn.rval;
                    222:                if (r >= NRGS) return ( -1 );
                    223: #ifndef NODBG
                    224:                if( rdebug ) 
                    225:                {
                    226:                        printf( "preference for %s\n", rnames[r] );
                    227:                }
                    228: #endif
                    229:                return( r );
                    230:        }
                    231:        /* we look for shared regs under unary-like ops */
                    232:        switch( optype( o ) ) 
                    233:        {
                    234: 
                    235:        case BITYPE:
                    236:                /* look for simple cases */
                    237:                /* look only on the left */
                    238:        case UTYPE:
                    239:                return( shared( p->in.left ) );
                    240:        }
                    241:        return( -1 );
                    242: }
                    243: 
                    244: usable( p, n, r )
                    245: register NODE *p; 
                    246: register n,r;
                    247: {
                    248:        /* decide if register r is usable in tree p to satisfy need n */
                    249:        /* this does not concern itself with pairs */
                    250: 
                    251:        if( r>= NRGS || (busy[r] & TBUSY) ) return( 0 );
                    252:        if( busy[r] > 1 ) 
                    253:        {
                    254:                /*
                    255:                ** uerror( "register %d too busy", r );
                    256:                */
                    257:                return( 0 );
                    258:        }
                    259:        if( busy[r] == 0 ) {
                    260:                return(1);
                    261:        }
                    262: 
                    263:        /* busy[r] is 1: is there chance for sharing */
                    264:        return( shareit( p, r, n ) );
                    265: 
                    266: }
                    267: 
                    268: shareit( p, r, n )
                    269: register NODE *p; 
                    270: register r;
                    271: int n;
                    272: {
                    273:        /* can we make register r available by sharing from p
                    274:        ** given that the need is n 
                    275:        */
                    276:        register NODE *sub;
                    277:        register int t = optype(p->tn.op);
                    278:        
                    279:        sub = getlt( p, t );
                    280:        if( (n&LSHARE) && ushare( sub, r ) )  {
                    281:                return 1;
                    282:        }
                    283:        sub = getrt( p, t );
                    284:        if( (n&RSHARE) && ushare( sub, r ) ) {
                    285:                return(1);
                    286:        }
                    287:        return(0);
                    288: }
                    289: 
                    290: ushare( p, r )
                    291: register NODE *p; 
                    292: register r;
                    293: {
                    294:        /* can we find register r to share in p */
                    295:        if( p->in.op == REG ) 
                    296:        {
                    297:                if( szty( p->tn.type ) == 2 && r==(p->tn.rval+1) ) return( 1 );
                    298:                return( r == p->tn.rval );
                    299:        }
                    300:        switch( optype( p->tn.op ) )
                    301:        {
                    302:        case BITYPE:
                    303:                if( ushare( p->in.right, r ) ) return( 1 );
                    304:        case UTYPE:
                    305:                if( ushare( p->in.left, r ) ) return( 1 );
                    306:        }
                    307:        return(0);
                    308: }
                    309: 
                    310: regrcl( p )
                    311: register NODE *p; 
                    312: {
                    313:        /* free registers in the tree (or fragment) p */
                    314:        register r;
                    315:        if( !p ) return;
                    316:        r = p->tn.rval;
                    317:        if( p->in.op == REG ) rfree( r, p->in.type );
                    318:        switch( optype( p->tn.op ) )
                    319:        {
                    320:        case BITYPE:
                    321:                regrcl( p->in.right );
                    322:                /* explict assignment to regs not accounted for */
                    323:                if( asgop(p->tn.op) && p->in.left->tn.op == REG ) break;
                    324:        case UTYPE:
                    325:                regrcl( p->in.left );
                    326:        }
                    327: }
                    328: 
                    329: rfree( r, t )
                    330: register TWORD t; 
                    331: register r;
                    332: {
                    333:        /* mark register r free, if it is legal to do so */
                    334:        /* t is the type */
                    335: 
                    336: #ifndef NODBG
                    337:        if( rdebug )
                    338:        {
                    339:                printf( "rfree( %s, ", rnames[r] );
                    340:                t2print( t );
                    341:                printf( " )\n" );
                    342:        }
                    343: #endif
                    344:        if( istreg(r) )
                    345:        {
                    346:                if( --busy[r] < 0 ) cerror( "register overfreed");
                    347:                if( szty( t ) > 1 )
                    348:                {
                    349:                        if( !istreg(r+1) ) cerror( "big register" );
                    350:                        if( --busy[r+1] < 0 ) cerror( "register overfreed" );
                    351:                }
                    352:        }
                    353: }
                    354: 
                    355: rbusy(r, t )
                    356: register r; 
                    357: register TWORD t; 
                    358: {
                    359:        /* mark register r busy */
                    360: 
                    361: #ifndef NODBG
                    362:        if( rdebug )
                    363:        {
                    364:                printf( "rbusy( %s, ", rnames[r] );
                    365:                t2print( t );
                    366:                printf( " )\n" );
                    367:        }
                    368: #endif
                    369:        if( istreg(r) ) 
                    370:        {
                    371:                ++busy[r];
                    372:                if( szty( t ) > 1 )
                    373:                {
                    374:                        if( !istreg(r+1) ) cerror( "big register" );
                    375:                        ++busy[r+1];
                    376:                }
                    377:        }
                    378: }
                    379: 
                    380: prbusy( s )
                    381: char *s;
                    382: {
                    383:        /* print out the busy[] array */
                    384:        int i;
                    385:        printf( "%s [", s );
                    386:        for( i=0; i<NRGS-1; ++i ) printf( "%d,", busy[i] );
                    387:        printf( "%d]\n", busy[NRGS-1] );
                    388: }
                    389: 
                    390: # endif
                    391: 
                    392: rwprint( rw )
                    393: register rw;
                    394: {
                    395:        /* print rewriting rule */
                    396:        register i, flag;
                    397:        static char * rwnames[] = 
                    398:        {
                    399:                "RLEFT",
                    400:                "RRIGHT",
                    401:                "RESC1",
                    402:                "RESC2",
                    403:                "RESC3",
                    404:                "RESCC",
                    405:                "RNOP",
                    406:                0,
                    407:        };
                    408:        if( rw == RNULL )
                    409:        {
                    410:                printf( "RNULL" );
                    411:                return;
                    412:        }
                    413:        flag = 0;
                    414:        for( i=0; rwnames[i]; ++i )
                    415:        {
                    416:                if( rw & (1<<i) )
                    417:                {
                    418:                        if( flag ) printf( "|" );
                    419:                        ++flag;
                    420:                        printf( rwnames[i] );
                    421:                }
                    422:        }
                    423:        if( !flag ) printf( "?%o", rw );
                    424: }
                    425: 
                    426: reclaim( p, rw, goal )
                    427: register NODE *p; 
                    428: register rw, goal;
                    429: {
                    430:        register NODE *q;
                    431:        register o;
                    432: 
                    433:        /* get back stuff */
                    434: #ifndef NODBG
                    435:        if( rdebug )
                    436:        {
                    437:                printf( "reclaim( %d, ", p-node );
                    438:                rwprint( rw );
                    439:                printf( ", " );
                    440:                prgoal( goal );
                    441:                printf( " )\n" );
                    442:        }
                    443: #endif
                    444:        if( !p ) return;
                    445:        /* special cases... */
                    446:        if( (o=p->tn.op) == COMOP )
                    447:        {
                    448:                /* LHS has already been freed; don't free again */
                    449:                regrcl( p->in.right );
                    450:        }
                    451:        else regrcl( p );
                    452:        if( (o==FREE && rw==RNULL) || rw==RNOP ) return;
                    453:        if( callop(o) )
                    454:        {
                    455:                /* check that all scratch regs are free */
                    456:                callchk(p);  /* ordinarily, this is the same as allchk() */
                    457:        }
                    458:        if( rw == RNULL || (goal&FOREFF) )
                    459:        {
                    460:                /* totally clobber, leave nothing */
                    461:                tfree(p);
                    462:                return;
                    463:        }
                    464:        /* handle condition codes specially */
                    465:        if( (goal & FORCC) && (rw&RESCC)) 
                    466:        {
                    467:                /* result is CC register */
                    468:                tfree(p);
                    469:                p->in.op = CCODES;
                    470:                p->tn.lval = 0;
                    471:                p->tn.rval = 0;
                    472:                return;
                    473:        }
                    474:        q = 0;
                    475:        if( rw&RLEFT) q = getl( p );
                    476:        else if( rw&RRIGHT ) q = getr( p );
                    477:        else if( rw&RESC1 ) q = &resc[0];
                    478:        else if( rw&RESC2 ) q = &resc[1];
                    479:        else if( rw&RESC3 ) q = &resc[2];
                    480:        else 
                    481:        {
                    482:                cerror( "illegal reclaim, op %s", opst[p->tn.op]);
                    483:        }
                    484:        if( o == STARG ) p = p->in.left;  /* STARGs are still STARGS */
                    485:        q = tcopy(q);
                    486:        tfree(p);
                    487:        *p = *q;  /* make the result replace the original */
                    488:        q->in.op = FREE;
                    489: }
                    490: 
                    491: NODE *
                    492: tcopy( p )
                    493: register NODE *p; 
                    494: {
                    495:        /* make a fresh copy of p */
                    496:        register NODE *q;
                    497:        register r;
                    498: 
                    499:        q=talloc();
                    500:        *q = *p;
                    501:        r = p->tn.rval;
                    502:        if( p->in.op == REG ) rbusy( r, p->in.type );
                    503:        switch( optype(q->in.op) )
                    504:        {
                    505:        case BITYPE:
                    506:                q->in.right = tcopy(p->in.right);
                    507:        case UTYPE:
                    508:                q->in.left = tcopy(p->in.left);
                    509:        }
                    510:        return(q);
                    511: }
                    512: 
                    513: allchk()
                    514: {
                    515:        /* check to ensure that all register are free */
                    516:        register i;
                    517: 
                    518:        for( i=0; i<NRGS; ++i )
                    519:        {
                    520:                if( busy[i] )
                    521:                {
                    522:                        cerror( "register allocation error");
                    523:                }
                    524:        }
                    525: }
                    526: 
                    527: /* this may not be the best place for this routine... */
                    528: argsize( p )
                    529: register NODE *p; 
                    530: {
                    531:        /* size of the arguments */
                    532:        register t;
                    533:        t = 0;
                    534:        if( p->tn.op == CM )
                    535:        {
                    536:                t = argsize( p->in.left );
                    537:                p = p->in.right;
                    538:        }
                    539:        if( p->tn.type & (TDOUBLE|TFLOAT) )
                    540:        {
                    541:                SETOFF( t, ALDOUBLE );
                    542:                t += SZDOUBLE;
                    543:        }
                    544:        else if( p->tn.type & (TLONG|TULONG) )
                    545:        {
                    546:                SETOFF( t, ALLONG );
                    547:                t += SZLONG;
                    548:        }
                    549:        else if( p->tn.type & TPOINT )
                    550:        {
                    551:                SETOFF( t, ALPOINT );
                    552:                t += SZPOINT;
                    553:        }
                    554:        else if( p->tn.type & TSTRUCT )
                    555:        {
                    556:                SETOFF( t, p->stn.stalign );  /* alignment */
                    557:                t += p->stn.stsize;  /* size */
                    558:        }
                    559:        else 
                    560:        {
                    561:                SETOFF( t, ALINT );
                    562:                t += SZINT;
                    563:        }
                    564:        return( t );
                    565: }

unix.superglobalmegacorp.com

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