X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=2112fe04cf2d84277ab00d36ae9efca14b93a0aa;hb=6b124543aff56817fcfe6d5b5ff181ac5c790e73;hp=c71baed1cef8a7836adae45426d0382eea1ed906;hpb=ba53fd7f91ba12069198a4164950cb96f14a610a;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index c71baed1c..2112fe04c 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -454,117 +454,93 @@ static tarval *computed_value_Confirm(const ir_node *n) { * There are several case where we can evaluate a Cmp node, see later. */ static tarval *computed_value_Proj_Cmp(const ir_node *n) { - ir_node *a = get_Proj_pred(n); - ir_node *aa = get_Cmp_left(a); - ir_node *ab = get_Cmp_right(a); - long proj_nr = get_Proj_proj(n); + ir_node *cmp = get_Proj_pred(n); + ir_node *left = get_Cmp_left(cmp); + ir_node *right = get_Cmp_right(cmp); + long pn_cmp = get_Proj_proj(n); + ir_mode *mode = get_irn_mode(left); + tarval *tv_l, *tv_r; /* * BEWARE: a == a is NOT always True for floating Point values, as * NaN != NaN is defined, so we must check this here. */ - if (aa == ab && ( - !mode_is_float(get_irn_mode(aa)) || proj_nr == pn_Cmp_Lt || proj_nr == pn_Cmp_Gt) - ) { /* 1.: */ - + if (left == right && (!mode_is_float(mode) || pn_cmp == pn_Cmp_Lt || pn_cmp == pn_Cmp_Gt)) { /* This is a trick with the bits used for encoding the Cmp Proj numbers, the following statement is not the same: - return new_tarval_from_long (proj_nr == pn_Cmp_Eq, mode_b) */ - return new_tarval_from_long (proj_nr & pn_Cmp_Eq, mode_b); + return new_tarval_from_long(pn_cmp == pn_Cmp_Eq, mode_b) */ + return new_tarval_from_long(pn_cmp & pn_Cmp_Eq, mode_b); } - tarval *taa = value_of(aa); - tarval *tab = value_of(ab); - ir_mode *mode = get_irn_mode(aa); + tv_l = value_of(left); + tv_r = value_of(right); - /* - * The predecessors of Cmp are target values. We can evaluate - * the Cmp. - */ - if ((taa != tarval_bad) && (tab != tarval_bad)) { - /* strange checks... */ - pn_Cmp flags = tarval_cmp(taa, tab); + if ((tv_l != tarval_bad) && (tv_r != tarval_bad)) { + /* + * The predecessors of Cmp are target values. We can evaluate + * the Cmp. + */ + pn_Cmp flags = tarval_cmp(tv_l, tv_r); if (flags != pn_Cmp_False) { - return new_tarval_from_long (proj_nr & flags, mode_b); - } - } - /* for integer values, we can check against MIN/MAX */ - else if (mode_is_int(mode)) { - /* MIN <=/> x. This results in true/false. */ - if (taa == get_mode_min(mode)) { - /* a compare with the MIN value */ - if (proj_nr == pn_Cmp_Le) - return get_tarval_b_true(); - else if (proj_nr == pn_Cmp_Gt) - return get_tarval_b_false(); - } - /* x >=/< MIN. This results in true/false. */ - else - if (tab == get_mode_min(mode)) { - /* a compare with the MIN value */ - if (proj_nr == pn_Cmp_Ge) - return get_tarval_b_true(); - else if (proj_nr == pn_Cmp_Lt) - return get_tarval_b_false(); - } - /* MAX >=/< x. This results in true/false. */ - else if (taa == get_mode_max(mode)) { - if (proj_nr == pn_Cmp_Ge) - return get_tarval_b_true(); - else if (proj_nr == pn_Cmp_Lt) - return get_tarval_b_false(); - } - /* x <=/> MAX. This results in true/false. */ - else if (tab == get_mode_max(mode)) { - if (proj_nr == pn_Cmp_Le) - return get_tarval_b_true(); - else if (proj_nr == pn_Cmp_Gt) - return get_tarval_b_false(); - } - - pn_Cmp cmp_result = vrp_cmp(aa, ab); + return new_tarval_from_long (pn_cmp & flags, mode_b); + } + } else if (mode_is_int(mode)) { + /* for integer values, we can check against MIN/MAX */ + pn_Cmp cmp_result; + + if (tv_l == get_mode_min(mode)) { + /* MIN <=/> x. This results in true/false. */ + if (pn_cmp == pn_Cmp_Le) + return tarval_b_true; + else if (pn_cmp == pn_Cmp_Gt) + return tarval_b_false; + } else if (tv_r == get_mode_min(mode)) { + /* x >=/< MIN. This results in true/false. */ + if (pn_cmp == pn_Cmp_Ge) + return tarval_b_true; + else if (pn_cmp == pn_Cmp_Lt) + return tarval_b_false; + } else if (tv_l == get_mode_max(mode)) { + /* MAX >=/< x. This results in true/false. */ + if (pn_cmp == pn_Cmp_Ge) + return tarval_b_true; + else if (pn_cmp == pn_Cmp_Lt) + return tarval_b_false; + } else if (tv_r == get_mode_max(mode)) { + /* x <=/> MAX. This results in true/false. */ + if (pn_cmp == pn_Cmp_Le) + return tarval_b_true; + else if (pn_cmp == pn_Cmp_Gt) + return tarval_b_false; + } + + cmp_result = vrp_cmp(left, right); if (cmp_result != pn_Cmp_False) { if (cmp_result == pn_Cmp_Lg) { - if( proj_nr == pn_Cmp_Eq) { - return get_tarval_b_false(); - } else if(proj_nr == pn_Cmp_Lg) { - return get_tarval_b_true(); + if (pn_cmp == pn_Cmp_Eq) { + return tarval_b_false; + } else if (pn_cmp == pn_Cmp_Lg) { + return tarval_b_true; } } else { - return new_tarval_from_long(cmp_result & proj_nr, mode_b); + return new_tarval_from_long(cmp_result & pn_cmp, mode_b); } } + } else if (mode_is_reference(mode)) { + /* pointer compare */ + ir_node *s_l = skip_Proj(left); + ir_node *s_r = skip_Proj(right); + + if ((is_Alloc(s_l) && tarval_is_null(tv_r)) || + (tarval_is_null(tv_l) && is_Alloc(s_r))) { + /* + * The predecessors are Allocs and (void*)(0) constants. In Firm Allocs never + * return NULL, they raise an exception. Therefore we can predict + * the Cmp result. + */ + return new_tarval_from_long(pn_cmp & pn_Cmp_Lg, mode_b); + } } - /* - * The predecessors are Allocs or (void*)(0) constants. Allocs never - * return NULL, they raise an exception. Therefore we can predict - * the Cmp result. - */ - else { - ir_node *aaa = skip_Proj(aa); - ir_node *aba = skip_Proj(ab); - - if ( ( (/* aa is ProjP and aaa is Alloc */ - is_Proj(aa) - && mode_is_reference(get_irn_mode(aa)) - && is_Alloc(aaa)) - && ( (/* ab is NULL */ - mode_is_reference(get_irn_mode(ab)) - && tarval_is_null(tab)) - || (/* ab is other Alloc */ - is_Proj(ab) - && mode_is_reference(get_irn_mode(ab)) - && is_Alloc(aba) - && (aaa != aba)))) - || (/* aa is NULL and aba is Alloc */ - mode_is_reference(get_irn_mode(aa)) - && tarval_is_null(taa) - && is_Proj(ab) - && mode_is_reference(get_irn_mode(ab)) - && is_Alloc(aba))) - /* 3.: */ - return new_tarval_from_long(proj_nr & pn_Cmp_Lg, mode_b); - } - return computed_value_Cmp_Confirm(a, aa, ab, proj_nr); + return computed_value_Cmp_Confirm(cmp, left, right, pn_cmp); } /* computed_value_Proj_Cmp */ /** @@ -688,7 +664,7 @@ static tarval *computed_value_Proj(const ir_node *proj) { * @param n The node this should be evaluated */ tarval *computed_value(const ir_node *n) { - if(mode_is_int(get_irn_mode(n)) && tarval_is_all_one( + if(mode_is_int(get_irn_mode(n)) && n->vrp.valid && tarval_is_all_one( tarval_or(n->vrp.bits_set, n->vrp.bits_not_set))) { return n->vrp.bits_set; } @@ -2369,7 +2345,7 @@ static ir_node *transform_node_Add(ir_node *n) { } } } - if (mode_is_int(mode)) { + if (mode_is_int(mode) && a->vrp.valid && b->vrp.valid) { tarval *c = tarval_and( tarval_not(a->vrp.bits_not_set), tarval_not(b->vrp.bits_not_set) @@ -3530,14 +3506,14 @@ static ir_node *transform_node_And(ir_node *n) { return n; } - if (is_Const(a) && (tarval_is_all_one(tarval_or(get_Const_tarval(a), + if (is_Const(a) && b->vrp.valid && (tarval_is_all_one(tarval_or(get_Const_tarval(a), b->vrp.bits_not_set)))) { return new_rd_Id(get_irn_dbg_info(n), get_nodes_block(n), b, get_irn_mode(n)); } - if (is_Const(b) && (tarval_is_all_one(tarval_or(get_Const_tarval(b), + if (is_Const(b) && a->vrp.valid && (tarval_is_all_one(tarval_or(get_Const_tarval(b), a->vrp.bits_not_set)))) { return new_rd_Id(get_irn_dbg_info(n), get_nodes_block(n), a, get_irn_mode(n)); @@ -4022,7 +3998,7 @@ static ir_node *transform_node_Proj_Cond(ir_node *proj) { } } else { long num = get_Proj_proj(proj); - if (num != get_Cond_default_proj(n)) { + if (num != get_Cond_default_proj(n) && b->vrp.valid) { /* Try handling with vrp data. We only remove dead parts. */ tarval *tp = new_tarval_from_long(num, get_irn_mode(b));