Annotation of researchv9/jerq/sgs/comp/allo.c, revision 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.