From 27922d518d3c81c85df4b2d391bc54e85dab01f5 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 12 Nov 2018 14:53:36 +0000 Subject: [PATCH] 2018-11=12 Richard Biener * tree-vrp.h (value_range[_base]::set): Make public. Provide overload for single value. (value_range[_base]::set_nonnull): New. (value_range[_base]::set_null): Likewise. (value_range): Document bitmap copying behavior, mark copy constructor and assignment operator deleted. (value_range::move): New. (value_range::set_and_canonicalize): Default bitmap to zero. (set_value_range_to_nonnull): Remove. (set_value_range_to_null): Likewise. (set_value_range): Likewise. (set_value_range_to_value): Likewise. (extract_range_from_unary_expr): Work on value_range_base. (extract_range_from_binary_expr_1): Likewise. Rename to... (extract_range_from_binary_expr): ... this. * tree-vrp.c (value_range::update): Clear equiv bitmap if required. (value_range::move): New, move equiv bitmap. (value_range_base::set_undefined): Avoid assignment. (value_range::set_undefined): Likewise. (value_range_base::set_varying): Likewise. (value_range::set_varying): Likewise. (set_value_range): Remove. (value_range_base::set): New overload for value. (value_range::set): Likewise. (set_value_range_to_nonnull): Remove. (value_range_base::set_nonnull): New. (value_range::set_nonnull): Likewise. (set_value_range_to_null): Remove. (value_range_base::set_null): New. (value_range::set_null): Likewise. (range_is_null): Work on value_range_base. (range_is_nonnull): Likewise. (ranges_from_anti_range): Likewise. (extract_range_into_wide_ints): Likewise. (extract_range_from_multiplicative_op): Likewise. (extract_range_from_binary_expr): Likewise. Update for API changes. (extract_range_from_unary_expr): Likewise. Remove OBJ_TYPE_REF handling. (value_range::intersect_helper): Avoid copy and assignment. (value_range::union_helper): Likewise. (determine_value_range_1): Adjust. * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::try_find_new_range): Avoid assignment by using move. (evrp_range_analyzer::record_ranges_from_stmt): Avoid assignment. * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis): Likewise. * tree-ssanames.c (get_range_info): Likewise. * vr-values.h (vr_values::get_vr_for_comparison): Adjust API. * vr-values.c (vr_values::get_value_range): Adjust. (vr_values::update_value_range): Likewise. (symbolic_range_based_on_p): Work on value_range_base. (vr_values::extract_range_from_binary_expr): Use value_range_base. (vr_values::extract_range_from_unary_expr): Likewise. (vr_values::extract_range_from_cond_expr): Avoid assignment. (vr_values::extract_range_from_comparison): Adjust. (vr_values::check_for_binary_op_overflow): Use value_range_base. (vr_values::extract_range_basic): Adjust. (vr_values::adjust_range_with_scev): Likewise. (vr_values::vrp_visit_assignment_or_call): Likewise. (vr_values::get_vr_for_comparison): Change API to avoid assignment and copy construction. (vr_values::compare_name_with_value): Adjust accordingly. (vr_values::compare_names): Likewise. (vr_values::extract_range_from_phi_node): Avoid assignment and bogus in-place modify of equiv bitmap. (vr_values::simplify_bit_ops_using_ranges): Use value_range_base. * ipa-prop.c (ipa_compute_jump_functions_for_edge): Adjust for extract_range_from_unary_expr API change. * ipa-cp.c (ipa_vr_operation_and_type_effects): Likewise. From-SVN: r266030 --- gcc/ChangeLog | 73 ++++++++++ gcc/gimple-ssa-evrp-analyze.c | 6 +- gcc/ipa-cp.c | 8 +- gcc/ipa-prop.c | 10 +- gcc/tree-ssa-threadedge.c | 4 +- gcc/tree-ssanames.c | 2 +- gcc/tree-vrp.c | 259 +++++++++++++++++----------------- gcc/tree-vrp.h | 44 ++++-- gcc/vr-values.c | 188 ++++++++++++------------ gcc/vr-values.h | 2 +- 10 files changed, 343 insertions(+), 253 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b65a1f2eb71..f458802acec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,76 @@ +2018-11-12 Richard Biener + + * tree-vrp.h (value_range[_base]::set): Make public. Provide + overload for single value. + (value_range[_base]::set_nonnull): New. + (value_range[_base]::set_null): Likewise. + (value_range): Document bitmap copying behavior, mark + copy constructor and assignment operator deleted. + (value_range::move): New. + (value_range::set_and_canonicalize): Default bitmap to zero. + (set_value_range_to_nonnull): Remove. + (set_value_range_to_null): Likewise. + (set_value_range): Likewise. + (set_value_range_to_value): Likewise. + (extract_range_from_unary_expr): Work on value_range_base. + (extract_range_from_binary_expr_1): Likewise. Rename to... + (extract_range_from_binary_expr): ... this. + * tree-vrp.c (value_range::update): Clear equiv bitmap + if required. + (value_range::move): New, move equiv bitmap. + (value_range_base::set_undefined): Avoid assignment. + (value_range::set_undefined): Likewise. + (value_range_base::set_varying): Likewise. + (value_range::set_varying): Likewise. + (set_value_range): Remove. + (value_range_base::set): New overload for value. + (value_range::set): Likewise. + (set_value_range_to_nonnull): Remove. + (value_range_base::set_nonnull): New. + (value_range::set_nonnull): Likewise. + (set_value_range_to_null): Remove. + (value_range_base::set_null): New. + (value_range::set_null): Likewise. + (range_is_null): Work on value_range_base. + (range_is_nonnull): Likewise. + (ranges_from_anti_range): Likewise. + (extract_range_into_wide_ints): Likewise. + (extract_range_from_multiplicative_op): Likewise. + (extract_range_from_binary_expr): Likewise. Update for API changes. + (extract_range_from_unary_expr): Likewise. Remove OBJ_TYPE_REF + handling. + (value_range::intersect_helper): Avoid copy and assignment. + (value_range::union_helper): Likewise. + (determine_value_range_1): Adjust. + * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::try_find_new_range): + Avoid assignment by using move. + (evrp_range_analyzer::record_ranges_from_stmt): Avoid assignment. + * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis): + Likewise. + * tree-ssanames.c (get_range_info): Likewise. + * vr-values.h (vr_values::get_vr_for_comparison): Adjust API. + * vr-values.c (vr_values::get_value_range): Adjust. + (vr_values::update_value_range): Likewise. + (symbolic_range_based_on_p): Work on value_range_base. + (vr_values::extract_range_from_binary_expr): Use value_range_base. + (vr_values::extract_range_from_unary_expr): Likewise. + (vr_values::extract_range_from_cond_expr): Avoid assignment. + (vr_values::extract_range_from_comparison): Adjust. + (vr_values::check_for_binary_op_overflow): Use value_range_base. + (vr_values::extract_range_basic): Adjust. + (vr_values::adjust_range_with_scev): Likewise. + (vr_values::vrp_visit_assignment_or_call): Likewise. + (vr_values::get_vr_for_comparison): Change API to avoid + assignment and copy construction. + (vr_values::compare_name_with_value): Adjust accordingly. + (vr_values::compare_names): Likewise. + (vr_values::extract_range_from_phi_node): Avoid assignment and + bogus in-place modify of equiv bitmap. + (vr_values::simplify_bit_ops_using_ranges): Use value_range_base. + * ipa-prop.c (ipa_compute_jump_functions_for_edge): Adjust + for extract_range_from_unary_expr API change. + * ipa-cp.c (ipa_vr_operation_and_type_effects): Likewise. + 2018-11-12 Eric Botcazou * config/mcore/mcore.h (WORD_REGISTER_OPERATIONS): Remove duplicate. diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index 1cd13dda7b6..bd11eea12b4 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -97,7 +97,7 @@ evrp_range_analyzer::try_find_new_range (tree name, && vrp_operand_equal_p (old_vr->max (), vr.max ())) return NULL; value_range *new_vr = vr_values->allocate_value_range (); - *new_vr = vr; + new_vr->move (&vr); return new_vr; } return NULL; @@ -319,8 +319,8 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) also have to be very careful about sharing the underlying bitmaps. Ugh. */ value_range *new_vr = vr_values->allocate_value_range (); - *new_vr = vr; - new_vr->equiv_clear (); + new_vr->set (vr.kind (), vr.min (), vr.max ()); + vr.equiv_clear (); push_value_range (output, new_vr); } } diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 882c8975ff4..81da108fb62 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1876,12 +1876,8 @@ ipa_vr_operation_and_type_effects (value_range_base *dst_vr, enum tree_code operation, tree dst_type, tree src_type) { - /* ??? We'd want to use value_range_base on the VRP workers. */ - value_range dst_tem; - value_range src_tem (*src_vr); - extract_range_from_unary_expr (&dst_tem, operation, dst_type, - &src_tem, src_type); - *dst_vr = value_range_base (dst_tem.kind (), dst_tem.min (), dst_tem.max ()); + extract_range_from_unary_expr (dst_vr, operation, dst_type, + src_vr, src_type); if (dst_vr->varying_p () || dst_vr->undefined_p ()) return false; return true; diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 5d9d8cff52e..c779d865315 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1885,12 +1885,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, && (type = get_range_info (arg, &min, &max)) && (type == VR_RANGE || type == VR_ANTI_RANGE)) { - /* ??? We'd want to use value_range_base here but the - VRP workers need to be adjusted first. */ - value_range resvr; - value_range tmpvr (type, - wide_int_to_tree (TREE_TYPE (arg), min), - wide_int_to_tree (TREE_TYPE (arg), max)); + value_range_base resvr; + value_range_base tmpvr (type, + wide_int_to_tree (TREE_TYPE (arg), min), + wide_int_to_tree (TREE_TYPE (arg), max)); extract_range_from_unary_expr (&resvr, NOP_EXPR, param_type, &tmpvr, TREE_TYPE (arg)); if (!resvr.undefined_p () && !resvr.varying_p ()) diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 3494ee90b58..8be8d79acab 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -166,7 +166,7 @@ record_temporary_equivalences_from_phis (edge e, away in the VR stack. */ vr_values *vr_values = evrp_range_analyzer->get_vr_values (); value_range *new_vr = vr_values->allocate_value_range (); - *new_vr = value_range (); + new (new_vr) value_range (); /* There are three cases to consider: @@ -181,7 +181,7 @@ record_temporary_equivalences_from_phis (edge e, if (TREE_CODE (src) == SSA_NAME) new_vr->deep_copy (vr_values->get_value_range (src)); else if (TREE_CODE (src) == INTEGER_CST) - set_value_range_to_value (new_vr, src, NULL); + new_vr->set (src); else new_vr->set_varying (); diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index a2c2efb634a..b53c4be3074 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -447,7 +447,7 @@ get_range_info (const_tree name, value_range &vr) min = wide_int_to_tree (TREE_TYPE (name), wmin); max = wide_int_to_tree (TREE_TYPE (name), wmax); } - vr = value_range (kind, min, max); + vr.set (kind, min, max); return kind; } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f5e0d03099e..a182e643ad7 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -134,12 +134,13 @@ value_range::value_range (const value_range_base &other) set (other.kind (), other.min(), other.max (), NULL); } -/* Like above, but keep the equivalences intact. */ +/* Like set, but keep the equivalences in place. */ void value_range::update (value_range_kind kind, tree min, tree max) { - set (kind, min, max, m_equiv); + set (kind, min, max, + (kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL); } /* Copy value_range in FROM into THIS while avoiding bitmap sharing. @@ -154,6 +155,14 @@ value_range::deep_copy (const value_range *from) set (from->m_kind, from->min (), from->max (), from->m_equiv); } +void +value_range::move (value_range *from) +{ + set (from->m_kind, from->min (), from->max ()); + m_equiv = from->m_equiv; + from->m_equiv = NULL; +} + /* Check the validity of the range. */ void @@ -262,27 +271,25 @@ value_range_base::constant_p () const void value_range_base::set_undefined () { - *this = value_range_base (VR_UNDEFINED, NULL, NULL); + set (VR_UNDEFINED, NULL, NULL); } void value_range::set_undefined () { - equiv_clear (); - *this = value_range (VR_UNDEFINED, NULL, NULL, NULL); + set (VR_UNDEFINED, NULL, NULL, NULL); } void value_range_base::set_varying () { - *this = value_range_base (VR_VARYING, NULL, NULL); + set (VR_VARYING, NULL, NULL); } void value_range::set_varying () { - equiv_clear (); - *this = value_range (VR_VARYING, NULL, NULL, NULL); + set (VR_VARYING, NULL, NULL, NULL); } /* Return TRUE if it is possible that range contains VAL. */ @@ -598,15 +605,6 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type, return vr_type; } -/* Set value range VR to {T, MIN, MAX, EQUIV}. */ - -void -set_value_range (value_range *vr, enum value_range_kind kind, - tree min, tree max, bitmap equiv) -{ - *vr = value_range (kind, min, max, equiv); -} - /* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}. This means adjusting VRTYPE, MIN and MAX representing the case of a @@ -739,35 +737,52 @@ value_range::set_and_canonicalize (enum value_range_kind kind, equiv_clear (); } -/* Set value range VR to a single value. This function is only called - with values we get from statements, and exists to clear the - TREE_OVERFLOW flag. */ +void +value_range_base::set (tree val) +{ + gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val)); + if (TREE_OVERFLOW_P (val)) + val = drop_tree_overflow (val); + set (VR_RANGE, val, val); +} void -set_value_range_to_value (value_range *vr, tree val, bitmap equiv) +value_range::set (tree val) { - gcc_assert (is_gimple_min_invariant (val)); + gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val)); if (TREE_OVERFLOW_P (val)) val = drop_tree_overflow (val); - set_value_range (vr, VR_RANGE, val, val, equiv); + set (VR_RANGE, val, val, NULL); } /* Set value range VR to a non-NULL range of type TYPE. */ void -set_value_range_to_nonnull (value_range *vr, tree type) +value_range_base::set_nonnull (tree type) { tree zero = build_int_cst (type, 0); - set_value_range (vr, VR_ANTI_RANGE, zero, zero, NULL); + set (VR_ANTI_RANGE, zero, zero); } +void +value_range::set_nonnull (tree type) +{ + tree zero = build_int_cst (type, 0); + set (VR_ANTI_RANGE, zero, zero, NULL); +} /* Set value range VR to a NULL range of type TYPE. */ void -set_value_range_to_null (value_range *vr, tree type) +value_range_base::set_null (tree type) +{ + set (build_int_cst (type, 0)); +} + +void +value_range::set_null (tree type) { - set_value_range_to_value (vr, build_int_cst (type, 0), NULL); + set (build_int_cst (type, 0)); } /* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */ @@ -797,13 +812,13 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2) /* Return true if VR is [0, 0]. */ static inline bool -range_is_null (const value_range *vr) +range_is_null (const value_range_base *vr) { return vr->zero_p (); } static inline bool -range_is_nonnull (const value_range *vr) +range_is_nonnull (const value_range_base *vr) { return (vr->kind () == VR_ANTI_RANGE && vr->min () == vr->max () @@ -1195,8 +1210,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type, *VR1 will be VR_UNDEFINED. */ static bool -ranges_from_anti_range (const value_range *ar, - value_range *vr0, value_range *vr1) +ranges_from_anti_range (const value_range_base *ar, + value_range_base *vr0, value_range_base *vr1) { tree type = ar->type (); @@ -1237,7 +1252,7 @@ ranges_from_anti_range (const value_range *ar, resulting wide ints are set to [-MIN, +MAX] for the type. */ static void inline -extract_range_into_wide_ints (const value_range *vr, +extract_range_into_wide_ints (const value_range_base *vr, signop sign, unsigned prec, wide_int &wmin, wide_int &wmax) { @@ -1259,10 +1274,10 @@ extract_range_into_wide_ints (const value_range *vr, *VR = *VR0 .CODE. *VR1. */ static void -extract_range_from_multiplicative_op (value_range *vr, +extract_range_from_multiplicative_op (value_range_base *vr, enum tree_code code, - const value_range *vr0, - const value_range *vr1) + const value_range_base *vr0, + const value_range_base *vr1) { gcc_assert (code == MULT_EXPR || code == TRUNC_DIV_EXPR @@ -1290,7 +1305,7 @@ extract_range_from_multiplicative_op (value_range *vr, overflow_undefined)) vr->set_and_canonicalize (VR_RANGE, wide_int_to_tree (type, res_lb), - wide_int_to_tree (type, res_ub), NULL); + wide_int_to_tree (type, res_ub)); else vr->set_varying (); } @@ -1411,7 +1426,7 @@ set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max, { /* If the limits are swapped, we wrapped around and cover the entire range. We have a similar check at the end of - extract_range_from_binary_expr_1. */ + extract_range_from_binary_expr. */ if (wi::gt_p (tmin, tmax, sgn)) kind = VR_VARYING; else @@ -1485,15 +1500,15 @@ set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max, type EXPR_TYPE. The resulting range is stored in *VR. */ void -extract_range_from_binary_expr_1 (value_range *vr, - enum tree_code code, tree expr_type, - const value_range *vr0_, - const value_range *vr1_) +extract_range_from_binary_expr (value_range_base *vr, + enum tree_code code, tree expr_type, + const value_range_base *vr0_, + const value_range_base *vr1_) { signop sign = TYPE_SIGN (expr_type); unsigned int prec = TYPE_PRECISION (expr_type); - value_range vr0 = *vr0_, vr1 = *vr1_; - value_range vrtem0, vrtem1; + value_range_base vr0 = *vr0_, vr1 = *vr1_; + value_range_base vrtem0, vrtem1; enum value_range_kind type; tree min = NULL_TREE, max = NULL_TREE; int cmp; @@ -1550,7 +1565,7 @@ extract_range_from_binary_expr_1 (value_range *vr, easier to special case when vr0 is ~[0,0] for EXACT_DIV_EXPR. */ if (code == EXACT_DIV_EXPR && range_is_nonnull (&vr0)) { - set_value_range_to_nonnull (vr, expr_type); + vr->set_nonnull (expr_type); return; } @@ -1559,11 +1574,12 @@ extract_range_from_binary_expr_1 (value_range *vr, if (vr0.kind () == VR_ANTI_RANGE && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1)) { - extract_range_from_binary_expr_1 (vr, code, expr_type, &vrtem0, vr1_); + extract_range_from_binary_expr (vr, code, expr_type, &vrtem0, vr1_); if (!vrtem1.undefined_p ()) { - value_range vrres; - extract_range_from_binary_expr_1 (&vrres, code, expr_type, &vrtem1, vr1_); + value_range_base vrres; + extract_range_from_binary_expr (&vrres, code, expr_type, + &vrtem1, vr1_); vr->union_ (&vrres); } return; @@ -1572,12 +1588,12 @@ extract_range_from_binary_expr_1 (value_range *vr, if (vr1.kind () == VR_ANTI_RANGE && ranges_from_anti_range (&vr1, &vrtem0, &vrtem1)) { - extract_range_from_binary_expr_1 (vr, code, expr_type, vr0_, &vrtem0); + extract_range_from_binary_expr (vr, code, expr_type, vr0_, &vrtem0); if (!vrtem1.undefined_p ()) { - value_range vrres; - extract_range_from_binary_expr_1 (&vrres, code, expr_type, - vr0_, &vrtem1); + value_range_base vrres; + extract_range_from_binary_expr (&vrres, code, expr_type, + vr0_, &vrtem1); vr->union_ (&vrres); } return; @@ -1627,9 +1643,9 @@ extract_range_from_binary_expr_1 (value_range *vr, If both are null, then the result is null. Otherwise they are varying. */ if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1)) - set_value_range_to_nonnull (vr, expr_type); + vr->set_nonnull (expr_type); else if (range_is_null (&vr0) && range_is_null (&vr1)) - set_value_range_to_null (vr, expr_type); + vr->set_null (expr_type); else vr->set_varying (); } @@ -1639,9 +1655,9 @@ extract_range_from_binary_expr_1 (value_range *vr, whether the expression evaluates to non-NULL. */ if (!range_includes_zero_p (&vr0) || !range_includes_zero_p (&vr1)) - set_value_range_to_nonnull (vr, expr_type); + vr->set_nonnull (expr_type); else if (range_is_null (&vr0) && range_is_null (&vr1)) - set_value_range_to_null (vr, expr_type); + vr->set_null (expr_type); else vr->set_varying (); } @@ -1650,9 +1666,9 @@ extract_range_from_binary_expr_1 (value_range *vr, /* For pointer types, we are really only interested in asserting whether the expression evaluates to non-NULL. */ if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1)) - set_value_range_to_nonnull (vr, expr_type); + vr->set_nonnull (expr_type); else if (range_is_null (&vr0) || range_is_null (&vr1)) - set_value_range_to_null (vr, expr_type); + vr->set_null (expr_type); else vr->set_varying (); } @@ -1670,13 +1686,9 @@ extract_range_from_binary_expr_1 (value_range *vr, [0,0] - VR_VARYING is not dropped to varying, but is calculated as [MIN+1, MAX]. */ if (vr0.varying_p ()) - vr0.update (VR_RANGE, - vrp_val_min (expr_type), - vrp_val_max (expr_type)); + vr0.set (VR_RANGE, vrp_val_min (expr_type), vrp_val_max (expr_type)); if (vr1.varying_p ()) - vr1.update (VR_RANGE, - vrp_val_min (expr_type), - vrp_val_max (expr_type)); + vr1.set (VR_RANGE, vrp_val_min (expr_type), vrp_val_max (expr_type)); const bool minus_p = (code == MINUS_EXPR); tree min_op0 = vr0.min (); @@ -1779,8 +1791,8 @@ extract_range_from_binary_expr_1 (value_range *vr, extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max); if (wide_int_range_min_max (wmin, wmax, code, sign, prec, vr0_min, vr0_max, vr1_min, vr1_max)) - vr->update (VR_RANGE, wide_int_to_tree (expr_type, wmin), - wide_int_to_tree (expr_type, wmax)); + vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin), + wide_int_to_tree (expr_type, wmax)); else vr->set_varying (); return; @@ -1812,9 +1824,8 @@ extract_range_from_binary_expr_1 (value_range *vr, useful ranges just from the shift count. E.g. x >> 63 for signed 64-bit x is always [-1, 0]. */ if (vr0.kind () != VR_RANGE || vr0.symbolic_p ()) - vr0.update (VR_RANGE, - vrp_val_min (expr_type), - vrp_val_max (expr_type)); + vr0.set (VR_RANGE, vrp_val_min (expr_type), + vrp_val_max (expr_type)); extract_range_from_multiplicative_op (vr, code, &vr0, &vr1); return; } @@ -1831,7 +1842,7 @@ extract_range_from_binary_expr_1 (value_range *vr, { min = wide_int_to_tree (expr_type, res_lb); max = wide_int_to_tree (expr_type, res_ub); - vr->set_and_canonicalize (VR_RANGE, min, max, NULL); + vr->set_and_canonicalize (VR_RANGE, min, max); return; } } @@ -1876,15 +1887,13 @@ extract_range_from_binary_expr_1 (value_range *vr, vr->set_undefined (); return; } - set_value_range (vr, VR_RANGE, - wide_int_to_tree (expr_type, wmin), - wide_int_to_tree (expr_type, wmax), NULL); + vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin), + wide_int_to_tree (expr_type, wmax)); if (extra_range_p) { - value_range extra_range; - set_value_range (&extra_range, VR_RANGE, - wide_int_to_tree (expr_type, extra_min), - wide_int_to_tree (expr_type, extra_max), NULL); + value_range_base + extra_range (VR_RANGE, wide_int_to_tree (expr_type, extra_min), + wide_int_to_tree (expr_type, extra_max)); vr->union_ (&extra_range); } return; @@ -1904,7 +1913,7 @@ extract_range_from_binary_expr_1 (value_range *vr, vr0_min, vr0_max, vr1_min, vr1_max); min = wide_int_to_tree (expr_type, wmin); max = wide_int_to_tree (expr_type, wmax); - set_value_range (vr, VR_RANGE, min, max, NULL); + vr->set (VR_RANGE, min, max); return; } else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR) @@ -1931,7 +1940,7 @@ extract_range_from_binary_expr_1 (value_range *vr, { min = wide_int_to_tree (expr_type, wmin); max = wide_int_to_tree (expr_type, wmax); - set_value_range (vr, VR_RANGE, min, max, NULL); + vr->set (VR_RANGE, min, max); } else vr->set_varying (); @@ -1949,7 +1958,7 @@ extract_range_from_binary_expr_1 (value_range *vr, { min = wide_int_to_tree (expr_type, wmin); max = wide_int_to_tree (expr_type, wmax); - set_value_range (vr, VR_RANGE, min, max, NULL); + vr->set (VR_RANGE, min, max); } else vr->set_varying (); @@ -1965,7 +1974,7 @@ extract_range_from_binary_expr_1 (value_range *vr, { min = wide_int_to_tree (expr_type, wmin); max = wide_int_to_tree (expr_type, wmax); - set_value_range (vr, VR_RANGE, min, max, NULL); + vr->set (VR_RANGE, min, max); } else vr->set_varying (); @@ -2004,7 +2013,7 @@ extract_range_from_binary_expr_1 (value_range *vr, vr->set_varying (); } else - set_value_range (vr, type, min, max, NULL); + vr->set (type, min, max); } /* Extract range information from a unary operation CODE based on @@ -2012,14 +2021,14 @@ extract_range_from_binary_expr_1 (value_range *vr, The resulting range is stored in *VR. */ void -extract_range_from_unary_expr (value_range *vr, +extract_range_from_unary_expr (value_range_base *vr, enum tree_code code, tree type, - const value_range *vr0_, tree op0_type) + const value_range_base *vr0_, tree op0_type) { signop sign = TYPE_SIGN (type); unsigned int prec = TYPE_PRECISION (type); - value_range vr0 = *vr0_; - value_range vrtem0, vrtem1; + value_range_base vr0 = *vr0_; + value_range_base vrtem0, vrtem1; /* VRP only operates on integral and pointer types. */ if (!(INTEGRAL_TYPE_P (op0_type) @@ -2039,29 +2048,28 @@ extract_range_from_unary_expr (value_range *vr, } /* Handle operations that we express in terms of others. */ - if (code == PAREN_EXPR || code == OBJ_TYPE_REF) + if (code == PAREN_EXPR) { /* PAREN_EXPR and OBJ_TYPE_REF are simple copies. */ - vr->deep_copy (&vr0); + *vr = vr0; return; } else if (code == NEGATE_EXPR) { /* -X is simply 0 - X, so re-use existing code that also handles anti-ranges fine. */ - value_range zero; - set_value_range_to_value (&zero, build_int_cst (type, 0), NULL); - extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0); + value_range_base zero; + zero.set (build_int_cst (type, 0)); + extract_range_from_binary_expr (vr, MINUS_EXPR, type, &zero, &vr0); return; } else if (code == BIT_NOT_EXPR) { /* ~X is simply -1 - X, so re-use existing code that also handles anti-ranges fine. */ - value_range minusone; - set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL); - extract_range_from_binary_expr_1 (vr, MINUS_EXPR, - type, &minusone, &vr0); + value_range_base minusone; + minusone.set (build_int_cst (type, -1)); + extract_range_from_binary_expr (vr, MINUS_EXPR, type, &minusone, &vr0); return; } @@ -2073,7 +2081,7 @@ extract_range_from_unary_expr (value_range *vr, extract_range_from_unary_expr (vr, code, type, &vrtem0, op0_type); if (!vrtem1.undefined_p ()) { - value_range vrres; + value_range_base vrres; extract_range_from_unary_expr (&vrres, code, type, &vrtem1, op0_type); vr->union_ (&vrres); @@ -2096,9 +2104,9 @@ extract_range_from_unary_expr (value_range *vr, if (POINTER_TYPE_P (type) || POINTER_TYPE_P (op0_type)) { if (!range_includes_zero_p (&vr0)) - set_value_range_to_nonnull (vr, type); + vr->set_nonnull (type); else if (range_is_null (&vr0)) - set_value_range_to_null (vr, type); + vr->set_null (type); else vr->set_varying (); return; @@ -2132,7 +2140,7 @@ extract_range_from_unary_expr (value_range *vr, { tree min = wide_int_to_tree (outer_type, wmin); tree max = wide_int_to_tree (outer_type, wmax); - vr->set_and_canonicalize (VR_RANGE, min, max, NULL); + vr->set_and_canonicalize (VR_RANGE, min, max); } else vr->set_varying (); @@ -2145,9 +2153,8 @@ extract_range_from_unary_expr (value_range *vr, extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max); if (wide_int_range_abs (wmin, wmax, sign, prec, vr0_min, vr0_max, TYPE_OVERFLOW_UNDEFINED (type))) - set_value_range (vr, VR_RANGE, - wide_int_to_tree (type, wmin), - wide_int_to_tree (type, wmax), NULL); + vr->set (VR_RANGE, wide_int_to_tree (type, wmin), + wide_int_to_tree (type, wmax)); else vr->set_varying (); return; @@ -6024,24 +6031,21 @@ value_range::intersect_helper (value_range *vr0, const value_range *vr1) return; } - /* Save the original vr0 so we can return it as conservative intersection - result when our worker turns things to varying. */ - value_range saved (*vr0); - value_range_kind vr0type = vr0->kind (); tree vr0min = vr0->min (); tree vr0max = vr0->max (); intersect_ranges (&vr0type, &vr0min, &vr0max, vr1->kind (), vr1->min (), vr1->max ()); /* Make sure to canonicalize the result though as the inversion of a - VR_RANGE can still be a VR_RANGE. */ - vr0->set_and_canonicalize (vr0type, vr0min, vr0max, vr0->m_equiv); + VR_RANGE can still be a VR_RANGE. Work on a temporary so we can + fall back to vr0 when this turns things to varying. */ + value_range tem; + tem.set_and_canonicalize (vr0type, vr0min, vr0max); /* If that failed, use the saved original VR0. */ - if (vr0->varying_p ()) - { - *vr0 = saved; - return; - } + if (tem.varying_p ()) + return; + vr0->update (tem.kind (), tem.min (), tem.max ()); + /* If the result is VR_UNDEFINED there is no need to mess with the equivalencies. */ if (vr0->undefined_p ()) @@ -6168,37 +6172,30 @@ value_range::union_helper (value_range *vr0, const value_range *vr1) return; } - value_range saved (*vr0); value_range_kind vr0type = vr0->kind (); tree vr0min = vr0->min (); tree vr0max = vr0->max (); union_ranges (&vr0type, &vr0min, &vr0max, vr1->kind (), vr1->min (), vr1->max ()); - *vr0 = value_range (vr0type, vr0min, vr0max); - if (vr0->varying_p ()) + /* Work on a temporary so we can still use vr0 when union returns varying. */ + value_range tem; + tem.set_and_canonicalize (vr0type, vr0min, vr0max); + if (tem.varying_p ()) { /* Failed to find an efficient meet. Before giving up and setting the result to VARYING, see if we can at least derive a useful anti-range. */ - if (range_includes_zero_p (&saved) == 0 + if (range_includes_zero_p (vr0) == 0 && range_includes_zero_p (vr1) == 0) { - set_value_range_to_nonnull (vr0, saved.type ()); - - /* Since this meet operation did not result from the meeting of - two equivalent names, VR0 cannot have any equivalences. */ - if (vr0->m_equiv) - bitmap_clear (vr0->m_equiv); + vr0->set_nonnull (vr0->type ()); return; } vr0->set_varying (); return; } - vr0->set_and_canonicalize (vr0->kind (), vr0->min (), vr0->max (), - vr0->equiv ()); - if (vr0->varying_p ()) - return; + vr0->update (tem.kind (), tem.min (), tem.max ()); /* The resulting set of equivalences is always the intersection of the two sets. */ @@ -6877,8 +6874,8 @@ determine_value_range_1 (value_range *vr, tree expr) value_range vr0, vr1; determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1)); - extract_range_from_binary_expr_1 (vr, TREE_CODE (expr), TREE_TYPE (expr), - &vr0, &vr1); + extract_range_from_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr), + &vr0, &vr1); } else if (UNARY_CLASS_P (expr)) { @@ -6888,7 +6885,7 @@ determine_value_range_1 (value_range *vr, tree expr) &vr0, TREE_TYPE (TREE_OPERAND (expr, 0))); } else if (TREE_CODE (expr) == INTEGER_CST) - set_value_range_to_value (vr, expr, NULL); + vr->set (expr); else { value_range_kind kind; @@ -6898,8 +6895,8 @@ determine_value_range_1 (value_range *vr, tree expr) if (TREE_CODE (expr) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (expr)) && (kind = get_range_info (expr, &min, &max)) != VR_VARYING) - set_value_range (vr, kind, wide_int_to_tree (TREE_TYPE (expr), min), - wide_int_to_tree (TREE_TYPE (expr), max), NULL); + vr->set (kind, wide_int_to_tree (TREE_TYPE (expr), min), + wide_int_to_tree (TREE_TYPE (expr), max)); else vr->set_varying (); } diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h index 8130cb85f27..ae7dcc7b58e 100644 --- a/gcc/tree-vrp.h +++ b/gcc/tree-vrp.h @@ -44,6 +44,11 @@ public: value_range_base (); value_range_base (value_range_kind, tree, tree); + void set (value_range_kind, tree, tree); + void set (tree); + void set_nonnull (tree); + void set_null (tree); + enum value_range_kind kind () const; tree min () const; tree max () const; @@ -71,7 +76,6 @@ public: void dump () const; protected: - void set (value_range_kind, tree, tree); void check (); enum value_range_kind m_kind; @@ -96,8 +100,25 @@ class GTY((user)) value_range : public value_range_base public: value_range (); value_range (const value_range_base &); + /* Deep-copies equiv bitmap argument. */ value_range (value_range_kind, tree, tree, bitmap = NULL); + + /* Shallow-copies equiv bitmap. */ + value_range (const value_range &) /* = delete */; + /* Shallow-copies equiv bitmap. */ + value_range& operator=(const value_range&) /* = delete */; + + /* Move equiv bitmap from source range. */ + void move (value_range *); + + /* Leaves equiv bitmap alone. */ void update (value_range_kind, tree, tree); + /* Deep-copies equiv bitmap argument. */ + void set (value_range_kind, tree, tree, bitmap = NULL); + void set (tree); + void set_nonnull (tree); + void set_null (tree); + bool operator== (const value_range &) const; bool operator!= (const value_range &) const; void intersect (const value_range *); @@ -114,12 +135,12 @@ class GTY((user)) value_range : public value_range_base /* Misc methods. */ void deep_copy (const value_range *); - void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap); + void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap = NULL); void dump (FILE *) const; void dump () const; private: - void set (value_range_kind, tree, tree, bitmap); + /* Deep-copies bitmap argument. */ void set_equiv (bitmap); void check (); bool equal_p (const value_range &, bool ignore_equivs) const; @@ -225,12 +246,6 @@ extern bool stmt_interesting_for_vrp (gimple *); extern bool range_includes_zero_p (const value_range_base *); extern bool infer_value_range (gimple *, tree, tree_code *, tree *); -extern void set_value_range_to_nonnull (value_range *, tree); -extern void set_value_range_to_null (value_range *, tree); -extern void set_value_range (value_range *, enum value_range_kind, tree, - tree, bitmap); -extern void set_value_range_to_value (value_range *, tree, bitmap); - extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap); extern tree value_range_constant_singleton (const value_range_base *); @@ -247,14 +262,15 @@ extern int value_inside_range (tree, tree, tree); extern tree vrp_val_min (const_tree); extern tree vrp_val_max (const_tree); -extern void extract_range_from_unary_expr (value_range *vr, +extern void extract_range_from_unary_expr (value_range_base *vr, enum tree_code code, tree type, - const value_range *vr0_, + const value_range_base *vr0_, tree op0_type); -extern void extract_range_from_binary_expr_1 (value_range *, enum tree_code, - tree, const value_range *, - const value_range *); +extern void extract_range_from_binary_expr (value_range_base *, + enum tree_code, + tree, const value_range_base *, + const value_range_base *); extern bool vrp_operand_equal_p (const_tree, const_tree); extern enum value_range_kind intersect_range_with_nonzero_bits diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 1ffb9f6c92c..86829041358 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -118,7 +118,7 @@ vr_values::get_value_range (const_tree var) if (POINTER_TYPE_P (TREE_TYPE (sym)) && (nonnull_arg_p (sym) || get_ptr_nonnull (var))) - set_value_range_to_nonnull (vr, TREE_TYPE (sym)); + vr->set_nonnull (TREE_TYPE (sym)); else if (INTEGRAL_TYPE_P (TREE_TYPE (sym))) { get_range_info (var, *vr); @@ -130,7 +130,7 @@ vr_values::get_value_range (const_tree var) } else if (TREE_CODE (sym) == RESULT_DECL && DECL_BY_REFERENCE (sym)) - set_value_range_to_nonnull (vr, TREE_TYPE (sym)); + vr->set_nonnull (TREE_TYPE (sym)); } return vr; @@ -197,8 +197,8 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) return true; } else - set_value_range (old_vr, new_vr->kind (), - new_vr->min (), new_vr->max (), new_vr->equiv ()); + old_vr->set (new_vr->kind (), + new_vr->min (), new_vr->max (), new_vr->equiv ()); } new_vr->equiv_clear (); @@ -209,7 +209,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) /* Return true if value range VR involves exactly one symbol SYM. */ static bool -symbolic_range_based_on_p (value_range *vr, const_tree sym) +symbolic_range_based_on_p (value_range_base *vr, const_tree sym) { bool neg, min_has_symbol, max_has_symbol; tree inv; @@ -672,7 +672,7 @@ vr_values::extract_range_from_ssa_name (value_range *vr, tree var) if (!var_vr->varying_p ()) vr->deep_copy (var_vr); else - set_value_range (vr, VR_RANGE, var, var, NULL); + vr->set (var); vr->equiv_add (var, get_value_range (var), &vrp_equiv_obstack); } @@ -688,18 +688,18 @@ vr_values::extract_range_from_binary_expr (value_range *vr, { /* Get value ranges for each operand. For constant operands, create a new value range with the operand to simplify processing. */ - value_range vr0, vr1; + value_range_base vr0, vr1; if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0)) - set_value_range_to_value (&vr0, op0, NULL); + vr0.set (op0); else vr0.set_varying (); if (TREE_CODE (op1) == SSA_NAME) vr1 = *(get_value_range (op1)); else if (is_gimple_min_invariant (op1)) - set_value_range_to_value (&vr1, op1, NULL); + vr1.set (op1); else vr1.set_varying (); @@ -718,7 +718,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, vrp_val_max (expr_type)); } - extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1); + ::extract_range_from_binary_expr (vr, code, expr_type, &vr0, &vr1); /* Set value_range for n in following sequence: def = __builtin_memchr (arg, 0, sz) @@ -748,7 +748,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); tree range_min = build_zero_cst (expr_type); tree range_max = wide_int_to_tree (expr_type, wmax - 1); - set_value_range (vr, VR_RANGE, range_min, range_max, NULL); + vr->set (VR_RANGE, range_min, range_max); return; } } @@ -769,17 +769,17 @@ vr_values::extract_range_from_binary_expr (value_range *vr, /* Try with VR0 and [-INF, OP1]. */ if (is_gimple_min_invariant (minus_p ? vr0.max () : vr0.min ())) - set_value_range (&n_vr1, VR_RANGE, vrp_val_min (expr_type), op1, NULL); + n_vr1.set (VR_RANGE, vrp_val_min (expr_type), op1); /* Try with VR0 and [OP1, +INF]. */ else if (is_gimple_min_invariant (minus_p ? vr0.min () : vr0.max ())) - set_value_range (&n_vr1, VR_RANGE, op1, vrp_val_max (expr_type), NULL); + n_vr1.set (VR_RANGE, op1, vrp_val_max (expr_type)); /* Try with VR0 and [OP1, OP1]. */ else - set_value_range (&n_vr1, VR_RANGE, op1, op1, NULL); + n_vr1.set (VR_RANGE, op1, op1); - extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &n_vr1); + ::extract_range_from_binary_expr (vr, code, expr_type, &vr0, &n_vr1); } if (vr->varying_p () @@ -793,17 +793,17 @@ vr_values::extract_range_from_binary_expr (value_range *vr, /* Try with [-INF, OP0] and VR1. */ if (is_gimple_min_invariant (minus_p ? vr1.max () : vr1.min ())) - set_value_range (&n_vr0, VR_RANGE, vrp_val_min (expr_type), op0, NULL); + n_vr0.set (VR_RANGE, vrp_val_min (expr_type), op0); /* Try with [OP0, +INF] and VR1. */ else if (is_gimple_min_invariant (minus_p ? vr1.min (): vr1.max ())) - set_value_range (&n_vr0, VR_RANGE, op0, vrp_val_max (expr_type), NULL); + n_vr0.set (VR_RANGE, op0, vrp_val_max (expr_type)); /* Try with [OP0, OP0] and VR1. */ else - set_value_range (&n_vr0, VR_RANGE, op0, op0, NULL); + n_vr0.set (op0); - extract_range_from_binary_expr_1 (vr, code, expr_type, &n_vr0, &vr1); + ::extract_range_from_binary_expr (vr, code, expr_type, &n_vr0, &vr1); } /* If we didn't derive a range for MINUS_EXPR, and @@ -819,7 +819,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, || (vr1.kind () == VR_ANTI_RANGE && vr1.min () == op0 && vr1.min () == vr1.max ()))) - set_value_range_to_nonnull (vr, expr_type); + vr->set_nonnull (expr_type); } /* Extract range information from a unary expression CODE OP0 based on @@ -830,14 +830,14 @@ void vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code, tree type, tree op0) { - value_range vr0; + value_range_base vr0; /* Get value ranges for the operand. For constant operands, create a new value range with the operand to simplify processing. */ if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0)) - set_value_range_to_value (&vr0, op0, NULL); + vr0.set (op0); else vr0.set_varying (); @@ -854,26 +854,28 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt) /* Get value ranges for each operand. For constant operands, create a new value range with the operand to simplify processing. */ tree op0 = gimple_assign_rhs2 (stmt); - value_range vr0; + value_range tem0; + value_range *vr0 = &tem0; if (TREE_CODE (op0) == SSA_NAME) - vr0 = *(get_value_range (op0)); + vr0 = get_value_range (op0); else if (is_gimple_min_invariant (op0)) - set_value_range_to_value (&vr0, op0, NULL); + tem0.set (op0); else - vr0.set_varying (); + tem0.set_varying (); tree op1 = gimple_assign_rhs3 (stmt); - value_range vr1; + value_range tem1; + value_range *vr1 = &tem1; if (TREE_CODE (op1) == SSA_NAME) - vr1 = *(get_value_range (op1)); + vr1 = get_value_range (op1); else if (is_gimple_min_invariant (op1)) - set_value_range_to_value (&vr1, op1, NULL); + tem1.set (op1); else - vr1.set_varying (); + tem1.set_varying (); /* The resulting value range is the union of the operand ranges */ - vr->deep_copy (&vr0); - vr->union_ (&vr1); + vr->deep_copy (vr0); + vr->union_ (vr1); } @@ -896,7 +898,7 @@ vr_values::extract_range_from_comparison (value_range *vr, enum tree_code code, type. */ val = fold_convert (type, val); if (is_gimple_min_invariant (val)) - set_value_range_to_value (vr, val, NULL); + vr->set (val); else vr->update (VR_RANGE, val, val); } @@ -915,18 +917,18 @@ bool vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type, tree op0, tree op1, bool *ovf) { - value_range vr0, vr1; + value_range_base vr0, vr1; if (TREE_CODE (op0) == SSA_NAME) vr0 = *get_value_range (op0); else if (TREE_CODE (op0) == INTEGER_CST) - set_value_range_to_value (&vr0, op0, NULL); + vr0.set (op0); else vr0.set_varying (); if (TREE_CODE (op1) == SSA_NAME) vr1 = *get_value_range (op1); else if (TREE_CODE (op1) == INTEGER_CST) - set_value_range_to_value (&vr1, op1, NULL); + vr1.set (op1); else vr1.set_varying (); @@ -1044,7 +1046,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL && cfun->after_inlining) { - set_value_range_to_null (vr, type); + vr->set_null (type); return; } break; @@ -1185,8 +1187,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) maxi = prec - 1; goto bitop_builtin; bitop_builtin: - set_value_range (vr, VR_RANGE, build_int_cst (type, mini), - build_int_cst (type, maxi), NULL); + vr->set (VR_RANGE, build_int_cst (type, mini), + build_int_cst (type, maxi)); return; case CFN_UBSAN_CHECK_ADD: subcode = PLUS_EXPR; @@ -1213,10 +1215,9 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) size = targetm.goacc.dim_limit (axis); tree type = TREE_TYPE (gimple_call_lhs (stmt)); - set_value_range (vr, VR_RANGE, - build_int_cst (type, is_pos ? 0 : 1), - size ? build_int_cst (type, size - is_pos) - : vrp_val_max (type), NULL); + vr->set(VR_RANGE, build_int_cst (type, is_pos ? 0 : 1), + size + ? build_int_cst (type, size - is_pos) : vrp_val_max (type)); } return; case CFN_BUILT_IN_STRLEN: @@ -1230,7 +1231,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); tree range_min = build_zero_cst (type); tree range_max = wide_int_to_tree (type, wmax - 1); - set_value_range (vr, VR_RANGE, range_min, range_max, NULL); + vr->set (VR_RANGE, range_min, range_max); return; } break; @@ -1292,8 +1293,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) { /* This is the boolean return value whether compare and exchange changed anything or not. */ - set_value_range (vr, VR_RANGE, build_int_cst (type, 0), - build_int_cst (type, 1), NULL); + vr->set (VR_RANGE, build_int_cst (type, 0), + build_int_cst (type, 1)); return; } break; @@ -1309,15 +1310,13 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) bool ovf = false; if (check_for_binary_op_overflow (subcode, type, op0, op1, &ovf)) - set_value_range_to_value (vr, - build_int_cst (type, ovf), - NULL); + vr->set (build_int_cst (type, ovf)); else if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) vr->set_varying (); else - set_value_range (vr, VR_RANGE, build_int_cst (type, 0), - build_int_cst (type, 1), NULL); + vr->set (VR_RANGE, build_int_cst (type, 0), + build_int_cst (type, 1)); } else if (types_compatible_p (type, TREE_TYPE (op0)) && types_compatible_p (type, TREE_TYPE (op1))) @@ -1341,7 +1340,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) type, op0); extract_range_from_unary_expr (&vr1, NOP_EXPR, type, op1); - extract_range_from_binary_expr_1 (vr, subcode, type, + ::extract_range_from_binary_expr (vr, subcode, type, &vr0, &vr1); flag_wrapv = saved_flag_wrapv; } @@ -1354,7 +1353,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) && gimple_stmt_nonnegative_warnv_p (stmt, &sop)) set_value_range_to_nonnegative (vr, type); else if (vrp_stmt_computes_nonzero (stmt)) - set_value_range_to_nonnull (vr, type); + vr->set_nonnull (type); else vr->set_varying (); } @@ -1390,7 +1389,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt) gimple_assign_rhs2 (stmt)); else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) - set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL); + vr->set (gimple_assign_rhs1 (stmt)); else vr->set_varying (); @@ -1672,7 +1671,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, /* Like in PR19590, scev can return a constant function. */ if (is_gimple_min_invariant (chrec)) { - set_value_range_to_value (vr, chrec, NULL); + vr->set (chrec); return; } @@ -1751,12 +1750,12 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, /* Likewise if the addition did. */ if (maxvr.kind () == VR_RANGE) { - value_range initvr; + value_range_base initvr; if (TREE_CODE (init) == SSA_NAME) initvr = *(get_value_range (init)); else if (is_gimple_min_invariant (init)) - set_value_range_to_value (&initvr, init, NULL); + initvr.set (init); else return; @@ -1993,7 +1992,7 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p, } else if (is_gimple_min_invariant (tem)) { - set_value_range_to_value (vr, tem, NULL); + vr->set (tem); return; } } @@ -2007,18 +2006,22 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p, /* Helper that gets the value range of the SSA_NAME with version I or a symbolic range containing the SSA_NAME only if the value range - is varying or undefined. */ + is varying or undefined. Uses TEM as storage for the alternate range. */ -value_range -vr_values::get_vr_for_comparison (int i) +value_range * +vr_values::get_vr_for_comparison (int i, value_range *tem) { - value_range vr = *get_value_range (ssa_name (i)); + /* Shallow-copy equiv bitmap. */ + value_range *vr = 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 have N_i in their ranges. */ - if (vr.varying_p () || vr.undefined_p ()) - vr = value_range (VR_RANGE, ssa_name (i), ssa_name (i), NULL); + if (vr->varying_p () || vr->undefined_p ()) + { + tem->set (ssa_name (i)); + return tem; + } return vr; } @@ -2038,7 +2041,7 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, tree retval, t; int used_strict_overflow; bool sop; - value_range equiv_vr; + value_range *equiv_vr, tem_vr; /* Get the set of equivalences for VAR. */ e = get_value_range (var)->equiv (); @@ -2048,9 +2051,9 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, used_strict_overflow = -1; /* Compare vars' value range with val. */ - equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var)); + equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr); sop = false; - retval = compare_range_with_value (comp, &equiv_vr, val, &sop); + retval = compare_range_with_value (comp, equiv_vr, val, &sop); if (retval) used_strict_overflow = sop ? 1 : 0; @@ -2074,9 +2077,9 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, && prop_simulate_again_p (SSA_NAME_DEF_STMT (name))) continue; - equiv_vr = get_vr_for_comparison (i); + equiv_vr = get_vr_for_comparison (i, &tem_vr); sop = false; - t = compare_range_with_value (comp, &equiv_vr, val, &sop); + t = compare_range_with_value (comp, equiv_vr, val, &sop); if (t) { /* If we get different answers from different members @@ -2173,7 +2176,8 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2, if (! ssa_name (i1)) continue; - value_range vr1 = get_vr_for_comparison (i1); + value_range tem_vr1; + value_range *vr1 = get_vr_for_comparison (i1, &tem_vr1); t = retval = NULL_TREE; EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2) @@ -2183,9 +2187,10 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2, bool sop = false; - value_range vr2 = get_vr_for_comparison (i2); + value_range tem_vr2; + value_range *vr2 = get_vr_for_comparison (i2, &tem_vr2); - t = compare_ranges (comp, &vr1, &vr2, &sop); + t = compare_ranges (comp, vr1, vr2, &sop); if (t) { /* If we get different answers from different members @@ -2737,7 +2742,8 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) if (e->flags & EDGE_EXECUTABLE) { tree arg = PHI_ARG_DEF (phi, i); - value_range vr_arg; + value_range vr_arg_tem; + value_range *vr_arg = &vr_arg_tem; ++edges; @@ -2750,30 +2756,35 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) && e->flags & EDGE_DFS_BACK) may_simulate_backedge_again = true; - vr_arg = *(get_value_range (arg)); + value_range *vr_arg_ = get_value_range (arg); /* Do not allow equivalences or symbolic ranges to leak in from backedges. That creates invalid equivalencies. See PR53465 and PR54767. */ if (e->flags & EDGE_DFS_BACK) { - if (!vr_arg.varying_p () && !vr_arg.undefined_p ()) + if (!vr_arg_->varying_p () && !vr_arg_->undefined_p ()) { - vr_arg.equiv_clear (); - if (vr_arg.symbolic_p ()) - vr_arg.set_varying (); + vr_arg_tem.set (vr_arg_->kind (), vr_arg_->min (), + vr_arg_->max (), NULL); + if (vr_arg_tem.symbolic_p ()) + vr_arg_tem.set_varying (); } + else + vr_arg = vr_arg_; } /* If the non-backedge arguments range is VR_VARYING then we can still try recording a simple equivalence. */ - else if (vr_arg.varying_p ()) - vr_arg = value_range (VR_RANGE, arg, arg, NULL); + else if (vr_arg_->varying_p ()) + vr_arg_tem.set (arg); + else + vr_arg = vr_arg_; } else { if (TREE_OVERFLOW_P (arg)) arg = drop_tree_overflow (arg); - vr_arg = value_range (VR_RANGE, arg, arg); + vr_arg_tem.set (arg); } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2781,14 +2792,14 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) fprintf (dump_file, "\t"); print_generic_expr (dump_file, arg, dump_flags); fprintf (dump_file, ": "); - dump_value_range (dump_file, &vr_arg); + dump_value_range (dump_file, vr_arg); fprintf (dump_file, "\n"); } if (first) - vr_result->deep_copy (&vr_arg); + vr_result->deep_copy (vr_arg); else - vr_result->union_ (&vr_arg); + vr_result->union_ (vr_arg); first = false; if (vr_result->varying_p ()) @@ -2860,8 +2871,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) vrp_val_max (vr_result->type ()), build_int_cst (vr_result->type (), 1)); - *vr_result = value_range (vr_result->kind (), new_min, new_max, - vr_result->equiv ()); + vr_result->update (vr_result->kind (), new_min, new_max); /* If we dropped either bound to +-INF then if this is a loop PHI node SCEV may known more about its value-range. */ @@ -3219,7 +3229,7 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, tree op0 = gimple_assign_rhs1 (stmt); tree op1 = gimple_assign_rhs2 (stmt); tree op = NULL_TREE; - value_range vr0, vr1; + value_range_base vr0, vr1; wide_int may_be_nonzero0, may_be_nonzero1; wide_int must_be_nonzero0, must_be_nonzero1; wide_int mask; @@ -3227,14 +3237,14 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0)) - set_value_range_to_value (&vr0, op0, NULL); + vr0.set (op0); else return false; if (TREE_CODE (op1) == SSA_NAME) vr1 = *(get_value_range (op1)); else if (is_gimple_min_invariant (op1)) - set_value_range_to_value (&vr1, op1, NULL); + vr1.set (op1); else return false; diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 6ff461bd1e7..6785cb68fa7 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -75,7 +75,7 @@ class vr_values bool vrp_stmt_computes_nonzero (gimple *); bool op_with_boolean_value_range_p (tree); bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *); - value_range get_vr_for_comparison (int); + value_range *get_vr_for_comparison (int, value_range *); tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool); tree compare_names (enum tree_code, tree, tree, bool *); bool two_valued_val_range_p (tree, tree *, tree *); -- 2.30.2