X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fvrp.c;h=567f3839ace5a966c426a7679f94454b82f0c28a;hb=3da5ed2598245b896255bc444aaa1768f6098cfe;hp=818a8a52aba6e36b881e4bd7bf4ada0e612067ca;hpb=bd7a92059bd8e11ed5f3abca137a9f099689ca83;p=libfirm diff --git a/ir/ana/vrp.c b/ir/ana/vrp.c index 818a8a52a..567f3839a 100644 --- a/ir/ana/vrp.c +++ b/ir/ana/vrp.c @@ -27,6 +27,7 @@ #include "irtypes.h" #include "vrp.h" +#include "iroptimize.h" #include "irouts.h" #include "irgraph_t.h" #include "irgopt.h" @@ -81,8 +82,8 @@ static int vrp_update_node(ir_node *node) break; } case iro_And: { - vrp_attr *vrp_left, *vrp_right; - ir_node *left, *right; + const vrp_attr *vrp_left, *vrp_right; + const ir_node *left, *right; left = get_And_left(node); right = get_And_right(node); @@ -97,7 +98,7 @@ static int vrp_update_node(ir_node *node) case iro_Add: { int overflow_top, overflow_bottom; tarval *new_top, *new_bottom; - vrp_attr *vrp_left, *vrp_right; + 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)); @@ -129,7 +130,7 @@ static int vrp_update_node(ir_node *node) case iro_Sub: { int overflow_top, overflow_bottom; tarval *new_top, *new_bottom; - vrp_attr *vrp_left, *vrp_right; + 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)); @@ -158,7 +159,7 @@ static int vrp_update_node(ir_node *node) } case iro_Or: { - vrp_attr *vrp_left, *vrp_right; + const vrp_attr *vrp_left, *vrp_right; vrp_left = get_vrp_attr(get_Or_left(node)); vrp_right = get_vrp_attr(get_Or_right(node)); @@ -170,8 +171,8 @@ static int vrp_update_node(ir_node *node) } 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 = get_vrp_attr(get_Rotl_left(node)); vrp_right = get_vrp_attr(get_Rotl_right(node)); @@ -186,8 +187,8 @@ static int vrp_update_node(ir_node *node) } case iro_Shl: { - vrp_attr *vrp_left, *vrp_right; - ir_node *right = 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)); @@ -200,8 +201,8 @@ static int vrp_update_node(ir_node *node) } 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 = get_vrp_attr(get_Shr_left(node)); vrp_right = get_vrp_attr(get_Shr_right(node)); @@ -215,8 +216,8 @@ static int vrp_update_node(ir_node *node) } 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 = get_vrp_attr(get_Shrs_left(node)); vrp_right = get_vrp_attr(get_Shrs_right(node)); @@ -230,8 +231,7 @@ static int vrp_update_node(ir_node *node) } case iro_Eor: { - tarval *bits_set, *bits_not_set; - vrp_attr *vrp_left, *vrp_right; + const vrp_attr *vrp_left, *vrp_right; vrp_left = get_vrp_attr(get_Eor_left(node)); vrp_right = get_vrp_attr(get_Eor_right(node)); @@ -249,7 +249,7 @@ static int vrp_update_node(ir_node *node) } case iro_Id: { - vrp_attr *vrp_pred = get_vrp_attr(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; @@ -259,16 +259,16 @@ static int vrp_update_node(ir_node *node) } case iro_Not: { - vrp_attr *vrp_pred = get_vrp_attr(get_Not_op(node)); + 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 = get_vrp_attr(pred); + const vrp_attr *vrp_pred = get_vrp_attr(pred); ir_mode *new_mode; @@ -294,8 +294,8 @@ 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); if (cmp == pn_Cmp_Lg) { @@ -322,8 +322,8 @@ static int vrp_update_node(ir_node *node) pn_Cmp cmp; int i; - ir_node *pred = get_Phi_pred(node,0); - vrp_attr *vrp_pred = get_vrp_attr(pred); + 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; @@ -375,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); @@ -603,14 +620,14 @@ 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 == NULL) { /* phase has not yet been initialized */ return NULL; } - - vrp_attr *vrp = phase_get_irn_data(phase, node); + vrp = phase_get_irn_data(phase, node); if (vrp && vrp->valid) { return vrp; }