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