diff options
Diffstat (limited to 'gcc/vr-values.c')
-rw-r--r-- | gcc/vr-values.c | 154 |
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)) |