|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.