|
|
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.