Annotation of researchv10no/cmd/ccom/common/allo.c, revision 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.