From 46998ae95efac7c88ff94697e104e07de15aa13e Mon Sep 17 00:00:00 2001 From: Jonas Fietz Date: Wed, 10 Feb 2010 03:22:52 +0000 Subject: [PATCH] Add optimizations for Proj after Cond using VRP This uses the vrp information to evaluate int projs. This optimizes cases like: x |= 33; y = x & 96; to y = 1; [r27100] --- ir/ana/vrp.c | 37 +++++++------ ir/ir/iropt.c | 145 ++++++++++++++++++++++++++------------------------ 2 files changed, 95 insertions(+), 87 deletions(-) diff --git a/ir/ana/vrp.c b/ir/ana/vrp.c index 43f65a2f1..8b6067da7 100644 --- a/ir/ana/vrp.c +++ b/ir/ana/vrp.c @@ -624,25 +624,30 @@ ir_graph_pass_t *set_vrp_pass(const char *name) { } pn_Cmp vrp_cmp(ir_node *left, ir_node *right) { - if (left->vrp.range_type == VRP_UNDEFINED || - left->vrp.range_type == VRP_VARYING || + if (!(left->vrp.range_type == VRP_UNDEFINED || + left->vrp.range_type == VRP_VARYING) && !( right->vrp.range_type == VRP_UNDEFINED || - right->vrp.range_type == VRP_VARYING) - return pn_Cmp_False; - - tarval *lefttop = left->vrp.range_top; - tarval *leftbottom = left->vrp.range_bottom; - tarval *righttop = right->vrp.range_top; - tarval *rightbottom = right->vrp.range_bottom; - if (left->vrp.range_type == VRP_RANGE && right->vrp.range_type == - VRP_RANGE) { - if (tarval_cmp(lefttop, rightbottom) == pn_Cmp_Lt) { - return pn_Cmp_Lt; - } - if (tarval_cmp(leftbottom, righttop) == pn_Cmp_Gt) { - return pn_Cmp_Gt; + right->vrp.range_type == VRP_VARYING)) { + + tarval *lefttop = left->vrp.range_top; + tarval *leftbottom = left->vrp.range_bottom; + tarval *righttop = right->vrp.range_top; + tarval *rightbottom = right->vrp.range_bottom; + if (left->vrp.range_type == VRP_RANGE && right->vrp.range_type == + VRP_RANGE) { + if (tarval_cmp(lefttop, rightbottom) == pn_Cmp_Lt) { + return pn_Cmp_Lt; + } + if (tarval_cmp(leftbottom, righttop) == pn_Cmp_Gt) { + return pn_Cmp_Gt; + } + } + } + if (!tarval_is_null(tarval_and(left->vrp.bits_set, right->vrp.bits_not_set)) || + !tarval_is_null(tarval_and(left->vrp.bits_not_set, right->vrp.bits_set))) { + return pn_Cmp_Lg; } // TODO: We can get way more information here diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 777cd3a78..110afbe01 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -472,86 +472,89 @@ static tarval *computed_value_Proj_Cmp(const ir_node *n) { return new_tarval_from_long (proj_nr == pn_Cmp_Eq, mode_b) */ return new_tarval_from_long (proj_nr & pn_Cmp_Eq, mode_b); } - else { - tarval *taa = value_of(aa); - tarval *tab = value_of(ab); - ir_mode *mode = get_irn_mode(aa); + tarval *taa = value_of(aa); + tarval *tab = value_of(ab); + ir_mode *mode = get_irn_mode(aa); - /* - * 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 (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)) { + /* + * 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 (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(); } - /* 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); + if (cmp_result != pn_Cmp_False) { + return new_tarval_from_long(cmp_result & proj_nr, 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.: */ + } + /* + * 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); } /* computed_value_Proj_Cmp */ -- 2.20.1