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