|
|
1.1 root 1: /*
2: * n2/i386/peep.c
3: * Peephole optimizer.
4: * Look through the code graph, tracking the state of the machine
5: * and deleting or simplifing instructions
6: * which have no effect on the machine state.
7: * This code is machine independent in spirit.
8: * i386.
9: */
10:
11: #ifdef vax
12: #include "INC$LIB:cc2.h"
13: #else
14: #include "cc2.h"
15: #endif
16:
17: /*
18: * The register state table is an AFIELD structure for each machine register,
19: * indexed by machine register code.
20: * An "a_mode" of "A_NONE" means the register is empty
21: * or contains unknown information.
22: */
23: AFIELD regstate[NMREG];
24:
25: /* Forward. */
26: void emptyall();
27: void emptymreg();
28: int noeffect();
29: void simplify();
30: void simpoper();
31: void track();
32: int afcompare();
33: void afupdate();
34: AFIELD *afresolve();
35: int afdependency();
36: void emptyaf();
37:
38: /*
39: * Mainline of the peephole optimizer.
40: * Mark all of the world as unknown.
41: * Sweep the code graph, watching out for labels and machine code.
42: * Any label makes the entire machine state an unknown;
43: * with some flow analysis, this would not really be necessary.
44: */
45: peephole()
46: {
47: register INS *ip;
48: register int rel;
49:
50: emptyall();
51: for (ip=ins.i_fp; ip!=&ins; ip=ip->i_fp) {
52: if (ip->i_type == LLABEL)
53: emptyall();
54: else if (ip->i_type == JUMP) {
55: rel = ip->i_rel;
56: if (rel==ZLOOP || rel==ZLOOPE || rel==ZLOOPNE)
57: emptymreg(MECX);
58: } else if (ip->i_type == CODE) {
59: if (noeffect(ip)) {
60: ip = deleteins(ip, ip->i_fp);
61: ++nuseless;
62: ++changes;
63: } else {
64: simplify(ip);
65: track(ip);
66: }
67: }
68: }
69: }
70:
71: /*
72: * Mark all of the registers in the processor state as empty.
73: * Used whenever the state of the machine is, or will become,
74: * completely undefined.
75: */
76: void
77: emptyall()
78: {
79: register int i;
80:
81: for (i = 0; i < NMREG; i++)
82: emptymreg(i);
83: }
84:
85: /*
86: * Mark machine register "r" as empty
87: * (containing unknown data) in the processor state.
88: * Zap any processor state entries based off the register.
89: */
90: void
91: emptymreg(i) register int i;
92: {
93: register AFIELD *sp;
94:
95: regstate[i].a_mode = A_NONE; /* mark register state empty */
96: for (sp = ®state[0]; sp < ®state[NMREG]; ++sp)
97: if (MODRM(sp) == (A_XB | i))
98: sp->a_mode = A_NONE;
99: }
100:
101: /*
102: * Given a pointer to a CODE node,
103: * return 1 if the instruction has no effect on the machine state.
104: * Look at the operands of the instruction and the values
105: * currently in the registers.
106: * Make sure that an instruction that is being used
107: * to set the flags is not considered to have no effect.
108: */
109: int
110: noeffect(ip) register INS *ip;
111: {
112: register AFIELD *sp, *afp0, *afp1;
113:
114: afp0 = af_p(ip, 0);
115: afp1 = af_p(ip, 1);
116: if (ip->i_op == ZSUB) {
117: if (MOD(afp0) == A_DR && afp0->a_mode == afp1->a_mode) {
118: /* sub reg, reg */
119: sp = ®state[REGM(afp0)];
120: if (MOD(sp) == A_IMM && sp->a_sp == NULL && sp->a_value == 0) {
121: /* Value is already $0; check if flags needed */
122: if ((ip = ip->i_fp) == &ins)
123: return 0;
124: return (ip->i_type!=JUMP || ip->i_rel==ZJMP);
125: }
126: }
127: return 0;
128: } else if (ip->i_op == ZLEA)
129: return afcompare(A_EA, afp0, afp1);
130: else if (ip->i_op == ZMOV)
131: return (MOD(afp0)==A_DR && afcompare(0, afp0, afp1));
132: if (ip->i_fp->i_type == EPILOG && (usedregs & (BESI|BEDI|BEBX)) == 0) {
133: /*
134: * "add %esp, $n" or "pop %ecx" before "leave" has no effect.
135: * Watch out for functions which restore register variables,
136: * the stack adjust is required before the restores.
137: * This knows the details of i386/emit1.c/genepilog()
138: * code generation.
139: */
140: return ((ip->i_op == ZADD && afp0->a_mode == A_RESP)
141: || (ip->i_op == ZPOP && afp0->a_mode == A_RECX));
142: }
143: return 0;
144: }
145:
146: /*
147: * Try to make a CODE node into a simpler node that
148: * performs the same transformation of the machine state.
149: * Currently, this just tries to replace memory operands of dual op instructions
150: * and push instructions with register data and to simplify ZCMP.
151: */
152: void
153: simplify(ip) register INS *ip;
154: {
155: switch (ip->i_op) {
156:
157: case ZCMP:
158: case ZCMPB:
159: case ZCMPW:
160: simpcompare(ip);
161: break;
162:
163: case ZADC:
164: case ZADD:
165: case ZAND:
166: case ZOR:
167: case ZSBB:
168: case ZSUB:
169: case ZXOR:
170: simpoper(af_p(ip, 1));
171: break;
172:
173: case ZPUSH:
174: simpoper(af_p(ip, 0));
175: break;
176: }
177: }
178:
179: /*
180: * The "afp" points at an AFIELD.
181: * If it is a memory AFIELD, look through the processor state
182: * to see if a register contains the same value.
183: * Adjust the AFIELD to refer to the machine register if found.
184: */
185: void
186: simpoper(afp) register AFIELD *afp;
187: {
188: register int i, mode;
189:
190: mode = MOD(afp);
191: if (mode==A_IMM || mode==A_DIR || mode==A_XB) {
192: for (i = 0; i < NMREG; i++) {
193: if (afcompare(0, ®state[i], afp)) {
194: /* Gotcha, simplify the operand. */
195: afp->a_mode = A_DR | i;
196: afp->a_sp = NULL;
197: afp->a_value = 0;
198: ++nsimplify;
199: ++changes;
200: break;
201: }
202: }
203: }
204: }
205:
206: /*
207: * Simplify "cmp %eax, $0" to "or %eax, %eax"
208: * (and similarly for word and byte compare).
209: * The code generator sometimes generates the less efficient form
210: * for TREG patterns, because the TREG could be a stack temporary.
211: */
212: simpcompare(ip) register INS *ip;
213: {
214: register AFIELD *afp1;
215: AFIELD *afp0;
216: int mode, op;
217:
218: afp1 = af_p(ip, 1);
219: if (MOD(afp1) != A_IMM || afp1->a_sp != NULL || afp1->a_value != 0)
220: return; /* second operand is not 0 */
221: afp0 = af_p(ip, 0);
222: mode = MOD(afp0);
223: op = ip->i_op;
224: if (op == ZCMP && mode == A_DR)
225: op = ZOR;
226: else if (op == ZCMPB && mode == A_BR)
227: op = ZORB;
228: else if (op == ZCMPW && mode == A_WR)
229: op = ZORW;
230: else
231: return;
232: ip->i_op = op; /* change ZCMP? to ZOR? */
233: afp1->a_mode = afp0->a_mode; /* change 0 to register */
234: ++nsimplify;
235: ++changes;
236: }
237:
238: /*
239: * Look at the CODE node pointed to by "ip",
240: * and make the required changes to the processor state.
241: * Some special compiler idioms have special checks.
242: * Any instruction for which there is no special knowledge
243: * is assumed to have no effect on the machine state.
244: */
245: void
246: track(ip) register INS *ip;
247: {
248: register AFIELD *sp, *afp0, *afp1;
249: register short destmode;
250: register short destreg;
251: register short length;
252:
253: afp0 = af_p(ip, 0);
254: afp1 = af_p(ip, 1);
255:
256: /* Special idioms. */
257: if (MOD(afp0) == A_DR && afp0->a_mode == afp1->a_mode) {
258: if (ip->i_op == ZOR)
259: return; /* or reg, reg */
260: if (ip->i_op == ZSUB) { /* sub reg, reg */
261: sp = ®state[REGM(afp0)];
262: sp->a_mode = A_IMM; /* register becomes $0 */
263: sp->a_sp = NULL;
264: sp->a_value = 0;
265: return;
266: }
267: }
268:
269: switch (ip->i_op) {
270:
271: /* Clobber all registers. */
272: case ZCALL:
273: case ZICALL:
274: case ZIXCALL:
275: case ZXCALL:
276: case ZCMPS:
277: case ZCMPSB:
278: case ZLODS:
279: case ZLODSB:
280: case ZMOVS:
281: case ZMOVSB:
282: case ZSCAS:
283: case ZSCASB:
284: case ZSTOS:
285: case ZSTOSB:
286: case ZXCHG:
287: case ZXCHGB:
288: emptyall();
289: break;
290:
291: /* Clobber EAX. */
292: case ZCBW:
293: case ZCWDE:
294: case ZDIVB:
295: case ZIDIVB:
296: case ZIMULB:
297: case ZMULB:
298: emptymreg(MEAX);
299: break;
300:
301: /* Clobber ECX. */
302: case ZREPE:
303: case ZREPNE:
304: emptymreg(MECX);
305: break;
306:
307: /* Clobber EDX. */
308: case ZCDQ:
309: case ZCWD:
310: emptymreg(MEDX);
311: break;
312:
313: /* Clobber EAX and EDX. */
314: case ZDIV:
315: case ZIDIV:
316: case ZIMUL:
317: case ZMUL:
318: emptymreg(MEAX);
319: emptymreg(MEDX);
320: break;
321:
322: /* Clobber register or memory. */
323: /* Byte operations. */
324: case ZADDB:
325: case ZANDB:
326: case ZDECB:
327: case ZINCB:
328: case ZNEGB:
329: case ZNOTB:
330: case ZORB:
331: case ZRCLB:
332: case ZRCRB:
333: case ZROLB:
334: case ZRORB:
335: case ZSALB:
336: case ZSARB:
337: case ZSHLB:
338: case ZSHRB:
339: case ZSUBB:
340: case ZXORB:
341: length = 8;
342: goto lab;
343:
344: /* Word operations. */
345: case ZADDW:
346: case ZANDW:
347: case ZDECW:
348: case ZINCW:
349: case ZNEGW:
350: case ZNOTW:
351: case ZORW:
352: case ZSALW:
353: case ZSARW:
354: case ZSHLW:
355: case ZSHRW:
356: case ZSUBW:
357: case ZXORW:
358: case ZIMULW:
359: length = 16;
360: goto lab;
361:
362: /* Dword operations. */
363: case ZADC:
364: case ZADD:
365: case ZAND:
366: case ZINC:
367: case ZDEC:
368: case ZNEG:
369: case ZNOT:
370: case ZOR:
371: case ZPOP:
372: case ZRCL:
373: case ZRCR:
374: case ZROL:
375: case ZROR:
376: case ZSAL:
377: case ZSAR:
378: case ZSBB:
379: case ZSHL:
380: case ZSHR:
381: case ZSUB:
382: case ZXOR:
383: case ZIMULI:
384: length = 32;
385: lab:
386: destmode = MOD(afp0);
387: if (destmode==A_DR || destmode==A_BR || destmode == A_WR) {
388: /* To register. */
389: destreg = REGM(afp0);
390: if (length == 8)
391: destreg &= 0x03; /* e.g. AH -> MEAX */
392: emptymreg(destreg);
393: } else if (length == 32 && (destmode==A_DIR || destmode==A_XB))
394: emptyaf(afp0);
395: else
396: emptyall();
397: break;
398:
399: /* Track LEA. */
400: case ZLEA:
401: afupdate(A_EA, afp0, afp1);
402: break;
403:
404: /* Track MOV. */
405: case ZMOV:
406: destmode = MOD(afp0);
407: if (destmode==A_DR)
408: afupdate(0, afp0, afp1);
409: else if (destmode==A_DIR || destmode==A_XB) {
410: emptyaf(afp0);
411: destmode = MOD(afp1);
412: if (destmode==A_DR)
413: afupdate(0, afp1, afp0);
414: } else
415: emptyall();
416: break;
417:
418: /* Track MOVB, MOVW, MOVSX[B], MOVZX[B]. */
419: case ZMOVB:
420: case ZMOVW:
421: case ZMOVSX:
422: case ZMOVSXB:
423: case ZMOVZX:
424: case ZMOVZXB:
425: destmode = MOD(afp0);
426: destreg = REGM(afp0);
427: if (ip->i_op == ZMOVB && destmode == A_BR)
428: emptymreg(destreg&0x03);
429: else if (ip->i_op == ZMOVW && destmode == A_WR)
430: emptymreg(destreg);
431: else if (destmode==A_DR)
432: emptymreg(destreg);
433: else if (destmode==A_DIR || destmode==A_XB)
434: emptyaf(afp0);
435: else
436: emptyall();
437: break;
438:
439: /* Not explicitly listed above: no effect on state. */
440: default:
441: break;
442: }
443: }
444:
445: /*
446: * Compare two address fields "afp1" and "afp2".
447: * They must be "resolved" to the machine state if registers.
448: * The "afp1" argument always is the register side,
449: * and is required to have the flags that are set in "flags" in the address.
450: * The "afp2" is the lvalue side.
451: */
452: int
453: afcompare(flag, afp1, afp2) int flag; register AFIELD *afp1, *afp2;
454: {
455: register short mode;
456:
457: if ((afp1 = afresolve(afp1, 0)) == NULL)
458: return 0;
459: if ((afp2 = afresolve(afp2, 0)) == NULL)
460: return 0;
461: if (afp1->a_mode==A_NONE || afp2->a_mode==A_NONE)
462: return 0;
463: if (afp1->a_mode != afp2->a_mode)
464: return 0;
465: mode = MOD(afp1);
466: if (mode==A_IMM || mode==A_DIR || mode==A_XB) {
467: if (afp1->a_sp != afp2->a_sp)
468: return 0;
469: if (afp1->a_value != afp2->a_value)
470: return 0;
471: if ((afp1->a_mode&A_EA) != flag)
472: return 0;
473: }
474: return 1;
475: }
476:
477: /*
478: * Update address fields in the processor state table.
479: * The arguments have the same functions
480: * as their namesakes in "afcompare" (above).
481: */
482: void
483: afupdate(flag, afp1, afp2) int flag; register AFIELD *afp1, *afp2;
484: {
485: if ((afp1 = afresolve(afp1, 1)) == NULL)
486: cbotch("afupdate");
487: if ((afp2 = afresolve(afp2, 0)) == NULL)
488: afp1->a_mode = A_NONE;
489: else if (afdependency(afp1, afp2))
490: afp1->a_mode = A_NONE;
491: else {
492: afp1->a_mode = afp2->a_mode;
493: afp1->a_sp = afp2->a_sp;
494: afp1->a_value = afp2->a_value;
495: if (afp1->a_mode != A_NONE)
496: afp1->a_mode |= flag;
497: }
498: }
499:
500: /*
501: * Resolve an address descriptor to the entry in the processor state.
502: * If the entry will not map for some reason, return NULL.
503: * If "flag" is set the register descriptor is flushed.
504: */
505: AFIELD *
506: afresolve(afp, flag) register AFIELD *afp; int flag;
507: {
508: register short mode, reg;
509:
510: if ((mode = MOD(afp)) == A_BR || mode == A_WR)
511: return NULL; /* do not map byte and word registers */
512: if (mode == A_DR) {
513: reg = REGM(afp);
514: if (flag != 0)
515: emptymreg(reg);
516: return ®state[reg];
517: }
518: return afp;
519: }
520:
521: /*
522: * Given two AFIELD nodes,
523: * return true if the second depends on the value of the first.
524: * This checks for instructions like "mov bx,3[bx]",
525: * where you must not set the contents of "bx" to be "3[bx]".
526: */
527: int
528: afdependency(afp1, afp2) register AFIELD *afp1, *afp2;
529: {
530: register int i;
531:
532: for (i = 0; i < NMREG; i++)
533: if (afp1 == ®state[i])
534: return (MODRM(afp2) == (A_XB | i));
535: return 0;
536: }
537:
538: /*
539: * Purge any processor state entries that
540: * think they are holding the value of "afp".
541: * This is used to purge the state of the world when a register
542: * is stored into memory.
543: */
544: void
545: emptyaf(afp)
546: register AFIELD *afp;
547: {
548: register int i;
549:
550: for (i = 0; i < NMREG; i++)
551: if (afcompare(0, ®state[i], afp))
552: emptymreg(i);
553: }
554:
555: /* end of n2/i386/peep.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.