|
|
1.1 root 1: /* @(#) w3opt.c: 1.4 3/27/84 */
2: /* w3opt.c
3: **
4: ** 3B20S three-instruction window improver
5: **
6: **
7: **
8: ** This module contains improvements for three instruction windows,
9: ** of which there aren't many.
10: */
11:
12: /* #include "defs" -- optim.h takes care of this */
13: #include "optim.h"
14: #include "optutil.h"
15: /* w3opt -- 3-instruction peephole window */
16:
17: boolean /* true if changes made */
18: w3opt(pf,pl)
19: register NODE * pf; /* pointer to first inst. in window */
20: register NODE * pl; /* pointer to last inst. in window */
21: {
22: register NODE * pm = pf->forw; /* point at middle node */
23:
24: int cop1 = pf->op; /* op code number of first inst. */
25: int cop2 = pm->op; /* op code number of second */
26: int cop3 = pl->op; /* ... of third */
27:
28: int src1 ; /* size (bytes) of source of move */
29: int dst1; /* size of destination of move */
30: /* *p++ improvement
31: **
32: ** This improvement rearranges things to facilitate a later 2-instruction
33: ** improvement. We're looking for the kind of code the compiler generates
34: ** (naively) for *p++. We want to make an indirect reference possible:
35: **
36: ** movw O1,R -> movw O1,R
37: ** addw2 &n,O1 -> movX 0(R),O2
38: ** movX 0(R),O2 -> addw2 &n,O1
39: **
40: ** or
41: ** movw O1,R -> movw O1,R
42: ** addw2 &n,O1 -> movX O2,0(R)
43: ** movX O2,0(R) -> addw2 &n,O1
44: **
45: ** if O1 is not a register used by O2
46: ** if instruction following movX is not conditional branch, since
47: ** we're setting different condition codes than before
48: ** in the first case, O2 cannot be a register used by O1.
49: **
50: ** Note that this transformation is always correct because:
51: **
52: ** 1. O1 could not use R, or the first 2 instructions wouldn't work.
53: ** 2. O2 can use or set R without problems.
54: */
55:
56: if (
57: cop1 == MOVW
58: && cop2 == ADDW2
59: && ismove(pl,&src1,&dst1)
60: && isreg(pf->op2)
61: && *pm->op1 == '&' /* immediate operand */
62: && strcmp(pf->op1,pm->op2) == 0
63: && isdeadcc( pl )
64: && ! usesvar(pm->op2,pl->op2) /* O1 can't use O2 */
65: )
66: {
67: char * R = pf->op2; /* point at register string */
68: char * O1 = pf->op1; /* point at first operand */
69: char * O2; /* second operand */
70:
71: if (
72: ( ( O2 = pl->op2, iszoffset(pl->op1,R) ) /* test 0(R) */
73: || ( O2 = pl->op1, iszoffset(pl->op2,R) )
74: )
75: && ! usesvar(O2,O1) /* O2 can't use O1 */
76: && ( isiros( O1 ) || isiros( O2 ) )
77: /* safe for mmio */
78: )
79: {
80: wchange(); /* change the window */
81: lexchin(pm,pl); /* preserve line number info */
82: exchange(pm); /* exchange the last two nodes */
83: swplivecc(pm,pl); /* swap live/dead info on condtion codes */
84: return(true);
85: }
86: }
87: /* Remove redundant compares (see, also w2opt)
88: **
89: ** On the 3B20S, some instructions do not set all of the result
90: ** indicators correctly. Consequently it is only safe to remove
91: ** a compare against zero if the following conditional jump only
92: ** tests those bits which are set. The canonical 3 instruction
93: ** sequence is:
94: **
95: ** op O1,O2[,O3]
96: ** cmpX O[2|3],&0
97: ** jcond foo
98: **
99: ** For the instructions we test here, the only valid conditions to
100: ** jump on are equal (zero) and not equal (non-zero).
101: ** Note that signed tests are picked up correctly in w2opt for those
102: ** instructions that generate correct result indicators.
103: */
104:
105: if (
106: (cop2 == CMPW || cop2 == CMPH || cop2 == CMPB)
107: && strcmp(pm->op2,"&0") == 0
108: && strcmp(dst(pf),pm->op1) == 0
109: && (cop3 == JE || cop3 == JZ || cop3 == JNE || cop3 == JNZ)
110: && (MCOMB <= cop1 && cop1 <= UMODW3)
111: && stype(cop1) == stype(cop2)
112: && isiros(pm->op1) /* safe from mmio */
113: )
114: {
115: wchange();
116: ldelin2(pm); /* preserve line number info */
117: mvlivecc(pm); /* preserve live/dead info on condtion codes */
118: DELNODE(pm); /* delete the compare */
119: return(true);
120: }
121: return(false);
122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.