optim.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 299 行

C
299
字号
#ifndef lintstatic char	*sccsid = " @(#)optim.c	4.1	(ULTRIX)	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//**************************************************************************			Modification History**	David Metsky		15-Jan-86** 001	Added from BSD 4.3 version as part of upgrade.**	Based on:	optim.c		4.6		8/22/85**************************************************************************/# include "pass1.h"# define SWAP(p,q) {sp=p; p=q; q=sp;}# define RCON(p) (p->in.right->in.op==ICON)# define RO(p) p->in.right->in.op# define RV(p) p->in.right->tn.lval# define LCON(p) (p->in.left->in.op==ICON)# define LO(p) p->in.left->in.op# define LV(p) p->in.left->tn.lval	/* is p a constant without a name */# define nncon(p)	((p)->in.op == ICON && (p)->tn.rval == NONAME)int oflag = 0;NODE *fortarg( p ) NODE *p; {	/* fortran function arguments */	if( p->in.op == CM ){		p->in.left = fortarg( p->in.left );		p->in.right = fortarg( p->in.right );		return(p);		}	while( ISPTR(p->in.type) ){		p = buildtree( UNARY MUL, p, NIL );		}	return( optim(p) );	}	/* mapping relationals when the sides are reversed */short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };NODE *optim(p) register NODE *p; {	/* local optimizations, most of which are probably machine independent */	register o, ty;	NODE *sp;	int i;	TWORD t;	if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p);	if( oflag ) return(p);	ty = optype( o=p->in.op);	if( ty == LTYPE ) return(p);	if( ty == BITYPE ) p->in.right = optim(p->in.right);	p->in.left = optim(p->in.left);	/* collect constants */	switch(o){	case SCONV:	case PCONV:		return( clocal(p) );	case FORTCALL:		p->in.right = fortarg( p->in.right );		break;	case UNARY AND:		if( LO(p) != NAME || !andable(p->in.left) ) return(p);		LO(p) = ICON;		setuleft:		/* paint over the type of the left hand side with the type of the top */		p->in.left->in.type = p->in.type;		p->in.left->fn.cdim = p->fn.cdim;		p->in.left->fn.csiz = p->fn.csiz;		p->in.op = FREE;		return( p->in.left );	case UNARY MUL:		if( LO(p) != ICON ) break;		LO(p) = NAME;		goto setuleft;	case MINUS:		if( !nncon(p->in.right) ) break;		RV(p) = -RV(p);		o = p->in.op = PLUS;	case MUL:	case PLUS:	case AND:	case OR:	case ER:		/* commutative ops; for now, just collect constants */		/* someday, do it right */		if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right );		/* make ops tower to the left, not the right */		if( RO(p) == o ){			NODE *t1, *t2, *t3;			t1 = p->in.left;			sp = p->in.right;			t2 = sp->in.left;			t3 = sp->in.right;			/* now, put together again */			p->in.left = sp;			sp->in.left = t1;			sp->in.right = t2;			p->in.right = t3;			}		if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) &&		   conval(p->in.right, MINUS, p->in.left->in.right)){			zapleft:			RO(p->in.left) = FREE;			LO(p) = FREE;			p->in.left = p->in.left->in.left;		}		if( RCON(p) && LO(p)==o && RCON(p->in.left) &&		    conval( p->in.right, o, p->in.left->in.right ) ){			goto zapleft;			}		else if( LCON(p) && RCON(p) &&			 conval( p->in.left, o, p->in.right ) ){			zapright:			RO(p) = FREE;			p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz );			p->in.op = FREE;			return( clocal( p->in.left ) );			}		/* FALL THROUGH */	case ASG MUL:		/* change muls to adds or shifts */		if( (o == MUL || o == ASG MUL) &&		    nncon(p->in.right) && (i=ispow2(RV(p)))>=0){			if( i == 0 ) /* multiplication by 1 */				goto zapright;			if( i == 1 && optype(LO(p)) == LTYPE){				/* multiplication by 2 */				p->in.op = (asgop(o) ? ASG PLUS : PLUS);				o = p->in.op;				ncopy(p->in.right, p->in.left);				}			else {				p->in.op = (asgop(o) ? ASG LS : LS);				o = p->in.op;				p->in.right->in.type = p->in.right->fn.csiz = INT;				RV(p) = i;				}			}		/* change +'s of negative consts back to - */		if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){			RV(p) = -RV(p);			o = p->in.op = MINUS;			}		/* FALL THROUGH */	case ASG AND:	case ASG PLUS:	case ASG MINUS:	case RS:	case LS:		/* Operations with zero */		if( nncon(p->in.right) && RV(p) == 0 ) {			if( o == MUL || o == ASG MUL ||			    o == AND || o == ASG AND ) {				if( asgop(o) )					p->in.op = ASSIGN;				else if( optype(LO(p)) == LTYPE ) {					p->in.op = FREE;					LO(p) = FREE;					p = p->in.right;					}				else					p->in.op = COMOP; /* side effects */				}			else if( o == PLUS || o == MINUS ||				 o == ASG PLUS || o == ASG MINUS ||				 o == OR || o == ER ||				 o == LS || o == RS )				goto zapright;			}		break;	case ASG DIV:	case DIV:		if( nncon( p->in.right ) ){			if( RV(p) == 0 ) uerror("division by zero");			else if( RV(p) == 1 ) goto zapright;			/* Unsigned division by a power of two */			else if( (i=ispow2(RV(p)))>=0 &&				 (ISUNSIGNED(p->in.left->in.type) ||				  ISUNSIGNED(p->in.right->in.type)) ){				p->in.op = (asgop(o) ? ASG RS : RS);				p->in.right->in.type = p->in.right->fn.csiz = INT;				RV(p) = i;				}			}		break;	case ASG MOD:	case MOD:		if( nncon(p->in.right) ){			if( RV(p) == 0 ) uerror("modulus of zero");			else if( RV(p) == 1 ){ /* mod by one gives zero */				RV(p) = 0;				if( asgop(o) )					p->in.op = ASSIGN;				else if( optype(LO(p)) == LTYPE ) {					p->in.op = FREE;					LO(p) = FREE;					p = p->in.right;					}				else					p->in.op = COMOP; /* side effects */				}			else if ((i=ispow2(RV(p)))>=0 &&				 (ISUNSIGNED(p->in.left->in.type) ||				  ISUNSIGNED(p->in.right->in.type)) ){				/* Unsigned mod by a power of two */				p->in.op = (asgop(o) ? ASG AND : AND);				RV(p)--;				}			}		break;	case EQ:	case NE:	case LT:	case LE:	case GT:	case GE:	case ULT:	case ULE:	case UGT:	case UGE:		if( !LCON(p) ) break;		/* exchange operands */		sp = p->in.left;		p->in.left = p->in.right;		p->in.right = sp;		p->in.op = revrel[p->in.op - EQ ];		break;		}	return(p);	}ispow2( c ) CONSZ c; {	register i;	if( c <= 0 || (c&(c-1)) ) return(-1);	for( i=0; c>1; ++i) c >>= 1;	return(i);	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?