|
|
1.1 ! root 1: /* @(#) optdir.c: 1.3 6/26/84 */ ! 2: /* optdir.c ! 3: ** ! 4: ** Optimization Director ! 5: ** ! 6: ** The routines in this file monitor the information in ! 7: ** the machine independent portion of the compiler ! 8: ** and write comments in the assembly output informing ! 9: ** the machine dependent portion of the optimizer ! 10: ** that certain optimizations are possible. ! 11: ** ! 12: */ ! 13: ! 14: # include "mfile1.h" ! 15: # include "storclass.h" ! 16: ! 17: extern FILE *outfile; ! 18: extern int xdebug; ! 19: ! 20: #ifdef IMPREGAL ! 21: ! 22: /* Register allocation ! 23: ** Routines ra* direct the 'register allocation' optimization. ! 24: ** The optimization attempts to assign selected quantities, ! 25: ** i.e., ! 26: ** local variables that ! 27: ** - are simple (are not related to arrays, structures, ! 28: ** or unions) ! 29: ** - do not have their address taken explicitly with '&' ! 30: ** incoming arguments that ! 31: ** - are simple ! 32: ** - are in a procedure where no argument has its address taken ! 33: ** expilitly with an '&' ! 34: ** to available scratch or user registers. ! 35: ** ! 36: ** An estimator is computed for each qualifying quantity by the formulas: ! 37: ** ! 38: ** local variables ! 39: ** RAPOEST * (FORWEIGHT or WHWEIGHT)**(loop depth) ! 40: ** ----------------------------------------------- ! 41: ** (BRWEIGHT)**(branch depth) ! 42: ** ! 43: ** arguments ! 44: ** RAPOEST * (FORWEIGHT or WHWEIGHT)**(loop depth) ! 45: ** ----------------------------------------------- - 9 ! 46: ** (BRWEIGHT)**(branch depth) ! 47: ** ! 48: ** where '**' denotes exponentiation. ! 49: ** The quantities are ordered by decreasing estimator and up to HIGHSZ ! 50: ** are printed in the form ! 51: ** #REGAL <estimator> <storage class> <ident> <length> ! 52: ** ! 53: */ ! 54: ! 55: #define RAPAYOFF 3 /* operand payoff estimator in cycles */ ! 56: #define FORWEIGHT 10 /* weight to emphasize code in 'for' loops */ ! 57: #define WHWEIGHT 5 /* weight to emphasize code in 'while' and ! 58: ** 'do-while' loops */ ! 59: #define BRWEIGHT 10 /* weight to de-emphasize code in branches */ ! 60: #define HIGHSZ 20 /* size of table for sorting estimators */ ! 61: ! 62: int estimtab[SYMTSZ]; /* payoff estimator for each variable, ! 63: ** set to -1 if address of variable is taken */ ! 64: NODE *lastp; /* pointer to last NAME node processed */ ! 65: int lastid; /* index to symbol table for last NAME node */ ! 66: int dblflg = 0; /* flag indicating presence of doubles */ ! 67: ! 68: struct hinode { /* ordered table of variables with highest estimators */ ! 69: int hiestim; /* estimator of cycle payoff */ ! 70: int hiscl; /* scl of quant to put in reg */ ! 71: int hiident; /* identification of quantity: ! 72: * local offset ! 73: * argument offset*/ ! 74: int hilen; /* length in bytes of quantity */ ! 75: } high[HIGHSZ]; ! 76: ! 77: /* table status */ ! 78: ! 79: #define EMPTY -2 ! 80: #define ADDRSD -1 ! 81: ! 82: void ! 83: rainit() ! 84: ! 85: { ! 86: register int *p; ! 87: struct hinode *hp; ! 88: ! 89: /* initialize estimator table */ ! 90: for( p = estimtab; p < estimtab + SYMTSZ; p++ ) *p = EMPTY; ! 91: ! 92: /* initialize hi table */ ! 93: for( hp = high; hp < high + HIGHSZ; hp++ ) hp->hiestim = EMPTY; ! 94: } ! 95: ! 96: void ! 97: radbl() ! 98: { ! 99: dblflg = 1; ! 100: #ifndef NODBG ! 101: if (xdebug > 1 && dblflg) ! 102: fprintf(outfile, "radbl() sets dblflg\n"); ! 103: #endif ! 104: } ! 105: ! 106: void ! 107: raname(p) ! 108: NODE *p; ! 109: ! 110: { ! 111: int type, class; ! 112: int old; ! 113: ! 114: /* check for simpleness */ ! 115: type = stab[idname].stype; ! 116: if( !( (CHAR <= type && type <= LONG) || ! 117: (UCHAR <= type && type <= ULONG) || ! 118: (ULONG < type) ) ) return; ! 119: if( ISFTN(type) || ISARY(type) ) return; ! 120: if( stab[idname].slevel > 2 ) return; ! 121: ! 122: /* compute per reference payoff */ ! 123: old = estimtab[idname]; ! 124: #ifndef NODBG ! 125: if (xdebug) ! 126: { ! 127: fprintf(outfile, ! 128: "raname(0x%lx)\tstab[%d] `%s' sclass %s cur.est %d\n", ! 129: p, idname, stab[idname].sname, ! 130: scnames(stab[idname].sclass), old); ! 131: } ! 132: #endif ! 133: /* ! 134: * Don't count putting the PARAM into the REGISTER ! 135: * for REGISTER PARAM's. ! 136: */ ! 137: if( blevel >= 2 && estimtab[idname] != ADDRSD ) ! 138: switch( stab[idname].sclass ) { ! 139: int i, weight; ! 140: ! 141: case PARAM: ! 142: case AUTO: ! 143: if( estimtab[idname] == EMPTY ) estimtab[idname] = 0; ! 144: weight = RAPAYOFF; ! 145: for( i = 1; i <= fordepth; i++ ) { ! 146: if( weight >= 10000 ) break; ! 147: weight *= FORWEIGHT; ! 148: } ! 149: for( i = 1; i <= whdepth; i++ ) { ! 150: if( weight >= 10000 ) break; ! 151: weight *= WHWEIGHT; ! 152: } ! 153: for( i = 1; i <= brdepth; i++ ) { ! 154: weight /= BRWEIGHT; ! 155: } ! 156: estimtab[idname] += weight; ! 157: } ! 158: lastid = idname; ! 159: lastp = p; ! 160: #ifndef NODBG ! 161: if (xdebug > 1) ! 162: { ! 163: fprintf(outfile, ! 164: "`%s' type=%d class=%d level=%d flags=%x offset=%d\n", ! 165: stab[idname].sname, stab[idname].stype, ! 166: stab[idname].sclass, stab[idname].slevel, ! 167: stab[idname].sflags, stab[idname].offset); ! 168: fprintf(outfile, "\tfordepth=%d whdepth=%d brdepth=%d change=%d estimator=%d\n", ! 169: fordepth, whdepth, brdepth, estimtab[idname]-old, ! 170: estimtab[idname]); ! 171: } ! 172: #endif ! 173: } ! 174: ! 175: void ! 176: raua(p) ! 177: NODE *p; ! 178: ! 179: { ! 180: /* mark variables with address taken */ ! 181: if( p == lastp ) estimtab[lastid] = ADDRSD; ! 182: } ! 183: ! 184: void ! 185: raftn() ! 186: ! 187: { ! 188: ! 189: register int i, j, k, ei; ! 190: struct hinode *hp; ! 191: struct symtab *sp; ! 192: ! 193: /* check for end of function */ ! 194: if( blevel != 2 ) return; ! 195: ! 196: /* check for doubles */ ! 197: if( dblflg == 0 ) fprintf( outfile, "#REGAL\t%d\tNODBL\n", 0 ); ! 198: else return; ! 199: ! 200: /* check for args with address taken */ ! 201: for( i = 0; i < SYMTSZ; i++ ) { ! 202: if( stab[i].sclass == PARAM && estimtab[i] == ADDRSD ) { ! 203: for( j = 0; j < SYMTSZ; j++ ) ! 204: if( stab[j].sclass == PARAM ) ! 205: estimtab[j] = ADDRSD; ! 206: break; ! 207: } ! 208: } ! 209: ! 210: /* insert entries from symbol table in decreasing order */ ! 211: for( i = 0; i < SYMTSZ; i++ ) { ! 212: ei = estimtab[i]; ! 213: if( ei < 0 ) continue; ! 214: sp = &stab[i]; ! 215: ! 216: /* include cost for arg */ ! 217: if( sp->sclass == PARAM ) ei -= 9; ! 218: if( ei < 0 ) continue; ! 219: ! 220: /* insertion sort */ ! 221: for( j = 0; j < HIGHSZ; j++ ) { ! 222: if( ei > high[j].hiestim ) { ! 223: for( k = 8; k >= j; k-- ) { ! 224: hp = &high[k]; ! 225: (hp+1)->hiestim = hp->hiestim; ! 226: (hp+1)->hiscl = hp->hiscl; ! 227: (hp+1)->hiident = hp->hiident; ! 228: (hp+1)->hilen = hp->hilen; ! 229: } ! 230: hp = &high[j]; ! 231: hp->hiestim = ei; ! 232: hp->hiscl = sp->sclass; ! 233: hp->hiident = sp->offset; ! 234: switch( sp->stype ) { ! 235: case CHAR: ! 236: case UCHAR: ! 237: hp->hilen = 1; break; ! 238: case SHORT: ! 239: case USHORT: ! 240: hp->hilen = 2; break; ! 241: default: ! 242: hp->hilen = 4; break; ! 243: } ! 244: break; ! 245: } ! 246: } ! 247: } ! 248: ! 249: /* print entries */ ! 250: for( i = 0; i < HIGHSZ; i++ ) { ! 251: hp = &high[i]; ! 252: if( hp->hiestim == EMPTY ) break; ! 253: fprintf( outfile, "#REGAL\t%d", hp->hiestim ); ! 254: switch( hp->hiscl ) { ! 255: case AUTO: ! 256: fprintf( outfile, "\tAUTO \t%d(%%fp)", ! 257: hp->hiident/SZCHAR ); ! 258: break; ! 259: case PARAM: ! 260: fprintf( outfile, "\tPARAM\t%d(%%ap)", ! 261: hp->hiident/SZCHAR ); ! 262: break; ! 263: } ! 264: fprintf( outfile, "\t%d\n", hp->hilen ); ! 265: } ! 266: } ! 267: #endif /* IMPREGAL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.