xref: /csrg-svn/old/pcc/mip/optim.c (revision 16936)
1*16936Sralph static char *sccsid ="@(#)optim.c	4.2 (Berkeley) 08/13/84";
216935Sralph # include "mfile1"
316935Sralph 
416935Sralph # define SWAP(p,q) {sp=p; p=q; q=sp;}
516935Sralph # define RCON(p) (p->in.right->in.op==ICON)
616935Sralph # define RO(p) p->in.right->in.op
716935Sralph # define RV(p) p->in.right->tn.lval
816935Sralph # define LCON(p) (p->in.left->in.op==ICON)
916935Sralph # define LO(p) p->in.left->in.op
1016935Sralph # define LV(p) p->in.left->tn.lval
1116935Sralph 
1216935Sralph int oflag = 0;
1316935Sralph 
1416935Sralph NODE *
1516935Sralph fortarg( p ) NODE *p; {
1616935Sralph 	/* fortran function arguments */
1716935Sralph 
1816935Sralph 	if( p->in.op == CM ){
1916935Sralph 		p->in.left = fortarg( p->in.left );
2016935Sralph 		p->in.right = fortarg( p->in.right );
2116935Sralph 		return(p);
2216935Sralph 		}
2316935Sralph 
2416935Sralph 	while( ISPTR(p->in.type) ){
2516935Sralph 		p = buildtree( UNARY MUL, p, NIL );
2616935Sralph 		}
2716935Sralph 	return( optim(p) );
2816935Sralph 	}
2916935Sralph 
3016935Sralph 	/* mapping relationals when the sides are reversed */
3116935Sralph short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };
3216935Sralph NODE *
3316935Sralph optim(p) register NODE *p; {
3416935Sralph 	/* local optimizations, most of which are probably machine independent */
3516935Sralph 
3616935Sralph 	register o, ty;
3716935Sralph 	NODE *sp;
3816935Sralph 	int i;
3916935Sralph 	TWORD t;
4016935Sralph 
4116935Sralph 	if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p);
4216935Sralph 	if( oflag ) return(p);
4316935Sralph 	ty = optype( o=p->in.op);
4416935Sralph 	if( ty == LTYPE ) return(p);
4516935Sralph 
4616935Sralph 	if( ty == BITYPE ) p->in.right = optim(p->in.right);
4716935Sralph 	p->in.left = optim(p->in.left);
4816935Sralph 
4916935Sralph 	/* collect constants */
5016935Sralph 
5116935Sralph 	switch(o){
5216935Sralph 
5316935Sralph 	case SCONV:
5416935Sralph 	case PCONV:
5516935Sralph 		return( clocal(p) );
5616935Sralph 
5716935Sralph 	case FORTCALL:
5816935Sralph 		p->in.right = fortarg( p->in.right );
5916935Sralph 		break;
6016935Sralph 
6116935Sralph 	case UNARY AND:
62*16936Sralph 		if( LO(p) != NAME || !andable(p->in.left) ) return(p);
6316935Sralph 
6416935Sralph 		LO(p) = ICON;
6516935Sralph 
6616935Sralph 		setuleft:
6716935Sralph 		/* paint over the type of the left hand side with the type of the top */
6816935Sralph 		p->in.left->in.type = p->in.type;
6916935Sralph 		p->in.left->fn.cdim = p->fn.cdim;
7016935Sralph 		p->in.left->fn.csiz = p->fn.csiz;
7116935Sralph 		p->in.op = FREE;
7216935Sralph 		return( p->in.left );
7316935Sralph 
7416935Sralph 	case UNARY MUL:
7516935Sralph 		if( LO(p) != ICON ) break;
7616935Sralph 		LO(p) = NAME;
7716935Sralph 		goto setuleft;
7816935Sralph 
7916935Sralph 	case MINUS:
8016935Sralph 		if( !nncon(p->in.right) ) break;
8116935Sralph 		RV(p) = -RV(p);
8216935Sralph 		o = p->in.op = PLUS;
8316935Sralph 
8416935Sralph 	case MUL:
8516935Sralph 	case PLUS:
8616935Sralph 	case AND:
8716935Sralph 	case OR:
8816935Sralph 	case ER:
8916935Sralph 		/* commutative ops; for now, just collect constants */
9016935Sralph 		/* someday, do it right */
9116935Sralph 		if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right );
9216935Sralph 		/* make ops tower to the left, not the right */
9316935Sralph 		if( RO(p) == o ){
9416935Sralph 			NODE *t1, *t2, *t3;
9516935Sralph 			t1 = p->in.left;
9616935Sralph 			sp = p->in.right;
9716935Sralph 			t2 = sp->in.left;
9816935Sralph 			t3 = sp->in.right;
9916935Sralph 			/* now, put together again */
10016935Sralph 			p->in.left = sp;
10116935Sralph 			sp->in.left = t1;
10216935Sralph 			sp->in.right = t2;
10316935Sralph 			p->in.right = t3;
10416935Sralph 			}
10516935Sralph 		if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) &&
10616935Sralph 		  conval(p->in.right, MINUS, p->in.left->in.right)){
10716935Sralph 			zapleft:
10816935Sralph 			RO(p->in.left) = FREE;
10916935Sralph 			LO(p) = FREE;
11016935Sralph 			p->in.left = p->in.left->in.left;
11116935Sralph 		}
11216935Sralph 		if( RCON(p) && LO(p)==o && RCON(p->in.left) && conval( p->in.right, o, p->in.left->in.right ) ){
11316935Sralph 			goto zapleft;
11416935Sralph 			}
11516935Sralph 		else if( LCON(p) && RCON(p) && conval( p->in.left, o, p->in.right ) ){
11616935Sralph 			zapright:
11716935Sralph 			RO(p) = FREE;
11816935Sralph 			p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz );
11916935Sralph 			p->in.op = FREE;
12016935Sralph 			return( clocal( p->in.left ) );
12116935Sralph 			}
12216935Sralph 
12316935Sralph 		/* change muls to shifts */
12416935Sralph 
12516935Sralph 		if( o==MUL && nncon(p->in.right) && (i=ispow2(RV(p)))>=0){
12616935Sralph 			if( i == 0 ){ /* multiplication by 1 */
12716935Sralph 				goto zapright;
12816935Sralph 				}
12916935Sralph 			o = p->in.op = LS;
13016935Sralph 			p->in.right->in.type = p->in.right->fn.csiz = INT;
13116935Sralph 			RV(p) = i;
13216935Sralph 			}
13316935Sralph 
13416935Sralph 		/* change +'s of negative consts back to - */
13516935Sralph 		if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){
13616935Sralph 			RV(p) = -RV(p);
13716935Sralph 			o = p->in.op = MINUS;
13816935Sralph 			}
13916935Sralph 		break;
14016935Sralph 
14116935Sralph 	case DIV:
14216935Sralph 		if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright;
14316935Sralph 		break;
14416935Sralph 
14516935Sralph 	case EQ:
14616935Sralph 	case NE:
14716935Sralph 	case LT:
14816935Sralph 	case LE:
14916935Sralph 	case GT:
15016935Sralph 	case GE:
15116935Sralph 	case ULT:
15216935Sralph 	case ULE:
15316935Sralph 	case UGT:
15416935Sralph 	case UGE:
15516935Sralph 		if( !LCON(p) ) break;
15616935Sralph 
15716935Sralph 		/* exchange operands */
15816935Sralph 
15916935Sralph 		sp = p->in.left;
16016935Sralph 		p->in.left = p->in.right;
16116935Sralph 		p->in.right = sp;
16216935Sralph 		p->in.op = revrel[p->in.op - EQ ];
16316935Sralph 		break;
16416935Sralph 
16516935Sralph 		}
16616935Sralph 
16716935Sralph 	return(p);
16816935Sralph 	}
16916935Sralph 
17016935Sralph ispow2( c ) CONSZ c; {
17116935Sralph 	register i;
17216935Sralph 	if( c <= 0 || (c&(c-1)) ) return(-1);
17316935Sralph 	for( i=0; c>1; ++i) c >>= 1;
17416935Sralph 	return(i);
17516935Sralph 	}
17616935Sralph 
17716935Sralph nncon( p ) NODE *p; {
17816935Sralph 	/* is p a constant without a name */
17916935Sralph 	return( p->in.op == ICON && p->tn.rval == NONAME );
18016935Sralph 	}
181