X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=43390e837836eb3f99d1f72df3391de382fb4a78;hb=1e550cb45cd91bb74558a634ba49e451f7bf1566;hp=b4cf9fbcda8931453b46f08a267dbba350b2cf5f;hpb=7143a9a314a331e6554c07e9b0d52a039d6bccd1;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index b4cf9fbcd..43390e837 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -23,9 +23,7 @@ * @author Christian Schaefer, Goetz Lindenmaier, Michael Beck * @version $Id$ */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include @@ -48,7 +46,8 @@ #include "opt_confirms.h" #include "opt_polymorphy.h" #include "irtools.h" -#include "xmalloc.h" +#include "irhooks.h" +#include "array_t.h" /* Make types visible to allow most efficient access */ #include "entity_t.h" @@ -137,9 +136,12 @@ static tarval *computed_value_Sub(const ir_node *n) { tarval *ta; tarval *tb; - /* a - a */ - if (a == b && !is_Bad(a)) - return get_mode_null(mode); + /* NaN - NaN != 0 */ + if (! mode_is_float(mode)) { + /* a - a = 0 */ + if (a == b) + return get_mode_null(mode); + } ta = value_of(a); tb = value_of(b); @@ -226,11 +228,14 @@ static tarval *computed_value_Mul(const ir_node *n) { if (ta != tarval_bad && tb != tarval_bad) { return tarval_mul(ta, tb); } else { - /* a*0 = 0 or 0*b = 0 */ - if (ta == get_mode_null(mode)) - return ta; - if (tb == get_mode_null(mode)) - return tb; + /* a * 0 != 0 if a == NaN or a == Inf */ + if (!mode_is_float(mode)) { + /* a*0 = 0 or 0*b = 0 */ + if (ta == get_mode_null(mode)) + return ta; + if (tb == get_mode_null(mode)) + return tb; + } } return tarval_bad; } /* computed_value_Mul */ @@ -1252,18 +1257,19 @@ restart: if (n_mode == mode_b) { n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */ DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV); + return n; } else if (get_mode_arithmetic(n_mode) == get_mode_arithmetic(a_mode)) { - if (smaller_mode(b_mode, a_mode)) { + if (values_in_mode(b_mode, a_mode)) { n = b; /* ConvS(ConvL(xxxS(...))) == xxxS(...) */ DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV); + return n; } } } - if (get_mode_arithmetic(n_mode) == irma_twos_complement && - get_mode_arithmetic(a_mode) == irma_ieee754) { + if (mode_is_int(n_mode) && get_mode_arithmetic(a_mode) == irma_ieee754) { /* ConvI(ConvF(I)) -> I, iff float mantissa >= int mode */ - size_t int_mantissa = get_mode_size_bits(n_mode) - (mode_is_signed(n_mode) ? 1 : 0); - size_t float_mantissa = tarval_ieee754_get_mantissa_size(a_mode); + unsigned int_mantissa = get_mode_size_bits(n_mode) - (mode_is_signed(n_mode) ? 1 : 0); + unsigned float_mantissa = tarval_ieee754_get_mantissa_size(a_mode); if (float_mantissa >= int_mantissa) { n = b; @@ -1277,6 +1283,7 @@ restart: set_Conv_strict(b, 1); n = b; /* ConvA(ConvB(ConvA(...))) == ConvA(...) */ DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV); + return n; } } } @@ -1863,10 +1870,11 @@ static int is_const_Phi(ir_node *n) { if (! is_Phi(n) || get_irn_arity(n) == 0) return 0; - for (i = get_irn_arity(n) - 1; i >= 0; --i) + for (i = get_irn_arity(n) - 1; i >= 0; --i) { if (! is_Const(get_irn_n(n, i))) return 0; - return 1; + } + return 1; } /* is_const_Phi */ typedef tarval *(*tarval_sub_type)(tarval *a, tarval *b, ir_mode *mode); @@ -4341,7 +4349,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) { else if (proj_nr == pn_Cmp_Le || proj_nr == pn_Cmp_Lt) { if (tv != tarval_bad) { /* c >= 0 : Abs(a) <= c ==> (unsigned)(a + c) <= 2*c */ - if (get_irn_op(left) == op_Abs) { // TODO something is missing here + if (is_Abs(left)) { // TODO something is missing here } } } @@ -5278,10 +5286,15 @@ static ir_node *transform_node_Rotl(ir_node *n) { */ static ir_node *transform_node_Conv(ir_node *n) { ir_node *c, *oldn = n; - ir_node *a = get_Conv_op(n); + ir_mode *mode = get_irn_mode(n); + ir_node *a = get_Conv_op(n); - if (is_const_Phi(a)) { - c = apply_conv_on_phi(a, get_irn_mode(n)); + if (mode != mode_b && is_const_Phi(a)) { + /* Do NOT optimize mode_b Conv's, this leads to remaining + * Phib nodes later, because the conv_b_lower operation + * is instantly reverted, when it tries to insert a Convb. + */ + c = apply_conv_on_phi(a, mode); if (c) { DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI); return c; @@ -5289,10 +5302,34 @@ static ir_node *transform_node_Conv(ir_node *n) { } if (is_Unknown(a)) { /* Conv_A(Unknown_B) -> Unknown_A */ - ir_mode *mode = get_irn_mode(n); return new_r_Unknown(current_ir_graph, mode); } + if (mode_is_reference(mode) && + get_mode_size_bits(mode) == get_mode_size_bits(get_irn_mode(a)) && + is_Add(a)) { + ir_node *l = get_Add_left(a); + ir_node *r = get_Add_right(a); + dbg_info *dbgi = get_irn_dbg_info(a); + ir_node *block = get_nodes_block(n); + if(is_Conv(l)) { + ir_node *lop = get_Conv_op(l); + if(get_irn_mode(lop) == mode) { + /* ConvP(AddI(ConvI(P), x)) -> AddP(P, x) */ + n = new_rd_Add(dbgi, current_ir_graph, block, lop, r, mode); + return n; + } + } + if(is_Conv(r)) { + ir_node *rop = get_Conv_op(r); + if(get_irn_mode(rop) == mode) { + /* ConvP(AddI(x, ConvI(P))) -> AddP(x, P) */ + n = new_rd_Add(dbgi, current_ir_graph, block, l, rop, mode); + return n; + } + } + } + return n; } /* transform_node_Conv */ @@ -5315,10 +5352,11 @@ static ir_node *transform_node_End(ir_node *n) { continue; } else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka))) { continue; + } else if (is_Bad(ka)) { + /* no need to keep Bad */ + continue; } - /* FIXME: beabi need to keep a Proj(M) */ - if (is_Phi(ka) || is_irn_keep(ka) || is_Proj(ka)) - in[j++] = ka; + in[j++] = ka; } if (j != n_keepalives) set_End_keepalives(n, j, in); @@ -6016,6 +6054,7 @@ static void normalize_node(ir_node *n) { if (!operands_are_normalized(l, r)) { set_binop_left(n, r); set_binop_right(n, l); + hook_normalize(n); } } } /* normalize_node */ @@ -6103,7 +6142,7 @@ ir_node *identify_remember(pset *value_table, ir_node *n) { * @param value_table The value table * @param n The node to lookup */ -static INLINE ir_node *identify_cons(pset *value_table, ir_node *n) { +static inline ir_node *identify_cons(pset *value_table, ir_node *n) { ir_node *old = n; n = identify_remember(value_table, n);