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