⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optimize.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
		     */		    ep->nodetype = en_compl;		    ep = optnode (ep);		    #endif /* LONGLONG_BOOTSTRAP */		}		break;	    default:		CANNOT_REACH_HERE ();	    }	    return ep;	}	break;    case en_lt:    case en_le:    case en_gt:    case en_ge:	if (is_icon (ep->v.p[0])) {	    swap_nodes (ep);	}	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	/*	 *       constant expressions	 */	if ((is_icon (ep0) && is_icon (ep1)) ||	    (is_fcon (ep0) && is_fcon (ep1))) {	    ep = dooper (ep);	    return ep;	}	if (is_unsigned_type (ep0->etp) && is_icon (ep1)	    && (ep1->v.u == Ox0UL)) {	    switch (ep->nodetype) {	    case en_lt:		/*		 *      a < 0   =>      0		 */		ep->v.i = 0L;		ep->nodetype = en_icon;		break;	    case en_le:		/*		 *      a <= 0  =>      a == 0		 */		ep->nodetype = en_eq;		ep = optnode (ep);		break;	    case en_gt:		/*		 *      a > 0   =>      a != 0		 */		ep->nodetype = en_ne;		ep = optnode (ep);		break;	    case en_ge:		/*		 *      a >= 1  =>      1		 */		ep->v.i = 1L;		ep->nodetype = en_icon;		break;	    default:		CANNOT_REACH_HERE ();	    }	}	break;    case en_lsh:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep0) && is_icon (ep1)) {	    ep = dooper (ep);	    return ep;	}	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *   a << 0 => a		 */		ep = optnode (ep0);		return ep;	    }	    if (ep1->v.i >= (tp->size*8))	    {		/*		 *   a << n => a, 0		 */		ep1->v.i = 0;		ep1->nodetype = en_icon;		ep->nodetype = en_comma;		ep = optnode (ep);		return ep;	    }	}	break;    case en_rsh:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep0) && is_icon (ep1)) {	    ep = dooper (ep);	    return ep;	}	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *   a >> 0 => a		 */		ep = optnode (ep0);		return ep;	    }	    if ((ep1->v.i >= (tp->size*8)) && is_unsigned_type (tp))	    {		/*		 *   a >> n => a, 0 (unsigned)		 */		ep1->v.i = 0;		ep1->nodetype = en_icon;		ep->nodetype = en_comma;		ep = optnode (ep);		return ep;	    }	}	break;    case en_cond:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep0)) {	    if (ep0->v.i) {		/*		 *              1 ? x, y  => x		 */		ep = optnode (ep1->v.p[0]);	    } else {		/*		 *              0 ? x, y  => y		 */		ep = optnode (ep1->v.p[1]);	    }	    return ep;	}	break;    case en_asadd:    case en_assub:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x += 0  =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	}	break;    case en_asand:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x &= 0  =>      x = 0		 */		ep->nodetype = en_assign;		ep = optnode (ep);		return ep;	    }	    #ifndef LONGLONG_BOOTSTRAP	    if (ep1->v.i == (IVAL) ~(UVAL) 0x0UL) {		/*		 *      x &= ~0 =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	    #endif /* LONGLONG_BOOTSTRAP */	}	break;    case en_asor:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x |= 0  =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	    #ifndef LONGLONG_BOOTSTRAP	    if (ep1->v.i == (IVAL) ~(UVAL) 0x0UL) {		/*		 *      x |= ~0 =>      x = ~0		 */		ep->nodetype = en_assign;		ep = optnode (ep);		return ep;	    }	    #endif /* LONGLONG_BOOTSTRAP */	}	break;    case en_asmul:    case en_asmul2:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x *= 0  =>      x = 0		 */		ep->nodetype = en_assign;		ep = optnode (ep);		return ep;	    }	    if (ep1->v.i == 1L) {		/*		 *      x *= 1  =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	    sc = (IVAL) pwrof2 (ep1->v.i);	    if (sc != (IVAL) -1) {		/*		 *   a *= (2**n)  => a <<= n		 */		ep->v.p[1]->v.i = sc;		ep->nodetype = en_aslsh;		return optnode (ep);	    }	}	break;    case en_comma:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep0)) {	    /*	     *  constant, x =>  x	     */	    ep = optnode (ep1);	    return ep;	}	break;    case en_asrsh:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x <<= 0 =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	    if ((ep1->v.i > tp->size*8) && is_unsigned_type (tp)) {		/*		 *	x <<= n =>	x = 0		 */		ep1->v.i = 0;		ep->nodetype = en_assign;		ep = optnode (ep);		return ep;	    }	}	break;    case en_aslsh:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x <<= 0 =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	    if (ep1->v.i >= (tp->size*8)) {		/*		 *	x <<= n =>	x = 0		 */		ep1->v.i = 0;		ep->nodetype = en_assign;		ep = optnode (ep);		return ep;	    }	}	break;    case en_asxor:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 0L) {		/*		 *      x ^= 0  =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }#ifndef LONGLONG_BOOTSTRAP	    if (ep1->v.i == (IVAL) ~(UVAL) 0x0UL) {		/*		 *	x ^= ~0	=>	~x		 */		ep->nodetype = en_compl;		ep = optnode (ep);		return ep;	    }#endif /* LONGLONG_BOOTSTRAP */	}	break;    case en_asdiv:    case en_asdiv2:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (ep1->v.i == 1L) {		/*		 *      x /= 1  =>      x		 */		ep = optnode (ep0->v.p[0]);		return ep;	    }	}	break;    case en_asmod:	ep0 = ep->v.p[0];	ep1 = ep->v.p[1];	if (is_icon (ep1)) {	    if (is_unsigned_type (tp)) {		sc = (IVAL) pwrof2 (ep1->v.i);		if (sc != (IVAL) -1) {		    /*		     *  x %= (y**2)  => x &= (y-1)		     */		    ep->v.p[1]->v.u = bitmask ((BITSIZE) sc);		    ep->nodetype = en_asand;		    return optnode (ep);		}	    }	}	break;    case en_fcall:    case en_call:
    case en_usercall:    case en_list:    case en_assign:    case en_ref:    case en_ainc:    case en_adec:    case en_deref:	break;    case en_fieldref:	/*	 *        If possible reduce bit-field references to ordinary	 *              references as they are much more efficient	 */#ifdef CPU_DEFINED	ep1 = simplify_fieldref (ep, tp_char, tp_uchar);	if (ep1 == NIL_EXPR) {	    ep1 = simplify_fieldref (ep, tp_short, tp_ushort);	    if (ep1 == NIL_EXPR) {		ep1 = simplify_fieldref (ep, tp_long, tp_ulong);	    }	}	return ep1 ? ep1 : ep;#else	return ep;#endif    default:	break;    }    return ep;}EXPR   *opt0 P1 (EXPR *, ep){    return walkexpr (ep, optnode);}/* *	 xfold() will remove constant nodes and return the values to the *	 calling routines. */static IVAL xfold P1 (EXPR *, ep){    IVAL    i;    if (ep == NIL_EXPR) {	return 0L;    }    switch (ep->nodetype) {    case en_icon:	i = ep->v.i;	ep->v.i = 0L;	return i;    case en_add:	i = xfold (ep->v.p[0]) + xfold (ep->v.p[1]);	return i;    case en_sub:	return xfold (ep->v.p[0]) - xfold (ep->v.p[1]);    case en_mul:	if (is_icon (ep->v.p[0])) {	    return xfold (ep->v.p[1]) * ep->v.p[0]->v.i;	} else if (is_icon (ep->v.p[1])) {	    return xfold (ep->v.p[0]) * ep->v.p[1]->v.i;	}	/*lint -fallthrough */    case en_lsh:    case en_rsh:    case en_div:    case en_mod:    case en_asadd:    case en_assub:    case en_asmul:    case en_asmul2:    case en_asdiv:    case en_asdiv2:    case en_asmod:    case en_and:    case en_land:    case en_or:    case en_lor:    case en_xor:    case en_asand:    case en_asor:    case en_asxor:    case en_comma:    case en_list:    case en_fcall:    case en_call:
    case en_usercall:    case en_assign:    case en_eq:    case en_ne:    case en_lt:    case en_le:    case en_gt:    case en_ge:	ep->v.p[1] = fold_const (ep->v.p[1]);	/*lint -fallthrough */    case en_ref:    case en_fieldref:    case en_compl:    case en_test:    case en_not:    case en_deref:    case en_cast:	ep->v.p[0] = fold_const (ep->v.p[0]);	return 0L;    case en_uminus:	return -xfold (ep->v.p[0]);    default:	break;    }    return 0L;}/* *	 reorganise an expression for optimal constant grouping. */static EXPR *fold_const P1 (EXPR *, ep){    EXPR   *ep1;    IVAL    i;    if (ep == NIL_EXPR) {	return ep;    }    switch (ep->nodetype) {    case en_add:	if (is_icon (ep->v.p[0])) {	    swap_nodes (ep);	}	if (is_icon (ep->v.p[1])) {	    ep->v.p[1]->v.i += xfold (ep->v.p[0]);	    return ep;	}	break;    case en_sub:	if (is_icon (ep->v.p[0])) {	    ep->v.p[0]->v.i -= xfold (ep->v.p[1]);	    return ep;	}	if (is_icon (ep->v.p[1])) {	    ep->v.p[1]->v.i -= xfold (ep->v.p[0]);	    return ep;	}	break;    default:	break;    }    i = xfold (ep);    if (i != 0L) {	/*	 *       strip_icon() is in fact harmless here since this value is	 *       just added to ep	 *	 *       consider in 16-bit mode:	 *	 *                       int day, year;	 *                       day = 365 * (year - 1970);	 *	 *       and look at the code, which is transformed to	 *	 *                       day = 365*year + 1846;	 *	 *       which works if the multiplication returns the lower 16 bits	 *       of the result correctly.	 */	i = strip_icon (i, ep->etp);	ep1 = mk_icon (i, ep->etp);	ep = mk_node (en_add, ep, ep1, ep->etp);    }    return ep;}/* *	 apply all constant optimizations. */EXPR   *constantopt P1 (EXPR *, ep){    ep = fold_const (ep);    return opt0 (ep);}

⌨️ 快捷键说明

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