xref: /csrg-svn/old/pcc/mip/optim.c (revision 16935)
1 static char *sccsid ="@(#)optim.c	4.1 (Berkeley) 08/13/84";
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 	}
183