aboutsummaryrefslogtreecommitdiff
path: root/gcc/vr-values.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/vr-values.c')
-rw-r--r--gcc/vr-values.c105
1 files changed, 74 insertions, 31 deletions
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 9b21441..4d7dfd0 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -92,7 +92,7 @@ vr_values::get_lattice_entry (const_tree var)
return vr;
/* Create a default value range. */
- vr = new (vrp_value_range_pool.allocate ()) value_range_equiv;
+ vr = allocate_value_range_equiv ();
vr_value[ver] = vr;
/* After propagation finished return varying. */
@@ -173,6 +173,49 @@ vr_values::get_value_range (const_tree var,
return vr;
}
+bool
+vr_values::range_of_expr (irange &r, tree name, gimple *stmt)
+{
+ if (const value_range *vr = get_value_range (name, stmt))
+ {
+ if (vr->undefined_p () || vr->varying_p () || vr->constant_p ())
+ r = *vr;
+ else
+ {
+ value_range tmp = *vr;
+ tmp.normalize_symbolics ();
+ r = tmp;
+ }
+ return true;
+ }
+ return false;
+}
+
+tree
+vr_values::value_of_expr (tree op, gimple *)
+{
+ return op_with_constant_singleton_value_range (op);
+}
+
+tree
+vr_values::value_on_edge (edge, tree op)
+{
+ return op_with_constant_singleton_value_range (op);
+}
+
+tree
+vr_values::value_of_stmt (gimple *stmt, tree op)
+{
+ if (!op)
+ op = gimple_get_lhs (stmt);
+
+ gcc_checking_assert (!op|| op == gimple_get_lhs (stmt));
+
+ if (op)
+ return op_with_constant_singleton_value_range (op);
+ return NULL_TREE;
+}
+
/* Set the lattice entry for DEF to VARYING. */
void
@@ -451,7 +494,7 @@ simplify_using_ranges::op_with_boolean_value_range_p (tree op)
/* ?? Errr, this should probably check for [0,0] and [1,1] as well
as [0,1]. */
- const value_range *vr = get_value_range (op);
+ const value_range *vr = query->get_value_range (op);
return *vr == value_range (build_zero_cst (TREE_TYPE (op)),
build_one_cst (TREE_TYPE (op)));
}
@@ -1006,20 +1049,20 @@ vr_values::extract_range_from_comparison (value_range_equiv *vr,
overflow. */
static bool
-check_for_binary_op_overflow (range_query *store,
+check_for_binary_op_overflow (range_query *query,
enum tree_code subcode, tree type,
tree op0, tree op1, bool *ovf)
{
value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *store->get_value_range (op0);
+ vr0 = *query->get_value_range (op0);
else if (TREE_CODE (op0) == INTEGER_CST)
vr0.set (op0);
else
vr0.set_varying (TREE_TYPE (op0));
if (TREE_CODE (op1) == SSA_NAME)
- vr1 = *store->get_value_range (op1);
+ vr1 = *query->get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST)
vr1.set (op1);
else
@@ -1948,8 +1991,7 @@ vr_values::dump_all_value_ranges (FILE *file)
/* Initialize VRP lattice. */
-vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges"),
- simplifier (this)
+vr_values::vr_values () : simplifier (this)
{
values_propagated = false;
num_vr_values = num_ssa_names * 2;
@@ -1966,7 +2008,6 @@ vr_values::~vr_values ()
free (vr_value);
free (vr_phi_edge_counts);
bitmap_obstack_release (&vrp_equiv_obstack);
- vrp_value_range_pool.release ();
/* So that we can distinguish between VRP data being available
and not available. */
@@ -2092,7 +2133,7 @@ const value_range_equiv *
simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem)
{
/* Shallow-copy equiv bitmap. */
- const value_range_equiv *vr = get_value_range (ssa_name (i));
+ const value_range_equiv *vr = query->get_value_range (ssa_name (i));
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
@@ -2117,7 +2158,7 @@ simplify_using_ranges::compare_name_with_value
bool *strict_overflow_p, bool use_equiv_p)
{
/* Get the set of equivalences for VAR. */
- bitmap e = get_value_range (var)->equiv ();
+ bitmap e = query->get_value_range (var)->equiv ();
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
@@ -2197,8 +2238,8 @@ simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2,
{
/* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */
- bitmap e1 = get_value_range (n1)->equiv ();
- bitmap e2 = get_value_range (n2)->equiv ();
+ bitmap e1 = query->get_value_range (n1)->equiv ();
+ bitmap e2 = query->get_value_range (n2)->equiv ();
/* Use the fake bitmaps if e1 or e2 are not available. */
static bitmap s_e1 = NULL, s_e2 = NULL;
@@ -2310,8 +2351,8 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops_using_ranges
(enum tree_code code, tree op0, tree op1, bool * strict_overflow_p)
{
const value_range_equiv *vr0, *vr1;
- vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
- vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
+ vr0 = (TREE_CODE (op0) == SSA_NAME) ? query->get_value_range (op0) : NULL;
+ vr1 = (TREE_CODE (op1) == SSA_NAME) ? query->get_value_range (op1) : NULL;
tree res = NULL_TREE;
if (vr0 && vr1)
@@ -2390,7 +2431,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
}
else
gcc_unreachable ();
- const value_range_equiv *vr0 = get_value_range (op0, stmt);
+ const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
/* If vro, the range for OP0 to pass the overflow test, has
no intersection with *vr0, OP0's known range, then the
overflow test can't pass, so return the node for false.
@@ -2496,7 +2537,7 @@ simplify_using_ranges::vrp_evaluate_conditional (tree_code code, tree op0,
always fold regardless of the value of OP0. If -Wtype-limits
was specified, emit a warning. */
tree type = TREE_TYPE (op0);
- const value_range_equiv *vr0 = get_value_range (op0, stmt);
+ const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
if (vr0->varying_p ()
&& INTEGRAL_TYPE_P (type)
@@ -2547,7 +2588,7 @@ 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, get_value_range (use, stmt));
+ dump_value_range (dump_file, query->get_value_range (use, stmt));
}
fprintf (dump_file, "\n");
@@ -3123,7 +3164,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
}
else
{
- vr = get_value_range (op0, stmt);
+ vr = query->get_value_range (op0, stmt);
if (range_int_cst_p (vr))
{
op0min = vr->min ();
@@ -3134,7 +3175,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1) == SSA_NAME)
{
- const value_range_equiv *vr1 = get_value_range (op1, stmt);
+ const value_range_equiv *vr1 = query->get_value_range (op1, stmt);
if (range_int_cst_p (vr1))
op1min = vr1->min ();
}
@@ -3283,7 +3324,7 @@ simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi,
gimple *stmt)
{
tree op = gimple_assign_rhs1 (stmt);
- const value_range *vr = get_value_range (op, stmt);
+ const value_range *vr = query->get_value_range (op, stmt);
if (vr)
{
@@ -3373,14 +3414,14 @@ simplify_using_ranges::simplify_bit_ops_using_ranges
wide_int mask;
if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *(get_value_range (op0, stmt));
+ vr0 = *(query->get_value_range (op0, stmt));
else if (is_gimple_min_invariant (op0))
vr0.set (op0);
else
return false;
if (TREE_CODE (op1) == SSA_NAME)
- vr1 = *(get_value_range (op1, stmt));
+ vr1 = *(query->get_value_range (op1, stmt));
else if (is_gimple_min_invariant (op1))
vr1.set (op1);
else
@@ -3599,7 +3640,7 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
{
- const value_range *vr = get_value_range (op0, stmt);
+ const value_range *vr = query->get_value_range (op0, stmt);
/* If we have range information for OP0, then we might be
able to simplify this conditional. */
@@ -3672,7 +3713,7 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
subsequent passes. */
void
-simplify_cond_using_ranges_2 (vr_values *store, gcond *stmt)
+simplify_cond_using_ranges_2 (vr_values *query, gcond *stmt)
{
tree op0 = gimple_cond_lhs (stmt);
tree op1 = gimple_cond_rhs (stmt);
@@ -3702,7 +3743,7 @@ simplify_cond_using_ranges_2 (vr_values *store, gcond *stmt)
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
&& desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
{
- const value_range *vr = store->get_value_range (innerop);
+ const value_range *vr = query->get_value_range (innerop);
if (range_int_cst_p (vr)
&& range_fits_type_p (vr,
@@ -3743,7 +3784,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
if (TREE_CODE (op) == SSA_NAME)
{
- vr = get_value_range (op, stmt);
+ vr = query->get_value_range (op, stmt);
/* We can only handle integer ranges. */
if (vr->varying_p ()
@@ -4036,7 +4077,7 @@ simplify_using_ranges::simplify_float_conversion_using_ranges
gimple *stmt)
{
tree rhs1 = gimple_assign_rhs1 (stmt);
- const value_range *vr = get_value_range (rhs1, stmt);
+ const value_range *vr = query->get_value_range (rhs1, stmt);
scalar_float_mode fltmode
= SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
scalar_int_mode mode;
@@ -4141,7 +4182,7 @@ simplify_using_ranges::simplify_internal_call_using_ranges
return false;
else
type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
- if (!check_for_binary_op_overflow (store, subcode, type, op0, op1, &ovf)
+ if (!check_for_binary_op_overflow (query, subcode, type, op0, op1, &ovf)
|| (is_ubsan && ovf))
return false;
@@ -4200,7 +4241,7 @@ simplify_using_ranges::simplify_internal_call_using_ranges
bool
simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b)
{
- value_range vr = *get_value_range (var);
+ value_range vr = *query->get_value_range (var);
vr.normalize_symbolics ();
if (vr.varying_p () || vr.undefined_p ())
return false;
@@ -4217,8 +4258,8 @@ simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b)
return false;
}
-simplify_using_ranges::simplify_using_ranges (range_query *store)
- : store (store)
+simplify_using_ranges::simplify_using_ranges (range_query *query)
+ : query (query)
{
to_remove_edges = vNULL;
to_update_switch_stmts = vNULL;
@@ -4234,6 +4275,8 @@ simplify_using_ranges::~simplify_using_ranges ()
bool
simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
{
+ gcc_checking_assert (query);
+
gimple *stmt = gsi_stmt (*gsi);
if (is_gimple_assign (stmt))
{