aboutsummaryrefslogtreecommitdiff
path: root/gcc/vr-values.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/vr-values.cc')
-rw-r--r--gcc/vr-values.cc56
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");