Commit | Line | Data |
---|---|---|
18dc15e5 BJ |
1 | static char *sccsid ="%W% (Berkeley) %G%"; |
2 | # include "mfile1" | |
3 | ||
4 | # define SWAP(p,q) {sp=p; p=q; q=sp;} | |
5 | # define RCON(p) (p->in.right->in.op==ICON) | |
6 | # define RO(p) p->in.right->in.op | |
7 | # define RV(p) p->in.right->tn.lval | |
8 | # define LCON(p) (p->in.left->in.op==ICON) | |
9 | # define LO(p) p->in.left->in.op | |
10 | # define LV(p) p->in.left->tn.lval | |
11 | ||
12 | int oflag = 0; | |
13 | ||
14 | NODE * | |
15 | fortarg( p ) NODE *p; { | |
16 | /* fortran function arguments */ | |
17 | ||
18 | if( p->in.op == CM ){ | |
19 | p->in.left = fortarg( p->in.left ); | |
20 | p->in.right = fortarg( p->in.right ); | |
21 | return(p); | |
22 | } | |
23 | ||
24 | while( ISPTR(p->in.type) ){ | |
25 | p = buildtree( UNARY MUL, p, NIL ); | |
26 | } | |
27 | return( optim(p) ); | |
28 | } | |
29 | ||
30 | /* mapping relationals when the sides are reversed */ | |
31 | short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; | |
32 | NODE * | |
33 | optim(p) register NODE *p; { | |
34 | /* local optimizations, most of which are probably machine independent */ | |
35 | ||
36 | register o, ty; | |
37 | NODE *sp; | |
38 | int i; | |
39 | TWORD t; | |
40 | ||
41 | if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p); | |
42 | if( oflag ) return(p); | |
43 | ty = optype( o=p->in.op); | |
44 | if( ty == LTYPE ) return(p); | |
45 | ||
46 | if( ty == BITYPE ) p->in.right = optim(p->in.right); | |
47 | p->in.left = optim(p->in.left); | |
48 | ||
49 | /* collect constants */ | |
50 | ||
51 | switch(o){ | |
52 | ||
53 | case SCONV: | |
54 | case PCONV: | |
55 | return( clocal(p) ); | |
56 | ||
57 | case FORTCALL: | |
58 | p->in.right = fortarg( p->in.right ); | |
59 | break; | |
60 | ||
61 | case UNARY AND: | |
62 | if( LO(p) != NAME ) cerror( "& error" ); | |
63 | ||
64 | if( !andable(p->in.left) ) return(p); | |
65 | ||
66 | LO(p) = ICON; | |
67 | ||
68 | setuleft: | |
69 | /* paint over the type of the left hand side with the type of the top */ | |
70 | p->in.left->in.type = p->in.type; | |
71 | p->in.left->fn.cdim = p->fn.cdim; | |
72 | p->in.left->fn.csiz = p->fn.csiz; | |
73 | p->in.op = FREE; | |
74 | return( p->in.left ); | |
75 | ||
76 | case UNARY MUL: | |
77 | if( LO(p) != ICON ) break; | |
78 | LO(p) = NAME; | |
79 | goto setuleft; | |
80 | ||
81 | case MINUS: | |
82 | if( !nncon(p->in.right) ) break; | |
83 | RV(p) = -RV(p); | |
84 | o = p->in.op = PLUS; | |
85 | ||
86 | case MUL: | |
87 | case PLUS: | |
88 | case AND: | |
89 | case OR: | |
90 | case ER: | |
91 | /* commutative ops; for now, just collect constants */ | |
92 | /* someday, do it right */ | |
93 | if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right ); | |
94 | /* make ops tower to the left, not the right */ | |
95 | if( RO(p) == o ){ | |
96 | NODE *t1, *t2, *t3; | |
97 | t1 = p->in.left; | |
98 | sp = p->in.right; | |
99 | t2 = sp->in.left; | |
100 | t3 = sp->in.right; | |
101 | /* now, put together again */ | |
102 | p->in.left = sp; | |
103 | sp->in.left = t1; | |
104 | sp->in.right = t2; | |
105 | p->in.right = t3; | |
106 | } | |
107 | if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) && | |
108 | conval(p->in.right, MINUS, p->in.left->in.right)){ | |
109 | zapleft: | |
110 | RO(p->in.left) = FREE; | |
111 | LO(p) = FREE; | |
112 | p->in.left = p->in.left->in.left; | |
113 | } | |
114 | if( RCON(p) && LO(p)==o && RCON(p->in.left) && conval( p->in.right, o, p->in.left->in.right ) ){ | |
115 | goto zapleft; | |
116 | } | |
117 | else if( LCON(p) && RCON(p) && conval( p->in.left, o, p->in.right ) ){ | |
118 | zapright: | |
119 | RO(p) = FREE; | |
120 | p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz ); | |
121 | p->in.op = FREE; | |
122 | return( clocal( p->in.left ) ); | |
123 | } | |
124 | ||
125 | /* change muls to shifts */ | |
126 | ||
127 | if( o==MUL && nncon(p->in.right) && (i=ispow2(RV(p)))>=0){ | |
128 | if( i == 0 ){ /* multiplication by 1 */ | |
129 | goto zapright; | |
130 | } | |
131 | o = p->in.op = LS; | |
132 | p->in.right->in.type = p->in.right->fn.csiz = INT; | |
133 | RV(p) = i; | |
134 | } | |
135 | ||
136 | /* change +'s of negative consts back to - */ | |
137 | if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){ | |
138 | RV(p) = -RV(p); | |
139 | o = p->in.op = MINUS; | |
140 | } | |
141 | break; | |
142 | ||
143 | case DIV: | |
144 | if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; | |
145 | break; | |
146 | ||
147 | case EQ: | |
148 | case NE: | |
149 | case LT: | |
150 | case LE: | |
151 | case GT: | |
152 | case GE: | |
153 | case ULT: | |
154 | case ULE: | |
155 | case UGT: | |
156 | case UGE: | |
157 | if( !LCON(p) ) break; | |
158 | ||
159 | /* exchange operands */ | |
160 | ||
161 | sp = p->in.left; | |
162 | p->in.left = p->in.right; | |
163 | p->in.right = sp; | |
164 | p->in.op = revrel[p->in.op - EQ ]; | |
165 | break; | |
166 | ||
167 | } | |
168 | ||
169 | return(p); | |
170 | } | |
171 | ||
172 | ispow2( c ) CONSZ c; { | |
173 | register i; | |
174 | if( c <= 0 || (c&(c-1)) ) return(-1); | |
175 | for( i=0; c>1; ++i) c >>= 1; | |
176 | return(i); | |
177 | } | |
178 | ||
179 | nncon( p ) NODE *p; { | |
180 | /* is p a constant without a name */ | |
181 | return( p->in.op == ICON && p->tn.rval == NONAME ); | |
182 | } |