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