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.c154
1 files changed, 83 insertions, 71 deletions
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index e95df78..d030359 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -435,10 +435,8 @@ vr_values::op_with_constant_singleton_value_range (tree op)
/* Return true if op is in a boolean [0, 1] value-range. */
bool
-vr_values::op_with_boolean_value_range_p (tree op)
+simplify_using_ranges::op_with_boolean_value_range_p (tree op)
{
- const value_range_equiv *vr;
-
if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
return true;
@@ -449,7 +447,7 @@ vr_values::op_with_boolean_value_range_p (tree op)
if (TREE_CODE (op) != SSA_NAME)
return false;
- vr = get_value_range (op);
+ const value_range *vr = get_value_range (op);
return (vr->kind () == VR_RANGE
&& integer_zerop (vr->min ())
&& integer_onep (vr->max ()));
@@ -976,10 +974,9 @@ vr_values::extract_range_from_comparison (value_range_equiv *vr,
tree type, tree op0, tree op1)
{
bool sop;
- tree val;
-
- val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop,
- NULL);
+ tree val
+ = simplifier.vrp_evaluate_conditional_warnv_with_ops (code, op0, op1,
+ false, &sop, NULL);
if (val)
{
/* Since this expression was found on the RHS of an assignment,
@@ -1002,20 +999,21 @@ vr_values::extract_range_from_comparison (value_range_equiv *vr,
always overflow. Set *OVF to true if it is known to always
overflow. */
-bool
-vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
- tree op0, tree op1, bool *ovf)
+static bool
+check_for_binary_op_overflow (vr_values *store,
+ enum tree_code subcode, tree type,
+ tree op0, tree op1, bool *ovf)
{
value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *get_value_range (op0);
+ vr0 = *store->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 = *get_value_range (op1);
+ vr1 = *store->get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST)
vr1.set (op1);
else
@@ -1395,7 +1393,7 @@ vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
if (code == IMAGPART_EXPR)
{
bool ovf = false;
- if (check_for_binary_op_overflow (subcode, type,
+ if (check_for_binary_op_overflow (this, subcode, type,
op0, op1, &ovf))
vr->set (build_int_cst (type, ovf));
else if (TYPE_PRECISION (type) == 1
@@ -1636,7 +1634,7 @@ compare_ranges (enum tree_code comp, const value_range_equiv *vr0,
assumed signed overflow is undefined. */
static tree
-compare_range_with_value (enum tree_code comp, const value_range_equiv *vr,
+compare_range_with_value (enum tree_code comp, const value_range *vr,
tree val, bool *strict_overflow_p)
{
if (vr->varying_p () || vr->undefined_p ())
@@ -1946,15 +1944,14 @@ vr_values::dump_all_value_ranges (FILE *file)
/* Initialize VRP lattice. */
-vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
+vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges"),
+ simplifier (this)
{
values_propagated = false;
num_vr_values = num_ssa_names * 2;
vr_value = XCNEWVEC (value_range_equiv *, num_vr_values);
vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
bitmap_obstack_initialize (&vrp_equiv_obstack);
- to_remove_edges = vNULL;
- to_update_switch_stmts = vNULL;
}
/* Free VRP lattice. */
@@ -1971,12 +1968,6 @@ vr_values::~vr_values ()
and not available. */
vr_value = NULL;
vr_phi_edge_counts = NULL;
-
- /* If there are entries left in TO_REMOVE_EDGES or TO_UPDATE_SWITCH_STMTS
- then an EVRP client did not clean up properly. Catch it now rather
- than seeing something more obscure later. */
- gcc_assert (to_remove_edges.is_empty ()
- && to_update_switch_stmts.is_empty ());
}
@@ -2094,7 +2085,7 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
is varying or undefined. Uses TEM as storage for the alternate range. */
const value_range_equiv *
-vr_values::get_vr_for_comparison (int i, value_range_equiv *tem)
+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));
@@ -2117,8 +2108,9 @@ vr_values::get_vr_for_comparison (int i, value_range_equiv *tem)
*STRICT_OVERFLOW_P. */
tree
-vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
- bool *strict_overflow_p, bool use_equiv_p)
+simplify_using_ranges::compare_name_with_value
+ (enum tree_code comp, tree var, tree val,
+ bool *strict_overflow_p, bool use_equiv_p)
{
/* Get the set of equivalences for VAR. */
bitmap e = get_value_range (var)->equiv ();
@@ -2196,8 +2188,8 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
tree
-vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
- bool *strict_overflow_p)
+simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2,
+ bool *strict_overflow_p)
{
/* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */
@@ -2310,7 +2302,7 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
optimizers. */
tree
-vr_values::vrp_evaluate_conditional_warnv_with_ops_using_ranges
+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;
@@ -2331,11 +2323,12 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops_using_ranges
/* Helper function for vrp_evaluate_conditional_warnv. */
tree
-vr_values::vrp_evaluate_conditional_warnv_with_ops (enum tree_code code,
- tree op0, tree op1,
- bool use_equiv_p,
- bool *strict_overflow_p,
- bool *only_ranges)
+simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
+ (enum tree_code code,
+ tree op0, tree op1,
+ bool use_equiv_p,
+ bool *strict_overflow_p,
+ bool *only_ranges)
{
tree ret;
if (only_ranges)
@@ -2438,8 +2431,8 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops (enum tree_code code,
appropriate. */
tree
-vr_values::vrp_evaluate_conditional (tree_code code, tree op0,
- tree op1, gimple *stmt)
+simplify_using_ranges::vrp_evaluate_conditional (tree_code code, tree op0,
+ tree op1, gimple *stmt)
{
bool sop;
tree ret;
@@ -2531,7 +2524,7 @@ vr_values::vrp_evaluate_conditional (tree_code code, tree op0,
*TAKEN_EDGE_P. Otherwise, set *TAKEN_EDGE_P to NULL. */
void
-vr_values::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
+simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
{
tree val;
@@ -2551,7 +2544,7 @@ vr_values::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, vr_value[SSA_NAME_VERSION (use)]);
+ dump_value_range (dump_file, get_value_range (use));
}
fprintf (dump_file, "\n");
@@ -2624,7 +2617,7 @@ vr_values::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
Returns true if the default label is not needed. */
static bool
-find_case_label_ranges (gswitch *stmt, const value_range_equiv *vr,
+find_case_label_ranges (gswitch *stmt, const value_range *vr,
size_t *min_idx1, size_t *max_idx1,
size_t *min_idx2, size_t *max_idx2)
{
@@ -2808,7 +2801,7 @@ vr_values::extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
vrp_visit_assignment_or_call (stmt, output_p, vr);
else if (gimple_code (stmt) == GIMPLE_COND)
- vrp_visit_cond_stmt (as_a <gcond *> (stmt), taken_edge_p);
+ simplifier.vrp_visit_cond_stmt (as_a <gcond *> (stmt), taken_edge_p);
else if (gimple_code (stmt) == GIMPLE_SWITCH)
vrp_visit_switch_stmt (as_a <gswitch *> (stmt), taken_edge_p);
}
@@ -3029,8 +3022,9 @@ update_range:
/* Simplify boolean operations if the source is known
to be already a boolean. */
bool
-vr_values::simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi,
- gimple *stmt)
+simplify_using_ranges::simplify_truth_ops_using_ranges
+ (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree lhs, op0, op1;
@@ -3106,8 +3100,9 @@ vr_values::simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi,
modulo. */
bool
-vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
- gimple *stmt)
+simplify_using_ranges::simplify_div_or_mod_using_ranges
+ (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree val = NULL;
@@ -3115,7 +3110,7 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
tree op1 = gimple_assign_rhs2 (stmt);
tree op0min = NULL_TREE, op0max = NULL_TREE;
tree op1min = op1;
- const value_range_equiv *vr = NULL;
+ const value_range *vr = NULL;
if (TREE_CODE (op0) == INTEGER_CST)
{
@@ -3231,8 +3226,9 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
disjoint. Return true if we do simplify. */
bool
-vr_values::simplify_min_or_max_using_ranges (gimple_stmt_iterator *gsi,
- gimple *stmt)
+simplify_using_ranges::simplify_min_or_max_using_ranges
+ (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
@@ -3279,10 +3275,11 @@ vr_values::simplify_min_or_max_using_ranges (gimple_stmt_iterator *gsi,
ABS_EXPR into a NEGATE_EXPR. */
bool
-vr_values::simplify_abs_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
+simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
tree op = gimple_assign_rhs1 (stmt);
- const value_range_equiv *vr = get_value_range (op);
+ const value_range *vr = get_value_range (op);
if (vr)
{
@@ -3359,8 +3356,9 @@ vr_set_zero_nonzero_bits (const tree expr_type,
operation is redundant. */
bool
-vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
- gimple *stmt)
+simplify_using_ranges::simplify_bit_ops_using_ranges
+ (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
@@ -3444,7 +3442,7 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
static tree
test_for_singularity (enum tree_code cond_code, tree op0,
- tree op1, const value_range_equiv *vr)
+ tree op1, const value_range *vr)
{
tree min = NULL;
tree max = NULL;
@@ -3502,7 +3500,7 @@ test_for_singularity (enum tree_code cond_code, tree op0,
by PRECISION and UNSIGNED_P. */
static bool
-range_fits_type_p (const value_range_equiv *vr,
+range_fits_type_p (const value_range *vr,
unsigned dest_precision, signop dest_sgn)
{
tree src_type;
@@ -3554,7 +3552,7 @@ range_fits_type_p (const value_range_equiv *vr,
conditional as such, and return TRUE. */
bool
-vr_values::fold_cond (gcond *cond)
+simplify_using_ranges::fold_cond (gcond *cond)
{
/* ?? vrp_folder::fold_predicate_in() is a superset of this. At
some point we should merge all variants of this code. */
@@ -3579,7 +3577,7 @@ vr_values::fold_cond (gcond *cond)
the original conditional. */
bool
-vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
+simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
{
tree op0 = gimple_cond_lhs (stmt);
tree op1 = gimple_cond_rhs (stmt);
@@ -3594,7 +3592,7 @@ vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
{
- const value_range_equiv *vr = get_value_range (op0);
+ const value_range *vr = get_value_range (op0);
/* If we have range information for OP0, then we might be
able to simplify this conditional. */
@@ -3667,7 +3665,7 @@ vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
subsequent passes. */
void
-vr_values::simplify_cond_using_ranges_2 (gcond *stmt)
+simplify_cond_using_ranges_2 (vr_values *store, gcond *stmt)
{
tree op0 = gimple_cond_lhs (stmt);
tree op1 = gimple_cond_rhs (stmt);
@@ -3697,7 +3695,7 @@ vr_values::simplify_cond_using_ranges_2 (gcond *stmt)
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
&& desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
{
- const value_range_equiv *vr = get_value_range (innerop);
+ const value_range *vr = store->get_value_range (innerop);
if (range_int_cst_p (vr)
&& range_fits_type_p (vr,
@@ -3724,10 +3722,10 @@ vr_values::simplify_cond_using_ranges_2 (gcond *stmt)
argument. */
bool
-vr_values::simplify_switch_using_ranges (gswitch *stmt)
+simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
{
tree op = gimple_switch_index (stmt);
- const value_range_equiv *vr = NULL;
+ const value_range *vr = NULL;
bool take_default;
edge e;
edge_iterator ei;
@@ -3905,7 +3903,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
}
void
-vr_values::cleanup_edges_and_switches (void)
+simplify_using_ranges::cleanup_edges_and_switches (void)
{
int i;
edge e;
@@ -4023,11 +4021,12 @@ simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
/* Simplify a conversion from integral SSA name to float in STMT. */
bool
-vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
- gimple *stmt)
+simplify_using_ranges::simplify_float_conversion_using_ranges
+ (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
tree rhs1 = gimple_assign_rhs1 (stmt);
- const value_range_equiv *vr = get_value_range (rhs1);
+ const value_range *vr = get_value_range (rhs1);
scalar_float_mode fltmode
= SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
scalar_int_mode mode;
@@ -4085,8 +4084,9 @@ vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
/* Simplify an internal fn call using ranges if possible. */
bool
-vr_values::simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi,
- gimple *stmt)
+simplify_using_ranges::simplify_internal_call_using_ranges
+ (gimple_stmt_iterator *gsi,
+ gimple *stmt)
{
enum tree_code subcode;
bool is_ubsan = false;
@@ -4131,7 +4131,7 @@ vr_values::simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi,
return false;
else
type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
- if (!check_for_binary_op_overflow (subcode, type, op0, op1, &ovf)
+ if (!check_for_binary_op_overflow (store, subcode, type, op0, op1, &ovf)
|| (is_ubsan && ovf))
return false;
@@ -4188,9 +4188,9 @@ vr_values::simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi,
two-values when it is true. Return false otherwise. */
bool
-vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
+simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b)
{
- const value_range_equiv *vr = get_value_range (var);
+ const value_range *vr = get_value_range (var);
if (vr->varying_p ()
|| vr->undefined_p ()
|| TREE_CODE (vr->min ()) != INTEGER_CST
@@ -4220,10 +4220,22 @@ vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
return false;
}
+simplify_using_ranges::simplify_using_ranges (vr_values *store)
+ : store (store)
+{
+ to_remove_edges = vNULL;
+ to_update_switch_stmts = vNULL;
+}
+
+simplify_using_ranges::~simplify_using_ranges ()
+{
+ cleanup_edges_and_switches ();
+}
+
/* Simplify STMT using ranges if possible. */
bool
-vr_values::simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
+simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
if (is_gimple_assign (stmt))