X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fvrp.c;h=567f3839ace5a966c426a7679f94454b82f0c28a;hb=3da5ed2598245b896255bc444aaa1768f6098cfe;hp=f6627a9ca46868188a443d5f398a54ecdf9654bf;hpb=7c63b4d0d2dbedf66cc29bac75c32041da03ba7b;p=libfirm diff --git a/ir/ana/vrp.c b/ir/ana/vrp.c index f6627a9ca..567f3839a 100644 --- a/ir/ana/vrp.c +++ b/ir/ana/vrp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2009 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2010 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -25,9 +25,9 @@ */ #include "config.h" -#include "config.h" #include "irtypes.h" #include "vrp.h" +#include "iroptimize.h" #include "irouts.h" #include "irgraph_t.h" #include "irgopt.h" @@ -38,88 +38,69 @@ #include "irop.h" #include "pdeq.h" #include "irphase_t.h" - +#include "debug.h" static char v; static void *VISITED = &v; struct vrp_env_t { waitq *workqueue; + DEBUG_ONLY(firm_dbg_module_t *dbg); }; +static vrp_attr *get_vrp_attr(const ir_node *node) +{ + return (vrp_attr*) get_or_set_irn_phase_info(node, PHASE_VRP); +} + static int vrp_update_node(ir_node *node) { tarval *new_bits_set = get_tarval_bad(); tarval *new_bits_not_set = get_tarval_bad(); tarval *new_range_bottom = get_tarval_bad(); tarval *new_range_top = get_tarval_bad(); - ir_node *new_bits_node = NULL; - ir_node *new_range_node = NULL; enum range_types new_range_type = VRP_UNDEFINED; - enum range_ops new_range_op = VRP_NONE; int something_changed = 0; vrp_attr *vrp; - ir_phase *phase; if (!mode_is_int(get_irn_mode(node))) { return 0; /* we don't optimize for non-int-nodes*/ } - phase = get_irg_phase(get_irn_irg(node), PHASE_VRP); - - ir_printf("update_vrp for %d called\n", get_irn_node_nr(node)); - vrp = phase_get_or_set_irn_data(phase, node); + vrp = get_vrp_attr(node); /* TODO: Check if all predecessors have valid VRP information*/ - - switch (get_irn_opcode(node)) { case iro_Const: { tarval *tv = get_Const_tarval(node); new_bits_set = tv; - new_bits_not_set = tarval_not(tv); + new_bits_not_set = tv; new_range_bottom = tv; new_range_top = tv; new_range_type = VRP_RANGE; break; } - case iro_And: { - vrp_attr *vrp_left, *vrp_right; - ir_node *left, *right; - tarval *tmp_tv; + const vrp_attr *vrp_left, *vrp_right; + const ir_node *left, *right; left = get_And_left(node); right = get_And_right(node); - vrp_left = phase_get_or_set_irn_data(phase, left); - vrp_right = phase_get_or_set_irn_data(phase, right); - - + vrp_left = get_vrp_attr(left); + vrp_right = get_vrp_attr(right); new_bits_set = tarval_and(vrp_left->bits_set, vrp_right->bits_set); - new_bits_not_set = tarval_or(vrp_left->bits_not_set, vrp_right->bits_not_set); - - tmp_tv = tarval_not(vrp_left->bits_set); - tmp_tv = tarval_eor(vrp_left->bits_not_set, tmp_tv); - /*check if one of the predecessors is completely determined*/ - if (tarval_is_null(tmp_tv)) { - new_bits_node = right; - } + new_bits_not_set = tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set); - tmp_tv = tarval_not(vrp_right->bits_set); - tmp_tv = tarval_eor(vrp_right->bits_not_set, tmp_tv); - if (tarval_is_null(tmp_tv)) { - new_bits_node = left; - } break; } case iro_Add: { - vrp_attr *vrp_left, *vrp_right; - vrp_left = phase_get_or_set_irn_data(phase, get_Add_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Add_right(node)); int overflow_top, overflow_bottom; tarval *new_top, *new_bottom; + const vrp_attr *vrp_left, *vrp_right; + vrp_left = get_vrp_attr(get_Add_left(node)); + vrp_right = get_vrp_attr(get_Add_right(node)); if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type == VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING || @@ -147,14 +128,15 @@ static int vrp_update_node(ir_node *node) } case iro_Sub: { - vrp_attr *vrp_left, *vrp_right; - vrp_left = phase_get_or_set_irn_data(phase, get_Sub_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Sub_right(node)); int overflow_top, overflow_bottom; tarval *new_top, *new_bottom; + const vrp_attr *vrp_left, *vrp_right; + vrp_left = get_vrp_attr(get_Sub_left(node)); + vrp_right = get_vrp_attr(get_Sub_right(node)); if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type == - VRP_UNDEFINED) { + VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING || + vrp_right->range_type == VRP_VARYING) { return 0; } @@ -177,151 +159,97 @@ static int vrp_update_node(ir_node *node) } case iro_Or: { - vrp_attr *vrp_left, *vrp_right; - ir_node *left, *right; - tarval *tmp_tv; + const vrp_attr *vrp_left, *vrp_right; - left = get_Or_left(node); - right = get_Or_right(node); - - vrp_left = phase_get_or_set_irn_data(phase, get_Or_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Or_right(node)); + vrp_left = get_vrp_attr(get_Or_left(node)); + vrp_right = get_vrp_attr(get_Or_right(node)); new_bits_set = tarval_or(vrp_left->bits_set, vrp_right->bits_set); - new_bits_not_set = tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set); - - tmp_tv = tarval_not(vrp_left->bits_set); - tmp_tv = tarval_eor(vrp_left->bits_not_set, tmp_tv); - /*check if one of the predecessors is completely determined*/ - if (tarval_is_null(tmp_tv)) { - new_bits_node = right; - } + new_bits_not_set = tarval_or(vrp_left->bits_not_set, vrp_right->bits_not_set); - tmp_tv = tarval_not(vrp_right->bits_set); - tmp_tv = tarval_eor(vrp_right->bits_not_set, tmp_tv); - if (tarval_is_null(tmp_tv)) { - new_bits_node = left; - } break; } case iro_Rotl: { - vrp_attr *vrp_left, *vrp_right; - ir_node *right = get_Rotl_right(node); + const vrp_attr *vrp_left, *vrp_right; + const ir_node *right = get_Rotl_right(node); - vrp_left = phase_get_or_set_irn_data(phase, get_Rotl_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Rotl_right(node)); + vrp_left = get_vrp_attr(get_Rotl_left(node)); + vrp_right = get_vrp_attr(get_Rotl_right(node)); /* We can only compute this if the right value is a constant*/ if (is_Const(right)) { tarval *bits_set, *bits_not_set; bits_set = tarval_rotl(vrp_left->bits_set, get_Const_tarval(right)); bits_not_set = tarval_rotl(vrp_left->bits_not_set, get_Const_tarval(right)); - - new_bits_set = tarval_or(bits_set, vrp->bits_set); - new_bits_not_set = tarval_or(bits_not_set, vrp->bits_not_set); } break; } case iro_Shl: { - vrp_attr *vrp_left, *vrp_right; - ir_node *right = get_Shl_right(node); - vrp_left = phase_get_or_set_irn_data(phase, get_Shl_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Shl_right(node)); + const vrp_attr *vrp_left, *vrp_right; + const ir_node *right = get_Shl_right(node); + vrp_left = get_vrp_attr(get_Shl_left(node)); + vrp_right = get_vrp_attr(get_Shl_right(node)); /* We can only compute this if the right value is a constant*/ if (is_Const(right)) { - tarval *bits_set, *bits_not_set; - ir_mode *m = get_tarval_mode(vrp->bits_not_set); - bits_set = tarval_shl(vrp_left->bits_set, get_Const_tarval(right)); - bits_not_set = tarval_shl(vrp_left->bits_not_set, get_Const_tarval(right)); - - new_bits_set = tarval_or(bits_set, vrp->bits_set); - new_bits_not_set = tarval_or(bits_not_set, vrp->bits_not_set); - - bits_not_set = tarval_not( tarval_shl( - get_mode_all_one(m), - get_Const_tarval(right))); - new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set); - + new_bits_set = tarval_shl(vrp_left->bits_set, get_Const_tarval(right)); + new_bits_not_set = tarval_shl(vrp_left->bits_not_set, get_Const_tarval(right)); } break; } case iro_Shr: { - vrp_attr *vrp_left, *vrp_right; - ir_node *right = get_Shr_right(node); + const vrp_attr *vrp_left, *vrp_right; + const ir_node *right = get_Shr_right(node); - vrp_left = phase_get_or_set_irn_data(phase, get_Shr_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Shr_right(node)); + vrp_left = get_vrp_attr(get_Shr_left(node)); + vrp_right = get_vrp_attr(get_Shr_right(node)); /* We can only compute this if the right value is a constant*/ if (is_Const(right)) { - tarval *bits_set, *bits_not_set; - ir_mode *m = get_tarval_mode(vrp->bits_not_set); - bits_set = tarval_shr(vrp_left->bits_set, get_Const_tarval(right)); - bits_not_set = tarval_shr(vrp_left->bits_not_set, get_Const_tarval(right)); - - new_bits_set = tarval_or(bits_set, vrp->bits_set); - new_bits_not_set = tarval_or(bits_not_set, vrp->bits_not_set); - - bits_not_set = tarval_not( tarval_shr( - get_mode_all_one(m), - get_Const_tarval(right))); - new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set); + new_bits_set = tarval_shr(vrp_left->bits_set, get_Const_tarval(right)); + new_bits_not_set = tarval_shr(vrp_left->bits_not_set, get_Const_tarval(right)); } break; } case iro_Shrs: { - vrp_attr *vrp_left, *vrp_right; - ir_node *right = get_Shrs_right(node); + const vrp_attr *vrp_left, *vrp_right; + const ir_node *right = get_Shrs_right(node); - vrp_left = phase_get_or_set_irn_data(phase, get_Shrs_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Shrs_right(node)); + vrp_left = get_vrp_attr(get_Shrs_left(node)); + vrp_right = get_vrp_attr(get_Shrs_right(node)); /* We can only compute this if the right value is a constant*/ if (is_Const(right)) { - tarval *bits_set, *bits_not_set; - ir_mode *m = get_tarval_mode(vrp->bits_not_set); - bits_set = tarval_shrs(vrp_left->bits_set, get_Const_tarval(right)); - bits_not_set = tarval_shrs(vrp_left->bits_not_set, get_Const_tarval(right)); - - new_bits_set = tarval_or(bits_set, vrp->bits_set); - new_bits_not_set = tarval_or(bits_not_set, vrp->bits_not_set); - - bits_not_set = tarval_not( tarval_shrs( - get_mode_all_one(m), - get_Const_tarval(right))); - new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set); + new_bits_set = tarval_shrs(vrp_left->bits_set, get_Const_tarval(right)); + new_bits_not_set = tarval_shrs(vrp_left->bits_not_set, get_Const_tarval(right)); } break; } case iro_Eor: { - vrp_attr *vrp_left, *vrp_right; + const vrp_attr *vrp_left, *vrp_right; - vrp_left = phase_get_or_set_irn_data(phase, get_Eor_left(node)); - vrp_right = phase_get_or_set_irn_data(phase, get_Eor_right(node)); + vrp_left = get_vrp_attr(get_Eor_left(node)); + vrp_right = get_vrp_attr(get_Eor_right(node)); - tarval *bits_set, *bits_not_set; - bits_not_set = tarval_or( - tarval_and(vrp_left->bits_set, vrp_right->bits_set), - tarval_and(vrp_left->bits_not_set, - vrp_right->bits_not_set)); + new_bits_set = tarval_or( + tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set)), + tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set)); - bits_set = tarval_or( - tarval_and(vrp_left->bits_set, vrp_right->bits_not_set), - tarval_and(vrp_left->bits_not_set, vrp_right->bits_set)); + new_bits_not_set = tarval_not(tarval_or( + tarval_and(vrp_left->bits_set,vrp_right->bits_set), + tarval_and(tarval_not(vrp_left->bits_not_set), + tarval_not(vrp_right->bits_not_set)))); - new_bits_set = tarval_or(bits_set, vrp->bits_set); - new_bits_not_set = tarval_or(bits_not_set, vrp->bits_not_set); break; } case iro_Id: { - vrp_attr *vrp_pred = phase_get_or_set_irn_data(phase, get_Id_pred(node)); + const vrp_attr *vrp_pred = get_vrp_attr(get_Id_pred(node)); new_bits_set = vrp_pred->bits_set; new_bits_not_set = vrp_pred->bits_not_set; new_range_top = vrp_pred->range_top; @@ -331,19 +259,18 @@ static int vrp_update_node(ir_node *node) } case iro_Not: { - vrp_attr *vrp_pred = phase_get_or_set_irn_data(phase, get_Not_op(node)); - new_bits_set = tarval_or(vrp_pred->bits_not_set, vrp->bits_set); - new_bits_not_set = tarval_or(vrp_pred->bits_set, vrp->bits_not_set); + const vrp_attr *vrp_pred = get_vrp_attr(get_Not_op(node)); + new_bits_set = tarval_not(vrp_pred->bits_not_set); + new_bits_not_set = tarval_not(vrp_pred->bits_set); break; } case iro_Conv: { - ir_node *pred = get_Conv_op(node); + const ir_node *pred = get_Conv_op(node); ir_mode *old_mode = get_irn_mode(pred); - vrp_attr *vrp_pred = phase_get_or_set_irn_data(phase, pred); + const vrp_attr *vrp_pred = get_vrp_attr(pred); ir_mode *new_mode; - tarval *bits_not_set; if (!mode_is_int(old_mode)) return 0; @@ -351,14 +278,10 @@ static int vrp_update_node(ir_node *node) new_mode = get_irn_mode(node); /* The second and is needed if target type is smaller*/ - bits_not_set = tarval_not( - tarval_convert_to(get_mode_all_one(old_mode), - new_mode - )); - bits_not_set = tarval_or(bits_not_set, tarval_convert_to(vrp_pred->bits_not_set, new_mode)); - new_bits_not_set = tarval_or(bits_not_set, vrp->bits_not_set); + new_bits_not_set = tarval_convert_to(get_mode_all_one(old_mode), new_mode); + new_bits_not_set = tarval_and(new_bits_not_set, tarval_convert_to(vrp_pred->bits_not_set, new_mode)); new_bits_set = tarval_and( - tarval_not(bits_not_set), tarval_convert_to(vrp_pred->bits_set, new_mode)); + new_bits_not_set, tarval_convert_to(vrp_pred->bits_set, new_mode)); if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == pn_Cmp_Le) { vrp->range_top = vrp_pred->range_top; @@ -371,36 +294,22 @@ static int vrp_update_node(ir_node *node) } case iro_Confirm: { - pn_Cmp cmp = get_Confirm_cmp(node); - ir_node *bound = get_Confirm_bound(node); + const pn_Cmp cmp = get_Confirm_cmp(node); + const ir_node *bound = get_Confirm_bound(node); - /** @todo: Handle non-Const bounds */ if (cmp == pn_Cmp_Lg) { - /** @todo: Is there some way to preserve the information? */ - new_range_type = VRP_ANTIRANGE; + /** @todo: Handle non-Const bounds */ if (is_Const(bound)) { + new_range_type = VRP_ANTIRANGE; new_range_top = get_Const_tarval(bound); new_range_bottom = get_Const_tarval(bound); } } else if (cmp == pn_Cmp_Le) { - if (vrp->range_type == VRP_UNDEFINED) { + if (is_Const(bound)) { new_range_type = VRP_RANGE; - if (is_Const(bound)) { - new_range_top = get_Const_tarval(bound); - } + new_range_top = get_Const_tarval(bound); new_range_bottom = get_tarval_min(get_irn_mode(node)); - } else if (vrp->range_type == VRP_RANGE) { - if (is_Const(bound)) { - if (tarval_cmp(vrp->range_top, - get_Const_tarval(bound)) == pn_Cmp_Le) { - new_range_top = get_Const_tarval(bound); - } - new_range_bottom = get_tarval_min(get_irn_mode(node)); - - } else if (vrp->range_type == VRP_ANTIRANGE) { - /** @todo: How do we manage not to get a never ending loop? */ - } } } break; @@ -409,24 +318,23 @@ static int vrp_update_node(ir_node *node) case iro_Phi: { /* combine all ranges*/ - ir_node *pred = get_Phi_pred(node,0); - vrp_attr *vrp_pred = phase_get_or_set_irn_data(phase, pred); + int num = get_Phi_n_preds(node); + pn_Cmp cmp; + int i; + + const ir_node *pred = get_Phi_pred(node,0); + const vrp_attr *vrp_pred = get_vrp_attr(pred); new_range_top = vrp_pred->range_top; new_range_bottom = vrp_pred->range_bottom; new_range_type = vrp_pred->range_type; new_bits_set = vrp_pred->bits_set; new_bits_not_set = vrp_pred->bits_not_set; - int num = get_Phi_n_preds(node); - pn_Cmp cmp; - int i; - assert(num > 0); - for (i = 1; i < num; i++) { pred = get_Phi_pred(node, i); - vrp_pred = phase_get_or_set_irn_data(phase, pred); + vrp_pred = get_vrp_attr(pred); if (new_range_type == VRP_RANGE && vrp_pred->range_type == VRP_RANGE) { cmp = tarval_cmp(new_range_top, vrp_pred->range_top); @@ -439,8 +347,10 @@ static int vrp_update_node(ir_node *node) } } else { new_range_type = VRP_VARYING; - break; } + new_bits_set = tarval_and(new_bits_set, vrp_pred->bits_set); + new_bits_not_set = tarval_or(new_bits_not_set, + vrp_pred->bits_not_set); } break; @@ -465,6 +375,23 @@ static int vrp_update_node(ir_node *node) is_SymConst(node) is_Sync(node) is_Tuple(node) */ + /* @todo: At this place, we check if the mode of the variable changed. A + * better place for this might be in the convopt.c file + */ + + if (new_bits_set != tarval_bad && get_tarval_mode(new_bits_set) != get_tarval_mode(vrp->bits_set)) { + vrp->bits_set = tarval_convert_to(vrp->bits_set, get_irn_mode(node)); + } + if (new_bits_not_set != tarval_bad && get_tarval_mode(new_bits_not_set) != get_tarval_mode(vrp->bits_not_set)) { + vrp->bits_not_set = tarval_convert_to(vrp->bits_not_set, get_irn_mode(node)); + } + + if (vrp->range_type != VRP_UNDEFINED && new_range_type != VRP_UNDEFINED && get_tarval_mode(new_range_top) != get_tarval_mode(vrp->range_top)) { + /* @todo: We might be able to preserve this range information if it + * fits in */ + vrp->range_type = VRP_VARYING; + } + /* Merge the newly calculated values with those that might already exist*/ if (new_bits_set != tarval_bad) { new_bits_set = tarval_or(new_bits_set, vrp->bits_set); @@ -473,9 +400,8 @@ static int vrp_update_node(ir_node *node) vrp->bits_set = new_bits_set; } } - if (new_bits_not_set != tarval_bad) { - new_bits_not_set = tarval_or(new_bits_not_set, vrp->bits_not_set); + new_bits_not_set = tarval_and(new_bits_not_set, vrp->bits_not_set); if (tarval_cmp(new_bits_not_set, vrp->bits_not_set) != pn_Cmp_Eq) { something_changed = 1; @@ -483,121 +409,69 @@ static int vrp_update_node(ir_node *node) } } - if (vrp->bits_node == NULL && new_bits_node != NULL) { - something_changed = 1; - vrp->bits_node = new_bits_node; - } - if (vrp->range_type == VRP_UNDEFINED && new_range_type != VRP_UNDEFINED) { something_changed = 1; vrp->range_type = new_range_type; vrp->range_bottom = new_range_bottom; vrp->range_top = new_range_top; - vrp->range_op = new_range_op; - vrp->range_node = new_range_node; } else if (vrp->range_type == VRP_RANGE) { if (new_range_type == VRP_RANGE) { - if ((new_range_node == NULL && vrp->range_node == NULL) || - (new_range_node == vrp->range_node && - new_range_op == vrp->range_op)) { - if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Lt) { - something_changed = 1; - vrp->range_bottom = new_range_bottom; - } - if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Gt) { - something_changed = 1; - vrp->range_top = new_range_top; - } + if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Lt) { + something_changed = 1; + vrp->range_bottom = new_range_bottom; } - - /* prefer the absolute value*/ - if (new_range_node == NULL && vrp->range_node != NULL) { + if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Gt) { something_changed = 1; - vrp->range_node = NULL; vrp->range_top = new_range_top; - vrp->range_bottom = new_range_bottom; } } if (new_range_type == VRP_ANTIRANGE) { /* if they are overlapping, cut the range.*/ /* TODO: Maybe we can preserve more information here*/ - if (new_range_node == NULL && vrp->range_node == NULL) { - if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt && - tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) { - something_changed = 1; - vrp->range_bottom = new_range_top; - - } else if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Gt && - tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) { - something_changed = 1; - vrp->range_top = new_range_bottom; - } - - /* We can not handle the case where the anti range is in the*/ - /* range*/ - } + if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt && + tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) { + something_changed = 1; + vrp->range_bottom = new_range_top; - /* prefer the absolute value*/ - if (new_range_node == NULL && vrp->range_node != NULL) { + } else if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Gt && + tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) { something_changed = 1; - vrp->range_node = NULL; - vrp->range_top = new_range_top; - vrp->range_bottom = new_range_bottom; + vrp->range_top = new_range_bottom; } + + /* We can not handle the case where the anti range is in the*/ + /* range*/ + } } else if (vrp->range_type == VRP_ANTIRANGE) { if (new_range_type == VRP_ANTIRANGE) { - if ((new_range_node == NULL && vrp->range_node == NULL) || - (new_range_node == vrp->range_node && - new_range_op == vrp->range_op)) { - if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) { - something_changed = 1; - vrp->range_bottom = new_range_bottom; - } - if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) { - something_changed = 1; - vrp->range_top = new_range_top; - } + if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) { + something_changed = 1; + vrp->range_bottom = new_range_bottom; } - - /* prefer the absolute value*/ - if (new_range_node == NULL && vrp->range_node != NULL) { + if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) { something_changed = 1; - vrp->range_node = NULL; vrp->range_top = new_range_top; - vrp->range_bottom = new_range_bottom; } } if (new_range_type == VRP_RANGE) { - if ((new_range_node == NULL && vrp->range_node == NULL) || - (new_range_node == vrp->range_node && - new_range_op == vrp->range_op)) { - if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt) { - something_changed = 1; - vrp->range_bottom = new_range_top; - } - if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Lt) { - something_changed = 1; - vrp->range_top = new_range_bottom; - } + if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt) { + something_changed = 1; + vrp->range_bottom = new_range_top; } - - /* prefer the absolute value*/ - if (new_range_node == NULL && vrp->range_node != NULL) { + if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Lt) { something_changed = 1; - vrp->range_node = NULL; - vrp->range_top = new_range_top; - vrp->range_bottom = new_range_bottom; + vrp->range_top = new_range_bottom; } } } assert(tarval_is_null( - tarval_and(vrp->bits_set, vrp->bits_not_set))); + tarval_and(vrp->bits_set, tarval_not(vrp->bits_not_set)))); return something_changed; } @@ -614,23 +488,25 @@ static void vrp_first_pass(ir_node *n, void *e) vrp_update_node(n); + assure_irg_outs(get_current_ir_graph()); for (i = get_irn_n_outs(n) - 1; i >=0; --i) { succ = get_irn_out(n, i); if (get_irn_link(succ) == VISITED) { /* we found a loop*/ - waitq_put(env->workqueue, n); + waitq_put(env->workqueue, succ); } } } static void *vrp_init_node(ir_phase *phase, const ir_node *n, void *old) { - ir_printf("initialized node nr: %d\n", get_irn_node_nr(n)); ir_mode *mode; - if (old) { - assert(1==0 && "init called for node already initialized"); - } - vrp_attr *vrp = phase_alloc(phase, sizeof(vrp_attr)); + vrp_attr *vrp; + struct vrp_env_t *env = phase->priv; + + DBG((env->dbg, LEVEL_2, "initialized node nr: %d\n", get_irn_node_nr(n))); + assert(old==NULL && "init called for node already initialized"); + vrp = phase_alloc(phase, sizeof(vrp_attr)); memset(vrp, 0, sizeof(vrp_attr)); /* Initialize the vrp information to default */ @@ -643,10 +519,10 @@ static void *vrp_init_node(ir_phase *phase, const ir_node *n, void *old) * vrp space for non-int nodes. (currently caught by vrp_update_node) */ if (mode_is_int(mode)) { - // We are assuming that 0 is always represented as 0x0000 + /* We are assuming that 0 is always represented as this modes null */ vrp->valid = 1; - vrp->bits_set = new_tarval_from_long(0, mode); - vrp->bits_not_set = new_tarval_from_long(0, mode); + vrp->bits_set = get_mode_null(mode); + vrp->bits_not_set = get_mode_all_one(mode); vrp->range_bottom = get_tarval_top(); vrp->range_top = get_tarval_top(); } else { @@ -656,12 +532,9 @@ static void *vrp_init_node(ir_phase *phase, const ir_node *n, void *old) vrp->range_bottom = get_tarval_bad(); vrp->range_top = get_tarval_bad(); } - vrp->bits_node = NULL; - vrp->range_node = NULL; - vrp->range_op = VRP_NONE; /* TODO: We might be able to set better vrp info at this time, if this is - * a node which is newly created in an already initalized irg + * a node which is newly created in an already initialized irg * * maybe just call vrp_update_node and if it returns one, iterate over * successors @@ -671,22 +544,19 @@ static void *vrp_init_node(ir_phase *phase, const ir_node *n, void *old) void set_vrp_data(ir_graph *irg) { - ir_node *succ, *node; int i; struct vrp_env_t *env; ir_phase *phase; - if (!irg) { - /* no graph, skip */ - return; - } - assure_irg_outs(irg); /* ensure that out edges are consistent*/ - if (!(phase = get_irg_phase(irg, PHASE_VRP))) { - /* this is our first run */ - phase = init_irg_phase(irg, PHASE_VRP, 0, vrp_init_node); - env = phase_alloc(phase, sizeof(struct vrp_env_t)); + phase = irg_get_phase(irg, PHASE_VRP); + if (phase == NULL) { + /* this is our first run */ + phase = new_phase(irg, vrp_init_node); + irg_register_phase(irg, PHASE_VRP, phase); + env = phase_alloc(phase, sizeof(*env)); + FIRM_DBG_REGISTER(env->dbg, "ir.ana.vrp"); phase->priv = env; } else { env = phase->priv; @@ -694,7 +564,6 @@ void set_vrp_data(ir_graph *irg) env->workqueue = new_waitq(); - irg_walk_graph(irg, NULL, vrp_first_pass, env); /* while there are entries in the worklist, continue*/ @@ -738,8 +607,8 @@ pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right) } } - if (!tarval_is_null(tarval_and(vrp_left->bits_set, vrp_right->bits_not_set)) || - !tarval_is_null(tarval_and(vrp_left->bits_not_set, vrp_right->bits_set))) { + if (!tarval_is_null(tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set))) || + !tarval_is_null(tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set))) { return pn_Cmp_Lg; } /* TODO: We can get way more information here*/ @@ -747,15 +616,20 @@ pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right) return pn_Cmp_False; } -vrp_attr *vrp_get_info(const ir_node *n) { - ir_graph *irg = get_irn_irg(n); - ir_phase *phase = get_irg_phase(irg, PHASE_VRP); - +vrp_attr *vrp_get_info(const ir_node *node) +{ + const ir_graph *irg = get_irn_irg(node); + const ir_phase *phase = irg_get_phase(irg, PHASE_VRP); + vrp_attr *vrp; - if (!phase) { + if (phase == NULL) { /* phase has not yet been initialized */ return NULL; } - return phase_get_irn_data(phase, n); + vrp = phase_get_irn_data(phase, node); + if (vrp && vrp->valid) { + return vrp; + } + return NULL; }