diff options
Diffstat (limited to 'gcc/vr-values.cc')
-rw-r--r-- | gcc/vr-values.cc | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc index 6f8583c..38f204e 100644 --- a/gcc/vr-values.cc +++ b/gcc/vr-values.cc @@ -177,7 +177,7 @@ vr_values::get_value_range (const_tree var, } bool -vr_values::range_of_expr (irange &r, tree expr, gimple *stmt) +vr_values::range_of_expr (vrange &r, tree expr, gimple *stmt) { if (!gimple_range_ssa_p (expr)) return get_tree_range (r, expr, stmt); @@ -1630,6 +1630,20 @@ compare_range_with_value (enum tree_code comp, const value_range *vr, gcc_unreachable (); } +static inline void +fix_overflow (tree *min, tree *max) +{ + /* Even for valid range info, sometimes overflow flag will leak in. + As GIMPLE IL should have no constants with TREE_OVERFLOW set, we + drop them. */ + if (TREE_OVERFLOW_P (*min)) + *min = drop_tree_overflow (*min); + if (TREE_OVERFLOW_P (*max)) + *max = drop_tree_overflow (*max); + + gcc_checking_assert (compare_values (*min, *max) != 1); +} + /* Given a VAR in STMT within LOOP, determine the bounds of the variable and store it in MIN/MAX and return TRUE. If no bounds could be determined, return FALSE. */ @@ -1640,6 +1654,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, { tree init, step, chrec, tmin, tmax, type = TREE_TYPE (var); enum ev_direction dir; + int_range<2> r; chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var)); @@ -1647,7 +1662,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, if (is_gimple_min_invariant (chrec)) { *min = *max = chrec; - goto fix_overflow; + fix_overflow (min, max); + return true; } if (TREE_CODE (chrec) != POLYNOMIAL_CHREC) @@ -1659,13 +1675,17 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, if (!init || !step) return false; + Value_Range rinit (TREE_TYPE (init)); + Value_Range rstep (TREE_TYPE (step)); /* If INIT is an SSA with a singleton range, set INIT to said singleton, otherwise leave INIT alone. */ - if (TREE_CODE (init) == SSA_NAME) - query->get_value_range (init, stmt)->singleton_p (&init); + if (TREE_CODE (init) == SSA_NAME + && query->range_of_expr (rinit, init, stmt)) + rinit.singleton_p (&init); /* Likewise for step. */ - if (TREE_CODE (step) == SSA_NAME) - query->get_value_range (step, stmt)->singleton_p (&step); + if (TREE_CODE (step) == SSA_NAME + && query->range_of_expr (rstep, step, stmt)) + rstep.singleton_p (&step); /* If STEP is symbolic, we can't know whether INIT will be the minimum or maximum value in the range. Also, unless INIT is @@ -1699,7 +1719,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, if (TREE_CODE (step) == INTEGER_CST && is_gimple_val (init) && (TREE_CODE (init) != SSA_NAME - || query->get_value_range (init, stmt)->kind () == VR_RANGE)) + || (query->range_of_expr (r, init, stmt) + && r.kind () == VR_RANGE))) { widest_int nit; @@ -1724,7 +1745,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, { value_range maxvr, vr0, vr1; if (TREE_CODE (init) == SSA_NAME) - vr0 = *(query->get_value_range (init, stmt)); + query->range_of_expr (vr0, init, stmt); else if (is_gimple_min_invariant (init)) vr0.set (init); else @@ -1737,10 +1758,10 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, /* Likewise if the addition did. */ if (maxvr.kind () == VR_RANGE) { - value_range initvr; + int_range<2> initvr; if (TREE_CODE (init) == SSA_NAME) - initvr = *(query->get_value_range (init, stmt)); + query->range_of_expr (initvr, init, stmt); else if (is_gimple_min_invariant (init)) initvr.set (init); else @@ -1770,16 +1791,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, else *min = init; - fix_overflow: - /* Even for valid range info, sometimes overflow flag will leak in. - As GIMPLE IL should have no constants with TREE_OVERFLOW set, we - drop them. */ - if (TREE_OVERFLOW_P (*min)) - *min = drop_tree_overflow (*min); - if (TREE_OVERFLOW_P (*max)) - *max = drop_tree_overflow (*max); - - gcc_checking_assert (compare_values (*min, *max) != 1); + fix_overflow (min, max); return true; } @@ -2446,7 +2458,9 @@ simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p) fprintf (dump_file, "\t"); print_generic_expr (dump_file, use); fprintf (dump_file, ": "); - dump_value_range (dump_file, query->get_value_range (use, stmt)); + Value_Range r (TREE_TYPE (use)); + query->range_of_expr (r, use, stmt); + r.dump (dump_file); } fprintf (dump_file, "\n"); |