From patchwork Tue Oct 9 16:22:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 981412 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-487215-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="CzWcytXV"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42V2bS2H3Nz9s7W for ; Wed, 10 Oct 2018 03:23:31 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=tP+bgfpCbxNjGWLtmsipgu4NwtLIL3W7mXBytF7zj622SmSH5D wEisnzMLgOQRph0NsnpAnmRAzDEEefD79d30upSWv7g7MHp4l6K+iArRQ8xaDiBi 2MB0a5bfZf6lqiuDfy8slkiCyYGkOoa2C9egbgRYCEW0MjF5Z+Ut2v+eM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=bRA074xqgeDQVWtUbzLdSjwjqt0=; b=CzWcytXV2wgVVEq1CklL RumayEB7es2HbTO5t55krzZ7wdnWlajCnIL4uP+JotkG70MKAsbI9HJGclgZkRC4 7d5OrUe9yRmmT5zuSSJHUnbxP96xQBjRmpguJKKLF+0epiJCMxfqylLTOr4itIjg 31jspXzXrXBBrIcmhbd6tF8= Received: (qmail 125126 invoked by alias); 9 Oct 2018 16:23:16 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 124700 invoked by uid 89); 9 Oct 2018 16:23:15 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, TIME_LIMIT_EXCEEDED, UNSUBSCRIBE_BODY autolearn=unavailable version=3.3.2 spammy=vr, inv, anti, Minimum X-HELO: mail-wm1-f46.google.com Received: from mail-wm1-f46.google.com (HELO mail-wm1-f46.google.com) (209.85.128.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 09 Oct 2018 16:23:05 +0000 Received: by mail-wm1-f46.google.com with SMTP id y144-v6so2640274wmd.4 for ; Tue, 09 Oct 2018 09:23:04 -0700 (PDT) Received: from abulafia.quesejoda.com (142.red-79-151-249.dynamicip.rima-tde.net. [79.151.249.142]) by smtp.gmail.com with ESMTPSA id v10-v6sm17179653wrp.0.2018.10.09.09.23.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Oct 2018 09:23:01 -0700 (PDT) To: gcc-patches Cc: Andrew MacLeod From: Aldy Hernandez Subject: [patch] new API for value_range Message-ID: Date: Tue, 9 Oct 2018 12:22:59 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0 MIME-Version: 1.0 X-IsSubscribed: yes I'm assuming the silence on the RFC means nobody is viscerally opposed to it, so here goes the actual implementation ;-). FWI: https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00157.html My aim is no change to the current functionality, but there are some things that changed slightly (with no appreciable change in bootstrapability or tests). 1. Primarily, we were building value_ranges by modifying them in-flight with no regards to the validity of the resulting range. By enforcing the API, I noticed we periodically built VR_VARYING / VR_UNDEFINED, but left the equivalence bits uncleared. This comment in the original header file indicates that this is invalid behavior: /* Set of SSA names whose value ranges are equivalent to this one. This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */ The API now enforces this upon construction. 2. I also saw us setting min/max when VARYING or UNDEFINED was set. This is invalid. Although these values were being ignored, the API now enforces this. 3. I saw one case in set_value_range_with_overflow() were we were building an invalid range with swapped ranges, where we were silently depending on somebody further up the call chain to swap them for us. I've fixed this at creation. 4. There is one assert in ipcp_vr_lattice which I hope to remove, but left as proof that the original VR_UNDEFINED set was not necessary, as it is now done by default on an empty constructor: - void init () { m_vr.type = VR_UNDEFINED; } + void init () { gcc_assert (m_vr.undefined_p ()); } One last note. The file tree-vrp.c already has a cripple API of sorts in the form of functions (set_value_range_to_varying, etc). I have tried to keep those functions available, by calling the API under the covers, but would be okay in removing them altogether as a follow-up. Please refer to the RFC wrt the min/max/vrtype accessors, as well as the new tree type field. I am quoting the class declaration below to make it easy to review at a high level. Tested on x86-64 Linux. All languages, including Ada and Go. OK for trunk? Aldy class GTY((for_user)) value_range { public: value_range (); value_range (tree type); value_range (value_range_type, tree type, tree, tree, bitmap = NULL); bool operator== (const value_range &) const; bool operator!= (const value_range &) const; void intersect (const value_range *); void union_ (const value_range *); /* Like operator== but ignore equivalence bitmap. */ bool ignore_equivs_equal_p (const value_range &) const; /* Like a operator= but update equivalence bitmap efficiently. */ void copy_with_equiv_update (const value_range *); /* Types of value ranges. */ bool undefined_p () const; bool varying_p () const; bool symbolic_p () const; bool numeric_p () const; void set_undefined (tree = NULL); void set_varying (tree = NULL); /* Equivalence bitmap methods. */ bitmap equiv () const; void set_equiv (bitmap); void equiv_free (); void equiv_copy (const value_range *); void equiv_clear (); void equiv_and (const value_range *); void equiv_ior (const value_range *); /* Misc methods. */ tree type () const; bool null_p () const; bool may_contain_p (tree) const; tree singleton () const; void set_and_canonicalize (enum value_range_type, tree, tree, tree, bitmap); void dump () const; /* Temporary accessors that should eventually be removed. */ enum value_range_type vrtype () const; tree min () const; tree max () const; private: void set (value_range_type, tree type, tree, tree, bitmap); void check (); bool equal_p (const value_range &, bool ignore_equivs) const; enum value_range_type m_vrtype; public: /* These should be private, but GTY is a piece of crap. */ tree m_min; tree m_max; tree m_type; /* Set of SSA names whose value ranges are equivalent to this one. This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */ bitmap m_equiv; }; gcc/ * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::try_find_new_range): Adjust for value_range API. (evrp_range_analyzer::set_ssa_range_info): Same. (evrp_range_analyzer::record_ranges_from_phis): Same. (evrp_range_analyzer::record_ranges_from_stmt): Same. * gimple-ssa-evrp.c (evrp_dom_walker::before_dom_children): Same. * gimple-ssa-sprintf.c (get_int_range): Same. (format_integer): Same. (sprintf_dom_walker::handle_gimple_call): Same. * ipa-cp.c (ipcp_vr_lattice::meet_with_1): Same. (ipcp_vr_lattice::top_p): Same. (ipcp_vr_lattice::bottom_p): Same. (ipcp_vr_lattice::set_to_bottom): Same. (ipa_vr_operation_and_type_effects): Same. (propagate_vr_across_jump_function): Same. (ipcp_store_vr_results): Same. * ipa-prop.c (struct ipa_vr_ggc_hash_traits): Same. (ipa_print_node_jump_functions_for_edge): Same. (ipa_get_value_range): Same. (ipa_compute_jump_functions_for_edge): Same. (ipa_write_jump_function): Same. * tree-ssa-dom.c (simplify_stmt_for_jump_threading): Same. * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis): Same. * vr-values.c (set_value_range_to_nonnegative): Same. (set_value_range_to_truthvalue): Same. (vr_values::get_value_range): Same. (vr_values::set_defs_to_varying): Same. (vr_values::update_value_range): Same. (symbolic_range_based_on_p): Same. (vr_values::op_with_boolean_value_range_p): Same. (vr_values::extract_range_for_var_from_comparison_expr): Same. (vr_values::extract_range_from_ssa_name): Same. (vr_values::extract_range_from_binary_expr): Same. (vr_values::extract_range_from_unary_expr): Same. (vr_values::extract_range_from_cond_expr): Same. (vr_values::extract_range_from_comparison): Same. (vr_values::check_for_binary_op_overflow): Same. (vr_values::extract_range_basic): Same. (vr_values::extract_range_from_assignment): Same. (compare_ranges): Same. (compare_range_with_value): Same. (vr_values::adjust_range_with_scev): Same. (vrp_valueize): Same. (vrp_valueize_1): Same. (vr_values::get_vr_for_comparison): Same. (vr_values::compare_name_with_value): Same. (vr_values::compare_names): Same. (vr_values::vrp_evaluate_conditional): Same. (find_case_label_ranges): Same. (vr_values::vrp_visit_switch_stmt): Same. (vr_values::extract_range_from_phi_node): Same. (vr_values::simplify_div_or_mod_using_ranges): Same. (vr_values::simplify_bit_ops_using_ranges): Same. (test_for_singularity): Same. (range_fits_type_p): Same. (vr_values::simplify_cond_using_ranges_1): Same. (vr_values::simplify_switch_using_ranges): Same. (vr_values::simplify_float_conversion_using_ranges): Same. (vr_values::two_valued_val_range_p): Same. (vr_values::add_equivalence): Rewrite to return adjusted value instead of setting a pointer. * vr-values.h (vr_values::add_equivalence): Adjust to return value. (VR_INITIALIZER): Remove. * tree-vrp.c (value_range::set): New. (value_range::value_range): New. (value_range::copy_with_equiv_update): New. (value_range::check): New. (value_range::equal_p): New. (value_range::ignore_equivs_equal_p): New. (value_range::operator==): New. (value_range::operator!=): New. (value_range::symbolic_p): New. (value_range::numeric_p): New. (value_range::set_undefined): New. (value_range::set_varying): New. (value_range::may_contain_p): New. (value_range::equiv_free): New. (value_range::equiv_copy): New. (value_range::equiv_clear): New. (value_range::equiv_and): New. (value_range::equiv_ior): New. (value_range::singleton): New. (value_range::union_): New. (value_range::intersect): New. (value_range::dump): New. (set_value_range_to_undefined): New. (set_value_range_to_varying): New. (value_range::set_and_canonicalize): New. (set_value_range): Adjust for value_range API. (set_and_canonicalize_value_range): Same. (copy_value_range): Same. (set_value_range_to_nonnull): Same. (set_value_range_to_null): Same. (range_is_null): Same. (range_is_nonnull): Same. (range_int_cst_p): Same. (range_int_cst_singleton_p): Same. (symbolic_range_p): Same. (range_includes_zero_p): Same. (value_range_constant_singleton): Same. (vrp_set_zero_nonzero_bits): Same. (ranges_from_anti_range): Same. (extract_range_into_wide_ints): Same. (extract_range_from_multiplicative_op): Same. (set_value_range_with_overflow): Same. (extract_range_from_binary_expr_1): Same. (extract_range_from_unary_expr): Same. (dump_value_range): Same. (debug_value_range): Same. (vrp_prop::check_array_ref): Same. (vrp_prop::check_mem_ref): Same. (vrp_prop::vrp_initialize): Same. (vrp_prop::visit_stmt): Same. (intersect_ranges): Same. (vrp_prop::visit_phi): Same. (vrp_prop::vrp_finalize): Same. (determine_value_range_1): Same. (determine_value_range): Same. (vrp_intersect_ranges_1): Rename to... (vrp_intersect_1): this. (vrp_intersect_ranges): Rename to... (vrp_intersect): ...this. (vrp_meet_1): Rename to... (vrp_union_1): ...this. (vrp_meet): Rename to... (vrp_union): ...this. * tree-vrp.h (struct value_range): Rewrite into a proper class. (value_range::vrtype): New. (value_range::type): New. (value_range::equiv): New. (value_range::min): New. (value_range::max): New. (value_range::varying_p): New. (value_range::undefined_p): New. (value_range::set_equiv): New. (value_range::null_p): New. diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index e9afa80e191..e3695432c88 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -82,7 +82,7 @@ value_range * evrp_range_analyzer::try_find_new_range (tree name, tree op, tree_code code, tree limit) { - value_range vr = VR_INITIALIZER; + value_range vr (TREE_TYPE (name)); value_range *old_vr = get_value_range (name); /* Discover VR when condition is true. */ @@ -90,11 +90,11 @@ evrp_range_analyzer::try_find_new_range (tree name, limit, &vr); /* If we found any usable VR, set the VR to ssa_name and create a PUSH old value in the stack with the old VR. */ - if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) + if (!vr.undefined_p () && !vr.varying_p ()) { - if (old_vr->type == vr.type - && vrp_operand_equal_p (old_vr->min, vr.min) - && vrp_operand_equal_p (old_vr->max, vr.max)) + if (old_vr->vrtype () == vr.vrtype () + && vrp_operand_equal_p (old_vr->min (), vr.min ()) + && vrp_operand_equal_p (old_vr->max (), vr.max ())) return NULL; value_range *new_vr = vr_values->allocate_value_range (); *new_vr = vr; @@ -110,13 +110,10 @@ evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range *vr) /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) { - if ((vr->type == VR_RANGE - || vr->type == VR_ANTI_RANGE) - && (TREE_CODE (vr->min) == INTEGER_CST) - && (TREE_CODE (vr->max) == INTEGER_CST)) - set_range_info (lhs, vr->type, - wi::to_wide (vr->min), - wi::to_wide (vr->max)); + if (vr->numeric_p ()) + set_range_info (lhs, vr->vrtype (), + wi::to_wide (vr->min ()), + wi::to_wide (vr->max ())); } else if (POINTER_TYPE_P (TREE_TYPE (lhs)) && range_includes_zero_p (vr) == 0) @@ -241,13 +238,13 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) if (virtual_operand_p (lhs)) continue; - value_range vr_result = VR_INITIALIZER; + value_range vr_result (TREE_TYPE (lhs)); bool interesting = stmt_interesting_for_vrp (phi); if (!has_unvisited_preds && interesting) vr_values->extract_range_from_phi_node (phi, &vr_result); else { - set_value_range_to_varying (&vr_result); + set_value_range_to_varying (&vr_result, TREE_TYPE (lhs)); /* When we have an unvisited executable predecessor we can't use PHI arg ranges which may be still UNDEFINED but have to use VARYING for them. But we can still resort to @@ -284,7 +281,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) else if (stmt_interesting_for_vrp (stmt)) { edge taken_edge; - value_range vr = VR_INITIALIZER; + value_range vr; vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr); if (output) { @@ -315,7 +312,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) bitmaps. Ugh. */ value_range *new_vr = vr_values->allocate_value_range (); *new_vr = vr; - new_vr->equiv = NULL; + new_vr->set_equiv (NULL); push_value_range (output, new_vr); } } diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 50e8adc1aad..b075c1051d8 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -161,8 +161,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) value_range *vr = evrp_range_analyzer.get_value_range (output); /* Mark stmts whose output we fully propagate for removal. */ - if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) - && (val = value_range_constant_singleton (vr)) + if ((val = value_range_constant_singleton (vr)) && may_propagate_copy (output, val) && !stmt_could_throw_p (stmt) && !gimple_has_side_effects (stmt)) diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 471bfc45eb8..5bc5607c92f 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -1052,9 +1052,7 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax, { /* Try to determine the range of values of the integer argument. */ value_range *vr = vr_values->get_value_range (arg); - if (vr->type == VR_RANGE - && TREE_CODE (vr->min) == INTEGER_CST - && TREE_CODE (vr->max) == INTEGER_CST) + if (range_int_cst_p (vr)) { HOST_WIDE_INT type_min = (TYPE_UNSIGNED (argtype) @@ -1063,8 +1061,8 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax, HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype)); - *pmin = TREE_INT_CST_LOW (vr->min); - *pmax = TREE_INT_CST_LOW (vr->max); + *pmin = TREE_INT_CST_LOW (vr->min ()); + *pmax = TREE_INT_CST_LOW (vr->max ()); if (*pmin < *pmax) { @@ -1354,12 +1352,10 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values) /* Try to determine the range of values of the integer argument (range information is not available for pointers). */ value_range *vr = vr_values->get_value_range (arg); - if (vr->type == VR_RANGE - && TREE_CODE (vr->min) == INTEGER_CST - && TREE_CODE (vr->max) == INTEGER_CST) + if (range_int_cst_p (vr)) { - argmin = vr->min; - argmax = vr->max; + argmin = vr->min (); + argmax = vr->max (); /* Set KNOWNRANGE if the argument is in a known subrange of the directive's type and neither width nor precision @@ -1372,12 +1368,11 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values) res.argmin = argmin; res.argmax = argmax; } - else if (vr->type == VR_ANTI_RANGE) + else if (vr->vrtype () == VR_ANTI_RANGE) { /* Handle anti-ranges if/when bug 71690 is resolved. */ } - else if (vr->type == VR_VARYING - || vr->type == VR_UNDEFINED) + else if (vr->varying_p () || vr->undefined_p ()) { /* The argument here may be the result of promoting the actual argument to int. Try to determine the type of the actual @@ -3903,12 +3898,10 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi) and use the greater of the two at level 1 and the smaller of them at level 2. */ value_range *vr = evrp_range_analyzer.get_value_range (size); - if (vr->type == VR_RANGE - && TREE_CODE (vr->min) == INTEGER_CST - && TREE_CODE (vr->max) == INTEGER_CST) + if (range_int_cst_p (vr)) dstsize = (warn_level < 2 - ? TREE_INT_CST_LOW (vr->max) - : TREE_INT_CST_LOW (vr->min)); + ? TREE_INT_CST_LOW (vr->max ()) + : TREE_INT_CST_LOW (vr->min ())); /* The destination size is not constant. If the function is bounded (e.g., snprintf) a lower bound of zero doesn't diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 27ae8e0fe27..3223f32a073 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -314,7 +314,7 @@ public: inline bool set_to_bottom (); bool meet_with (const value_range *p_vr); bool meet_with (const ipcp_vr_lattice &other); - void init () { m_vr.type = VR_UNDEFINED; } + void init () { gcc_assert (m_vr.undefined_p ()); } void print (FILE * f); private: @@ -914,28 +914,21 @@ ipcp_vr_lattice::meet_with (const value_range *p_vr) return meet_with_1 (p_vr); } -/* Meet the current value of the lattice with value ranfge described by - OTHER_VR lattice. */ +/* Meet the current value of the lattice with value range described by + OTHER_VR lattice. Return TRUE if anything changed. */ bool ipcp_vr_lattice::meet_with_1 (const value_range *other_vr) { - tree min = m_vr.min, max = m_vr.max; - value_range_type type = m_vr.type; - if (bottom_p ()) return false; - if (other_vr->type == VR_VARYING) + if (other_vr->varying_p ()) return set_to_bottom (); - vrp_meet (&m_vr, other_vr); - if (type != m_vr.type - || min != m_vr.min - || max != m_vr.max) - return true; - else - return false; + value_range save (m_vr); + m_vr.union_ (other_vr); + return !m_vr.ignore_equivs_equal_p (save); } /* Return true if value range information in the lattice is yet unknown. */ @@ -943,7 +936,7 @@ ipcp_vr_lattice::meet_with_1 (const value_range *other_vr) bool ipcp_vr_lattice::top_p () const { - return m_vr.type == VR_UNDEFINED; + return m_vr.undefined_p (); } /* Return true if value range information in the lattice is known to be @@ -952,7 +945,7 @@ ipcp_vr_lattice::top_p () const bool ipcp_vr_lattice::bottom_p () const { - return m_vr.type == VR_VARYING; + return m_vr.varying_p (); } /* Set value range information in the lattice to bottom. Return true if it @@ -961,9 +954,10 @@ ipcp_vr_lattice::bottom_p () const bool ipcp_vr_lattice::set_to_bottom () { - if (m_vr.type == VR_VARYING) + if (m_vr.varying_p ()) return false; - m_vr.type = VR_VARYING; + /* ?? Use any type for VARYING for now. */ + m_vr.set_varying (integer_type_node); return true; } @@ -1882,12 +1876,11 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr, enum tree_code operation, tree dst_type, tree src_type) { - memset (dst_vr, 0, sizeof (*dst_vr)); + *dst_vr = value_range (); extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); - if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE) - return true; - else + if (dst_vr->varying_p () || dst_vr->undefined_p ()) return false; + return true; } /* Propagate value range across jump function JFUNC that is associated with @@ -1940,11 +1933,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, if (TREE_OVERFLOW_P (val)) val = drop_tree_overflow (val); - value_range tmpvr; - memset (&tmpvr, 0, sizeof (tmpvr)); - tmpvr.type = VR_RANGE; - tmpvr.min = val; - tmpvr.max = val; + value_range tmpvr (VR_RANGE, TREE_TYPE (val), val, val); return dest_lat->meet_with (&tmpvr); } } @@ -1953,7 +1942,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, if (jfunc->m_vr && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR, param_type, - TREE_TYPE (jfunc->m_vr->min))) + jfunc->m_vr->type ())) return dest_lat->meet_with (&vr); else return dest_lat->set_to_bottom (); @@ -5028,9 +5017,9 @@ ipcp_store_vr_results (void) && !plats->m_value_range.top_p ()) { vr.known = true; - vr.type = plats->m_value_range.m_vr.type; - vr.min = wi::to_wide (plats->m_value_range.m_vr.min); - vr.max = wi::to_wide (plats->m_value_range.m_vr.max); + vr.type = plats->m_value_range.m_vr.vrtype (); + vr.min = wi::to_wide (plats->m_value_range.m_vr.min ()); + vr.max = wi::to_wide (plats->m_value_range.m_vr.max ()); } else { diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 8b19fe3f391..ceecce1241f 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -113,16 +113,16 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove static hashval_t hash (const value_range *p) { - gcc_checking_assert (!p->equiv); - inchash::hash hstate (p->type); - hstate.add_ptr (p->min); - hstate.add_ptr (p->max); + gcc_checking_assert (!p->equiv ()); + inchash::hash hstate (p->vrtype ()); + hstate.add_ptr (p->min ()); + hstate.add_ptr (p->max ()); return hstate.end (); } static bool equal (const value_range *a, const value_range *b) { - return a->type == b->type && a->min == b->min && a->max == b->max; + return a->ignore_equivs_equal_p (*b); } static void mark_empty (value_range *&p) @@ -398,10 +398,10 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs) { fprintf (f, " VR "); fprintf (f, "%s[", - (jump_func->m_vr->type == VR_ANTI_RANGE) ? "~" : ""); - print_decs (wi::to_wide (jump_func->m_vr->min), f); + (jump_func->m_vr->vrtype () == VR_ANTI_RANGE) ? "~" : ""); + print_decs (wi::to_wide (jump_func->m_vr->min ()), f); fprintf (f, ", "); - print_decs (wi::to_wide (jump_func->m_vr->max), f); + print_decs (wi::to_wide (jump_func->m_vr->max ()), f); fprintf (f, "]\n"); } else @@ -1791,11 +1791,7 @@ ipa_get_value_range (value_range *tmp) static value_range * ipa_get_value_range (enum value_range_type type, tree min, tree max) { - value_range tmp; - tmp.type = type; - tmp.min = min; - tmp.max = max; - tmp.equiv = NULL; + value_range tmp (type, TREE_TYPE (min), min, max); return ipa_get_value_range (&tmp); } @@ -1890,16 +1886,13 @@ 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)) { - value_range tmpvr,resvr; - - tmpvr.type = type; - tmpvr.min = wide_int_to_tree (TREE_TYPE (arg), min); - tmpvr.max = wide_int_to_tree (TREE_TYPE (arg), max); - tmpvr.equiv = NULL; - memset (&resvr, 0, sizeof (resvr)); + value_range resvr; + value_range tmpvr (type, TREE_TYPE (arg), + 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.type == VR_RANGE || resvr.type == VR_ANTI_RANGE) + if (!resvr.undefined_p () && !resvr.varying_p ()) ipa_set_jfunc_vr (jfunc, &resvr); else gcc_assert (!jfunc->m_vr); @@ -4126,9 +4119,9 @@ ipa_write_jump_function (struct output_block *ob, if (jump_func->m_vr) { streamer_write_enum (ob->main_stream, value_rang_type, - VR_LAST, jump_func->m_vr->type); - stream_write_tree (ob, jump_func->m_vr->min, true); - stream_write_tree (ob, jump_func->m_vr->max, true); + VR_LAST, jump_func->m_vr->vrtype ()); + stream_write_tree (ob, jump_func->m_vr->min (), true); + stream_write_tree (ob, jump_func->m_vr->max (), true); } } diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index f7cc034b26e..cb74ed15d72 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -882,25 +882,27 @@ simplify_stmt_for_jump_threading (gimple *stmt, return NULL_TREE; value_range *vr = x_vr_values->get_value_range (op); - if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE) - || symbolic_range_p (vr)) + if (vr->undefined_p () + || vr->varying_p () + || vr->symbolic_p ()) return NULL_TREE; - if (vr->type == VR_RANGE) + if (vr->vrtype () == VR_RANGE) { size_t i, j; - find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j); + find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j); if (i == j) { tree label = gimple_switch_label (switch_stmt, i); + tree singleton; if (CASE_HIGH (label) != NULL_TREE - ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0 - && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0) - : (tree_int_cst_equal (CASE_LOW (label), vr->min) - && tree_int_cst_equal (vr->min, vr->max))) + ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0 + && tree_int_cst_compare (CASE_HIGH (label), vr->max ()) >= 0) + : ((singleton = vr->singleton ()) + && tree_int_cst_equal (CASE_LOW (label), singleton))) return label; if (i > j) @@ -908,7 +910,7 @@ simplify_stmt_for_jump_threading (gimple *stmt, } } - if (vr->type == VR_ANTI_RANGE) + if (vr->vrtype () == VR_ANTI_RANGE) { unsigned n = gimple_switch_num_labels (switch_stmt); tree min_label = gimple_switch_label (switch_stmt, 1); @@ -917,10 +919,10 @@ simplify_stmt_for_jump_threading (gimple *stmt, /* The default label will be taken only if the anti-range of the operand is entirely outside the bounds of all the (non-default) case labels. */ - if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0 + if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0 && (CASE_HIGH (max_label) != NULL_TREE - ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0 - : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0)) + ? tree_int_cst_compare (vr->max (), CASE_HIGH (max_label)) >= 0 + : tree_int_cst_compare (vr->max (), CASE_LOW (max_label)) >= 0)) return gimple_switch_label (switch_stmt, 0); } return NULL_TREE; @@ -936,11 +938,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, { edge dummy_e; tree dummy_tree; - value_range new_vr = VR_INITIALIZER; + value_range new_vr; x_vr_values->extract_range_from_stmt (stmt, &dummy_e, &dummy_tree, &new_vr); - if (range_int_cst_singleton_p (&new_vr)) - return new_vr.min; + tree singleton; + if ((singleton = new_vr.singleton ())) + return singleton; } } return NULL; diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index a2304493495..9f510730aed 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 (); - memset (new_vr, 0, sizeof (value_range)); + *new_vr = value_range (); /* There are three cases to consider: @@ -183,7 +183,7 @@ record_temporary_equivalences_from_phis (edge e, else if (TREE_CODE (src) == INTEGER_CST) set_value_range_to_value (new_vr, src, NULL); else - set_value_range_to_varying (new_vr); + set_value_range_to_varying (new_vr, TREE_TYPE (src)); /* This is a temporary range for DST, so push it. */ evrp_range_analyzer->push_value_range (dst, new_vr); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index cbc2ea2f26b..555f515f609 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -73,6 +73,248 @@ along with GCC; see the file COPYING3. If not see for still active basic-blocks. */ static sbitmap *live; +static void vrp_union (value_range *, const value_range *); +static void vrp_intersect (value_range *, const value_range *); + +/* Initialize value_range. */ + +void +value_range::set (enum value_range_type vrtype, tree type, + tree min, tree max, bitmap equiv) +{ + m_type = type; + m_vrtype = vrtype; + m_min = min; + m_max = max; + + /* Since updating the equivalence set involves deep copying the + bitmaps, only do it if absolutely necessary. + + All equivalence bitmaps are allocated from the same obstack. So + we can use the obstack associated with EQUIV to allocate vr->equiv. */ + if (m_equiv == NULL + && equiv != NULL) + m_equiv = BITMAP_ALLOC (equiv->obstack); + + if (equiv != m_equiv) + { + if (equiv && !bitmap_empty_p (equiv)) + bitmap_copy (m_equiv, equiv); + else + bitmap_clear (m_equiv); + } + if (flag_checking) + check (); +} + +value_range::value_range (value_range_type vrtype, tree type, + tree min, tree max, bitmap equiv) +{ + m_equiv = NULL; + set (vrtype, type, min, max, equiv); +} + +/* Initialize value_range from FROM and update equivalence table. */ + +void +value_range::copy_with_equiv_update (const value_range *from) +{ + set (from->m_vrtype, from->m_type, from->m_min, from->m_max, from->m_equiv); +} + +/* Check the validity of the range. */ + +void +value_range::check () +{ + if (flag_checking + && (m_vrtype == VR_RANGE || m_vrtype == VR_ANTI_RANGE)) + { + int cmp; + + gcc_assert (m_min && m_max); + + gcc_assert (!TREE_OVERFLOW_P (m_min) && !TREE_OVERFLOW_P (m_max)); + + /* An anti range cannot be [-MIN, +MAX] because that would + be either empty or VR_UNDEFINED. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (m_min)) && m_vrtype == VR_ANTI_RANGE) + gcc_assert (!vrp_val_is_min (m_min) || !vrp_val_is_max (m_max)); + + cmp = compare_values (m_min, m_max); + gcc_assert (cmp == 0 || cmp == -1 || cmp == -2); + } + + if (flag_checking + && (m_vrtype == VR_UNDEFINED || m_vrtype == VR_VARYING)) + { + gcc_assert (m_min == NULL_TREE && m_max == NULL_TREE); + gcc_assert (m_equiv == NULL || bitmap_empty_p (m_equiv)); + } +} + +/* Returns TRUE if THIS == OTHER. Ignores the equivalence bitmap if + IGNORE_EQUIVS is TRUE. */ + +bool +value_range::equal_p (const value_range &other, bool ignore_equivs) const +{ + return (m_type == other.m_type + && m_vrtype == other.m_vrtype + && vrp_operand_equal_p (m_min, other.m_min) + && vrp_operand_equal_p (m_max, other.m_max) + && (ignore_equivs + || vrp_bitmap_equal_p (m_equiv, other.m_equiv))); +} + +bool +value_range::ignore_equivs_equal_p (const value_range &other) const +{ + return equal_p (other, /*ignore_equivs=*/true); +} + +bool +value_range::operator== (const value_range &other) const +{ + return equal_p (other, /*ignore_equivs=*/false); +} + +bool +value_range::operator!= (const value_range &other) const +{ + return !(*this == other); +} + +bool +value_range::symbolic_p () const +{ + return (!varying_p () + && !undefined_p () + && (!is_gimple_min_invariant (m_min) + || !is_gimple_min_invariant (m_max))); +} + +/* NOTE: Numeric is not the inverse of symbolic_p because the range + could also be varying or undefined. Ideally they should be inverse + of each other, with varying only applying to symbolics. Varying of + numerics would be represented as [-MIN, +MAX]. */ + +bool +value_range::numeric_p () const +{ + return (!varying_p () + && !undefined_p () + && TREE_CODE (m_min) == INTEGER_CST + && TREE_CODE (m_max) == INTEGER_CST); +} + +void +value_range::set_undefined (tree type) +{ + if (m_equiv) + bitmap_clear (m_equiv); + if (type) + m_type = type; + else + gcc_assert (m_type); + *this = value_range (VR_UNDEFINED, m_type, NULL, NULL, m_equiv); +} + +void +value_range::set_varying (tree type) +{ + if (m_equiv) + bitmap_clear (m_equiv); + if (type) + m_type = type; + else + gcc_assert (m_type); + *this = value_range (VR_VARYING, m_type, NULL, NULL, m_equiv); +} + +bool +value_range::may_contain_p (tree val) const +{ + if (varying_p ()) + return true; + + if (undefined_p ()) + return true; + + if (m_vrtype == VR_ANTI_RANGE) + { + int res = value_inside_range (val, m_min, m_max); + return res == 0 || res == -2; + } + return value_inside_range (val, m_min, m_max) != 0; +} + +void +value_range::equiv_free () +{ + BITMAP_FREE (m_equiv); + m_equiv = NULL; +} + +void +value_range::equiv_copy (const value_range *other) +{ + bitmap_copy (m_equiv, other->m_equiv); +} + +void +value_range::equiv_clear () +{ + if (m_equiv) + bitmap_clear (m_equiv); +} + +void +value_range::equiv_and (const value_range *other) +{ + if (m_equiv && other->m_equiv) + bitmap_and_into (m_equiv, other->m_equiv); +} + +void +value_range::equiv_ior (const value_range *other) +{ + bitmap_ior_into (m_equiv, other->m_equiv); +} + +/* If value range is a singleton, return the singleton, otherwise + return NULL. Note: A singleton can be any gimple invariant, not + just constants. So, [&x, &x] counts as a singleton. */ + +tree +value_range::singleton () const +{ + if (m_vrtype == VR_RANGE + && vrp_operand_equal_p (m_min, m_max) + && is_gimple_min_invariant (m_min)) + return m_min; + return NULL_TREE; +} + +void +value_range::union_ (const value_range *other) +{ + vrp_union (this, other); +} + +void +value_range::intersect (const value_range *other) +{ + vrp_intersect (this, other); +} + +void +value_range::dump () const +{ + dump_value_range (stderr, this); + fprintf (stderr, "\n"); +} + /* Return true if the SSA name NAME is live on the edge E. */ static bool @@ -243,80 +485,41 @@ intersect_range_with_nonzero_bits (enum value_range_type vr_type, /* Set value range VR to VR_UNDEFINED. */ static inline void -set_value_range_to_undefined (value_range *vr) +set_value_range_to_undefined (value_range *vr, tree type) { - vr->type = VR_UNDEFINED; - vr->min = vr->max = NULL_TREE; - if (vr->equiv) - bitmap_clear (vr->equiv); + vr->set_undefined (type); } /* Set value range VR to VR_VARYING. */ void -set_value_range_to_varying (value_range *vr) +set_value_range_to_varying (value_range *vr, tree type) { - vr->type = VR_VARYING; - vr->min = vr->max = NULL_TREE; - if (vr->equiv) - bitmap_clear (vr->equiv); + vr->set_varying (type); } /* Set value range VR to {T, MIN, MAX, EQUIV}. */ void -set_value_range (value_range *vr, enum value_range_type t, tree min, - tree max, bitmap equiv) +set_value_range (value_range *vr, enum value_range_type vrtype, + tree min, tree max, bitmap equiv) { - /* Check the validity of the range. */ - if (flag_checking - && (t == VR_RANGE || t == VR_ANTI_RANGE)) - { - int cmp; - - gcc_assert (min && max); - - gcc_assert (!TREE_OVERFLOW_P (min) && !TREE_OVERFLOW_P (max)); - - if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE) - gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max)); - - cmp = compare_values (min, max); - gcc_assert (cmp == 0 || cmp == -1 || cmp == -2); - } - - if (flag_checking - && (t == VR_UNDEFINED || t == VR_VARYING)) - { - gcc_assert (min == NULL_TREE && max == NULL_TREE); - gcc_assert (equiv == NULL || bitmap_empty_p (equiv)); - } - - vr->type = t; - vr->min = min; - vr->max = max; - - /* Since updating the equivalence set involves deep copying the - bitmaps, only do it if absolutely necessary. - - All equivalence bitmaps are allocated from the same obstack. So - we can use the obstack associated with EQUIV to allocate vr->equiv. */ - if (vr->equiv == NULL - && equiv != NULL) - vr->equiv = BITMAP_ALLOC (equiv->obstack); + gcc_assert (min && max); + value_range tmp (vrtype, TREE_TYPE (min), min, max, equiv); + vr->copy_with_equiv_update (&tmp); +} - if (equiv != vr->equiv) - { - if (equiv && !bitmap_empty_p (equiv)) - bitmap_copy (vr->equiv, equiv); - else - bitmap_clear (vr->equiv); - } +void +set_value_range (value_range *vr, tree type, enum value_range_type vrtype, + tree min, tree max, bitmap equiv) +{ + value_range tmp (vrtype, type, min, max, equiv); + vr->copy_with_equiv_update (&tmp); } -/* Set value range VR to the canonical form of {T, MIN, MAX, EQUIV}. - This means adjusting T, MIN and MAX representing the case of a +/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}. + This means adjusting VRTYPE, MIN and MAX representing the case of a wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX] as anti-rage ~[MAX+1, MIN-1]. Likewise for wrapping anti-ranges. In corner cases where MAX+1 or MIN-1 wraps this will fall back @@ -325,18 +528,18 @@ set_value_range (value_range *vr, enum value_range_type t, tree min, extract ranges from var + CST op limit. */ void -set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, - tree min, tree max, bitmap equiv) +value_range::set_and_canonicalize (enum value_range_type vrtype, tree type, + tree min, tree max, bitmap equiv) { /* Use the canonical setters for VR_UNDEFINED and VR_VARYING. */ - if (t == VR_UNDEFINED) + if (vrtype == VR_UNDEFINED) { - set_value_range_to_undefined (vr); + set_undefined (type); return; } - else if (t == VR_VARYING) + else if (vrtype == VR_VARYING) { - set_value_range_to_varying (vr); + set_varying (type); return; } @@ -344,7 +547,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, if (TREE_CODE (min) != INTEGER_CST || TREE_CODE (max) != INTEGER_CST) { - set_value_range (vr, t, min, max, equiv); + set_value_range (this, vrtype, min, max, equiv); return; } @@ -359,7 +562,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, for VR_ANTI_RANGE empty range, so drop to varying as well. */ if (TYPE_PRECISION (TREE_TYPE (min)) == 1) { - set_value_range_to_varying (vr); + set_varying (TREE_TYPE (min)); return; } @@ -373,15 +576,15 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, to varying in this case. */ if (tree_int_cst_lt (max, min)) { - set_value_range_to_varying (vr); + set_varying (TREE_TYPE (min)); return; } - t = t == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE; + vrtype = vrtype == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE; } /* Anti-ranges that can be represented as ranges should be so. */ - if (t == VR_ANTI_RANGE) + if (vrtype == VR_ANTI_RANGE) { /* For -fstrict-enums we may receive out-of-range ranges so consider values < -INF and values > INF as -INF/INF as well. */ @@ -395,7 +598,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, { /* We cannot deal with empty ranges, drop to varying. ??? This could be VR_UNDEFINED instead. */ - set_value_range_to_varying (vr); + set_varying (type); return; } else if (TYPE_PRECISION (TREE_TYPE (min)) == 1 @@ -407,7 +610,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, min = max = vrp_val_max (TREE_TYPE (min)); else min = max = vrp_val_min (TREE_TYPE (min)); - t = VR_RANGE; + vrtype = VR_RANGE; } else if (is_min /* As a special exception preserve non-null ranges. */ @@ -417,14 +620,14 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, tree one = build_int_cst (TREE_TYPE (max), 1); min = int_const_binop (PLUS_EXPR, max, one); max = vrp_val_max (TREE_TYPE (max)); - t = VR_RANGE; + vrtype = VR_RANGE; } else if (is_max) { tree one = build_int_cst (TREE_TYPE (min), 1); max = int_const_binop (MINUS_EXPR, min, one); min = vrp_val_min (TREE_TYPE (min)); - t = VR_RANGE; + vrtype = VR_RANGE; } } @@ -432,7 +635,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, to make sure VRP iteration terminates, otherwise we can get into oscillations. */ - set_value_range (vr, t, min, max, equiv); + set_value_range (this, type, vrtype, min, max, equiv); } /* Copy value range FROM into value range TO. */ @@ -440,7 +643,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t, void copy_value_range (value_range *to, const value_range *from) { - set_value_range (to, from->type, from->min, from->max, from->equiv); + to->copy_with_equiv_update (from); } /* Set value range VR to a single value. This function is only called @@ -462,7 +665,7 @@ void set_value_range_to_nonnull (value_range *vr, tree type) { tree zero = build_int_cst (type, 0); - set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv); + set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv ()); } @@ -471,7 +674,7 @@ set_value_range_to_nonnull (value_range *vr, tree type) void set_value_range_to_null (value_range *vr, tree type) { - set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv); + set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv ()); } /* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */ @@ -503,9 +706,15 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2) static inline bool range_is_null (const value_range *vr) { - return vr->type == VR_RANGE - && integer_zerop (vr->min) - && integer_zerop (vr->max); + return vr->null_p (); +} + +static inline bool +range_is_nonnull (const value_range *vr) +{ + return (vr->vrtype () == VR_ANTI_RANGE + && vr->min () == vr->max () + && integer_zerop (vr->min ())); } /* Return true if max and min of VR are INTEGER_CST. It's not necessary @@ -514,9 +723,9 @@ range_is_null (const value_range *vr) bool range_int_cst_p (const value_range *vr) { - return (vr->type == VR_RANGE - && TREE_CODE (vr->max) == INTEGER_CST - && TREE_CODE (vr->min) == INTEGER_CST); + return (vr->vrtype () == VR_RANGE + && TREE_CODE (vr->min ()) == INTEGER_CST + && TREE_CODE (vr->max ()) == INTEGER_CST); } /* Return true if VR is a INTEGER_CST singleton. */ @@ -525,16 +734,7 @@ bool range_int_cst_singleton_p (const value_range *vr) { return (range_int_cst_p (vr) - && tree_int_cst_equal (vr->min, vr->max)); -} - -/* Return true if value range VR involves at least one symbol. */ - -bool -symbolic_range_p (const value_range *vr) -{ - return (!is_gimple_min_invariant (vr->min) - || !is_gimple_min_invariant (vr->max)); + && tree_int_cst_equal (vr->min (), vr->max ())); } /* Return the single symbol (an SSA_NAME) contained in T if any, or NULL_TREE @@ -849,34 +1049,20 @@ value_inside_range (tree val, tree min, tree max) bool range_includes_zero_p (const value_range *vr) { - if (vr->type == VR_VARYING) - return true; - - /* Ughh, we don't know. We choose not to optimize. */ - if (vr->type == VR_UNDEFINED) - return true; - - tree zero = build_int_cst (TREE_TYPE (vr->min), 0); - if (vr->type == VR_ANTI_RANGE) - { - int res = value_inside_range (zero, vr->min, vr->max); - return res == 0 || res == -2; - } - return value_inside_range (zero, vr->min, vr->max) != 0; + tree zero = build_int_cst (vr->type (), 0); + return vr->may_contain_p (zero); } -/* If *VR has a value rante that is a single constant value return that, - otherwise return NULL_TREE. */ +/* If *VR has a value range that is a single constant value return that, + otherwise return NULL_TREE. + + ?? This actually returns TRUE for [&x, &x], so perhaps "constant" + is not the best name. */ tree value_range_constant_singleton (const value_range *vr) { - if (vr->type == VR_RANGE - && vrp_operand_equal_p (vr->min, vr->max) - && is_gimple_min_invariant (vr->min)) - return vr->min; - - return NULL_TREE; + return vr->singleton (); } /* Value range wrapper for wide_int_range_set_zero_nonzero_bits. @@ -899,8 +1085,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type, return false; } wide_int_range_set_zero_nonzero_bits (TYPE_SIGN (expr_type), - wi::to_wide (vr->min), - wi::to_wide (vr->max), + wi::to_wide (vr->min ()), + wi::to_wide (vr->max ()), *may_be_nonzero, *must_be_nonzero); return true; } @@ -914,40 +1100,36 @@ static bool ranges_from_anti_range (const value_range *ar, value_range *vr0, value_range *vr1) { - tree type = TREE_TYPE (ar->min); + tree type = ar->type (); - vr0->type = VR_UNDEFINED; - vr1->type = VR_UNDEFINED; + vr0->set_undefined (type); + vr1->set_undefined (type); /* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U [A+1, +INF]. Not sure if this helps in practice, though. */ - if (ar->type != VR_ANTI_RANGE - || TREE_CODE (ar->min) != INTEGER_CST - || TREE_CODE (ar->max) != INTEGER_CST + if (ar->vrtype () != VR_ANTI_RANGE + || TREE_CODE (ar->min ()) != INTEGER_CST + || TREE_CODE (ar->max ()) != INTEGER_CST || !vrp_val_min (type) || !vrp_val_max (type)) return false; - if (!vrp_val_is_min (ar->min)) - { - vr0->type = VR_RANGE; - vr0->min = vrp_val_min (type); - vr0->max = wide_int_to_tree (type, wi::to_wide (ar->min) - 1); - } - if (!vrp_val_is_max (ar->max)) - { - vr1->type = VR_RANGE; - vr1->min = wide_int_to_tree (type, wi::to_wide (ar->max) + 1); - vr1->max = vrp_val_max (type); - } - if (vr0->type == VR_UNDEFINED) + if (!vrp_val_is_min (ar->min ())) + *vr0 = value_range (VR_RANGE, type, + vrp_val_min (type), + wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1)); + if (!vrp_val_is_max (ar->max ())) + *vr1 = value_range (VR_RANGE, type, + wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1), + vrp_val_max (type)); + if (vr0->undefined_p ()) { *vr0 = *vr1; - vr1->type = VR_UNDEFINED; + vr1->set_undefined (type); } - return vr0->type != VR_UNDEFINED; + return !vr0->undefined_p (); } /* Extract the components of a value range into a pair of wide ints in @@ -961,13 +1143,11 @@ extract_range_into_wide_ints (const value_range *vr, signop sign, unsigned prec, wide_int &wmin, wide_int &wmax) { - if ((vr->type == VR_RANGE - || vr->type == VR_ANTI_RANGE) - && TREE_CODE (vr->min) == INTEGER_CST - && TREE_CODE (vr->max) == INTEGER_CST) + gcc_assert (vr->vrtype () != VR_ANTI_RANGE || vr->symbolic_p ()); + if (range_int_cst_p (vr)) { - wmin = wi::to_wide (vr->min); - wmax = wi::to_wide (vr->max); + wmin = wi::to_wide (vr->min ()); + wmax = wi::to_wide (vr->max ()); } else { @@ -994,14 +1174,15 @@ extract_range_from_multiplicative_op (value_range *vr, || code == ROUND_DIV_EXPR || code == RSHIFT_EXPR || code == LSHIFT_EXPR); - gcc_assert (vr0->type == VR_RANGE && vr0->type == vr1->type); + gcc_assert (vr0->vrtype () == VR_RANGE + && vr0->vrtype () == vr1->vrtype ()); - tree type = TREE_TYPE (vr0->min); + tree type = vr0->type (); wide_int res_lb, res_ub; - wide_int vr0_lb = wi::to_wide (vr0->min); - wide_int vr0_ub = wi::to_wide (vr0->max); - wide_int vr1_lb = wi::to_wide (vr1->min); - wide_int vr1_ub = wi::to_wide (vr1->max); + wide_int vr0_lb = wi::to_wide (vr0->min ()); + wide_int vr0_ub = wi::to_wide (vr0->max ()); + wide_int vr1_lb = wi::to_wide (vr1->min ()); + wide_int vr1_ub = wi::to_wide (vr1->max ()); bool overflow_undefined = TYPE_OVERFLOW_UNDEFINED (type); bool overflow_wraps = TYPE_OVERFLOW_WRAPS (type); unsigned prec = TYPE_PRECISION (type); @@ -1010,11 +1191,11 @@ extract_range_from_multiplicative_op (value_range *vr, code, TYPE_SIGN (type), prec, vr0_lb, vr0_ub, vr1_lb, vr1_ub, overflow_undefined, overflow_wraps)) - set_and_canonicalize_value_range (vr, VR_RANGE, - wide_int_to_tree (type, res_lb), - wide_int_to_tree (type, res_ub), NULL); + vr->set_and_canonicalize (VR_RANGE, type, + wide_int_to_tree (type, res_lb), + wide_int_to_tree (type, res_ub), NULL); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); } /* If BOUND will include a symbolic bound, adjust it accordingly, @@ -1114,14 +1295,12 @@ set_value_range_with_overflow (value_range &vr, { const signop sgn = TYPE_SIGN (type); const unsigned int prec = TYPE_PRECISION (type); - vr.type = VR_RANGE; - vr.equiv = NULL; /* For one bit precision if max < min, then the swapped range covers all values. */ if (prec == 1 && wi::lt_p (wmax, wmin, sgn)) { - set_value_range_to_varying (&vr); + set_value_range_to_varying (&vr, type); return; } @@ -1133,10 +1312,18 @@ set_value_range_with_overflow (value_range &vr, wide_int tmax = wide_int::from (wmax, prec, sgn); if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE)) { - /* No overflow or both overflow or underflow. The - range kind stays VR_RANGE. */ - vr.min = wide_int_to_tree (type, tmin); - vr.max = wide_int_to_tree (type, tmax); + /* 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. */ + if (wi::gt_p (tmin, tmax, sgn)) + vr.set_varying (type); + else + /* No overflow or both overflow or underflow. The + range kind stays VR_RANGE. */ + vr = value_range (VR_RANGE, type, + wide_int_to_tree (type, tmin), + wide_int_to_tree (type, tmax)); + return; } else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE) || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE)) @@ -1145,7 +1332,6 @@ set_value_range_with_overflow (value_range &vr, changes to VR_ANTI_RANGE. */ bool covers = false; wide_int tem = tmin; - vr.type = VR_ANTI_RANGE; tmin = tmax + 1; if (wi::cmp (tmin, tmax, sgn) < 0) covers = true; @@ -1157,16 +1343,18 @@ set_value_range_with_overflow (value_range &vr, types values. */ if (covers || wi::cmp (tmin, tmax, sgn) > 0) { - set_value_range_to_varying (&vr); + set_value_range_to_varying (&vr, type); return; } - vr.min = wide_int_to_tree (type, tmin); - vr.max = wide_int_to_tree (type, tmax); + vr = value_range (VR_ANTI_RANGE, type, + wide_int_to_tree (type, tmin), + wide_int_to_tree (type, tmax)); + return; } else { /* Other underflow and/or overflow, drop to VR_VARYING. */ - set_value_range_to_varying (&vr); + set_value_range_to_varying (&vr, type); return; } } @@ -1176,19 +1364,21 @@ set_value_range_with_overflow (value_range &vr, value. */ wide_int type_min = wi::min_value (prec, sgn); wide_int type_max = wi::max_value (prec, sgn); + tree min, max; if (min_ovf == wi::OVF_UNDERFLOW) - vr.min = wide_int_to_tree (type, type_min); + min = wide_int_to_tree (type, type_min); else if (min_ovf == wi::OVF_OVERFLOW) - vr.min = wide_int_to_tree (type, type_max); + min = wide_int_to_tree (type, type_max); else - vr.min = wide_int_to_tree (type, wmin); + min = wide_int_to_tree (type, wmin); if (max_ovf == wi::OVF_UNDERFLOW) - vr.max = wide_int_to_tree (type, type_min); + max = wide_int_to_tree (type, type_min); else if (max_ovf == wi::OVF_OVERFLOW) - vr.max = wide_int_to_tree (type, type_max); + max = wide_int_to_tree (type, type_max); else - vr.max = wide_int_to_tree (type, wmax); + max = wide_int_to_tree (type, wmax); + vr = value_range (VR_RANGE, type, min, max); } } @@ -1205,7 +1395,7 @@ extract_range_from_binary_expr_1 (value_range *vr, signop sign = TYPE_SIGN (expr_type); unsigned int prec = TYPE_PRECISION (expr_type); value_range vr0 = *vr0_, vr1 = *vr1_; - value_range vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER; + value_range vrtem0 (expr_type), vrtem1 (expr_type); enum value_range_type type; tree min = NULL_TREE, max = NULL_TREE; int cmp; @@ -1213,7 +1403,7 @@ extract_range_from_binary_expr_1 (value_range *vr, if (!INTEGRAL_TYPE_P (expr_type) && !POINTER_TYPE_P (expr_type)) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } @@ -1237,33 +1427,30 @@ extract_range_from_binary_expr_1 (value_range *vr, && code != BIT_IOR_EXPR && code != BIT_XOR_EXPR) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } /* If both ranges are UNDEFINED, so is the result. */ - if (vr0.type == VR_UNDEFINED && vr1.type == VR_UNDEFINED) + if (vr0.undefined_p () && vr1.undefined_p ()) { - set_value_range_to_undefined (vr); + set_value_range_to_undefined (vr, expr_type); return; } /* If one of the ranges is UNDEFINED drop it to VARYING for the following code. At some point we may want to special-case operations that have UNDEFINED result for all or some value-ranges of the not UNDEFINED operand. */ - else if (vr0.type == VR_UNDEFINED) - set_value_range_to_varying (&vr0); - else if (vr1.type == VR_UNDEFINED) - set_value_range_to_varying (&vr1); + else if (vr0.undefined_p ()) + set_value_range_to_varying (&vr0, vr0.type ()); + else if (vr1.undefined_p ()) + set_value_range_to_varying (&vr1, vr1.type ()); /* We get imprecise results from ranges_from_anti_range when code is EXACT_DIV_EXPR. We could mask out bits in the resulting - range, but then we also need to hack up vrp_meet. It's just + range, but then we also need to hack up vrp_union. It's just easier to special case when vr0 is ~[0,0] for EXACT_DIV_EXPR. */ - if (code == EXACT_DIV_EXPR - && vr0.type == VR_ANTI_RANGE - && vr0.min == vr0.max - && integer_zerop (vr0.min)) + if (code == EXACT_DIV_EXPR && range_is_nonnull (&vr0)) { set_value_range_to_nonnull (vr, expr_type); return; @@ -1271,36 +1458,35 @@ extract_range_from_binary_expr_1 (value_range *vr, /* Now canonicalize anti-ranges to ranges when they are not symbolic and express ~[] op X as ([]' op X) U ([]'' op X). */ - if (vr0.type == VR_ANTI_RANGE + if (vr0.vrtype () == VR_ANTI_RANGE && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1)) { extract_range_from_binary_expr_1 (vr, code, expr_type, &vrtem0, vr1_); - if (vrtem1.type != VR_UNDEFINED) + if (!vrtem1.undefined_p ()) { - value_range vrres = VR_INITIALIZER; - extract_range_from_binary_expr_1 (&vrres, code, expr_type, - &vrtem1, vr1_); - vrp_meet (vr, &vrres); + value_range vrres (expr_type); + extract_range_from_binary_expr_1 (&vrres, code, expr_type, &vrtem1, vr1_); + vr->union_ (&vrres); } return; } /* Likewise for X op ~[]. */ - if (vr1.type == VR_ANTI_RANGE + if (vr1.vrtype () == VR_ANTI_RANGE && ranges_from_anti_range (&vr1, &vrtem0, &vrtem1)) { extract_range_from_binary_expr_1 (vr, code, expr_type, vr0_, &vrtem0); - if (vrtem1.type != VR_UNDEFINED) + if (!vrtem1.undefined_p ()) { - value_range vrres = VR_INITIALIZER; + value_range vrres (expr_type); extract_range_from_binary_expr_1 (&vrres, code, expr_type, vr0_, &vrtem1); - vrp_meet (vr, &vrres); + vr->union_ (&vrres); } return; } /* The type of the resulting value range defaults to VR0.TYPE. */ - type = vr0.type; + type = vr0.vrtype (); /* Refuse to operate on VARYING ranges, ranges of different kinds and symbolic ranges. As an exception, we allow BIT_{AND,IOR} @@ -1323,13 +1509,13 @@ extract_range_from_binary_expr_1 (value_range *vr, && code != MINUS_EXPR && code != RSHIFT_EXPR && code != POINTER_PLUS_EXPR - && (vr0.type == VR_VARYING - || vr1.type == VR_VARYING - || vr0.type != vr1.type - || symbolic_range_p (&vr0) - || symbolic_range_p (&vr1))) + && (vr0.varying_p () + || vr1.varying_p () + || vr0.vrtype () != vr1.vrtype () + || vr0.symbolic_p () + || vr1.symbolic_p ())) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } @@ -1347,7 +1533,7 @@ extract_range_from_binary_expr_1 (value_range *vr, else if (range_is_null (&vr0) && range_is_null (&vr1)) set_value_range_to_null (vr, expr_type); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); } else if (code == POINTER_PLUS_EXPR) { @@ -1359,7 +1545,7 @@ extract_range_from_binary_expr_1 (value_range *vr, else if (range_is_null (&vr0) && range_is_null (&vr1)) set_value_range_to_null (vr, expr_type); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); } else if (code == BIT_AND_EXPR) { @@ -1370,10 +1556,10 @@ extract_range_from_binary_expr_1 (value_range *vr, else if (range_is_null (&vr0) || range_is_null (&vr1)) set_value_range_to_null (vr, expr_type); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); } else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } @@ -1385,24 +1571,20 @@ extract_range_from_binary_expr_1 (value_range *vr, /* This will normalize things such that calculating [0,0] - VR_VARYING is not dropped to varying, but is calculated as [MIN+1, MAX]. */ - if (vr0.type == VR_VARYING) - { - vr0.type = VR_RANGE; - vr0.min = vrp_val_min (expr_type); - vr0.max = vrp_val_max (expr_type); - } - if (vr1.type == VR_VARYING) - { - vr1.type = VR_RANGE; - vr1.min = vrp_val_min (expr_type); - vr1.max = vrp_val_max (expr_type); - } + if (vr0.varying_p ()) + vr0 = value_range (VR_RANGE, vr0.type (), + vrp_val_min (expr_type), + vrp_val_max (expr_type), vr0.equiv ()); + if (vr1.varying_p ()) + vr1 = value_range (VR_RANGE, vr1.type (), + vrp_val_min (expr_type), + vrp_val_max (expr_type), vr0.equiv ()); const bool minus_p = (code == MINUS_EXPR); - tree min_op0 = vr0.min; - tree min_op1 = minus_p ? vr1.max : vr1.min; - tree max_op0 = vr0.max; - tree max_op1 = minus_p ? vr1.min : vr1.max; + tree min_op0 = vr0.min (); + tree min_op1 = minus_p ? vr1.max () : vr1.min (); + tree max_op0 = vr0.max (); + tree max_op1 = minus_p ? vr1.min () : vr1.max (); tree sym_min_op0 = NULL_TREE; tree sym_min_op1 = NULL_TREE; tree sym_max_op0 = NULL_TREE; @@ -1415,7 +1597,7 @@ extract_range_from_binary_expr_1 (value_range *vr, single-symbolic ranges, try to compute the precise resulting range, but only if we know that this resulting range will also be constant or single-symbolic. */ - if (vr0.type == VR_RANGE && vr1.type == VR_RANGE + if (vr0.vrtype () == VR_RANGE && vr1.vrtype () == VR_RANGE && (TREE_CODE (min_op0) == INTEGER_CST || (sym_min_op0 = get_single_symbol (min_op0, &neg_min_op0, &min_op0))) @@ -1448,28 +1630,26 @@ extract_range_from_binary_expr_1 (value_range *vr, if (((bool)min_ovf && sym_min_op0 != sym_min_op1) || ((bool)max_ovf && sym_max_op0 != sym_max_op1)) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } /* Adjust the range for possible overflow. */ set_value_range_with_overflow (*vr, expr_type, wmin, wmax, min_ovf, max_ovf); - if (vr->type == VR_VARYING) + if (vr->varying_p ()) return; /* Build the symbolic bounds if needed. */ - adjust_symbolic_bound (vr->min, code, expr_type, + min = vr->min (); + max = vr->max (); + adjust_symbolic_bound (min, code, expr_type, sym_min_op0, sym_min_op1, neg_min_op0, neg_min_op1); - adjust_symbolic_bound (vr->max, code, expr_type, + adjust_symbolic_bound (max, code, expr_type, sym_max_op0, sym_max_op1, neg_max_op0, neg_max_op1); - /* ?? It would probably be cleaner to eliminate min/max/type - entirely and hold these values in VR directly. */ - min = vr->min; - max = vr->max; - type = vr->type; + type = vr->vrtype (); } else { @@ -1485,7 +1665,7 @@ extract_range_from_binary_expr_1 (value_range *vr, a single range or anti-range as the above is [-INF+1, +INF(OVF)] intersected with ~[5, 5] but one could use a scheme similar to equivalences for this. */ - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } } @@ -1503,7 +1683,7 @@ extract_range_from_binary_expr_1 (value_range *vr, wide_int_to_tree (expr_type, wmin), wide_int_to_tree (expr_type, wmax), NULL); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } else if (code == MULT_EXPR) @@ -1511,7 +1691,7 @@ extract_range_from_binary_expr_1 (value_range *vr, if (!range_int_cst_p (&vr0) || !range_int_cst_p (&vr1)) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } extract_range_from_multiplicative_op (vr, code, &vr0, &vr1); @@ -1522,19 +1702,21 @@ extract_range_from_binary_expr_1 (value_range *vr, { if (range_int_cst_p (&vr1) && !wide_int_range_shift_undefined_p (prec, - wi::to_wide (vr1.min), - wi::to_wide (vr1.max))) + wi::to_wide (vr1.min ()), + wi::to_wide (vr1.max ()))) { if (code == RSHIFT_EXPR) { /* Even if vr0 is VARYING or otherwise not usable, we can derive useful ranges just from the shift count. E.g. x >> 63 for signed 64-bit x is always [-1, 0]. */ - if (vr0.type != VR_RANGE || symbolic_range_p (&vr0)) + if (vr0.vrtype () != VR_RANGE || vr0.symbolic_p ()) { - vr0.type = type = VR_RANGE; - vr0.min = vrp_val_min (expr_type); - vr0.max = vrp_val_max (expr_type); + type = VR_RANGE; + vr0 = value_range (type, vr0.type (), + vrp_val_min (expr_type), + vrp_val_max (expr_type), + vr0.equiv ()); } extract_range_from_multiplicative_op (vr, code, &vr0, &vr1); return; @@ -1544,22 +1726,22 @@ extract_range_from_binary_expr_1 (value_range *vr, { wide_int res_lb, res_ub; if (wide_int_range_lshift (res_lb, res_ub, sign, prec, - wi::to_wide (vr0.min), - wi::to_wide (vr0.max), - wi::to_wide (vr1.min), - wi::to_wide (vr1.max), + wi::to_wide (vr0.min ()), + wi::to_wide (vr0.max ()), + wi::to_wide (vr1.min ()), + wi::to_wide (vr1.max ()), TYPE_OVERFLOW_UNDEFINED (expr_type), TYPE_OVERFLOW_WRAPS (expr_type))) { min = wide_int_to_tree (expr_type, res_lb); max = wide_int_to_tree (expr_type, res_ub); - set_and_canonicalize_value_range (vr, VR_RANGE, - min, max, NULL); + vr->set_and_canonicalize (VR_RANGE, expr_type, min, max, + NULL); return; } } } - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } else if (code == TRUNC_DIV_EXPR @@ -1575,7 +1757,7 @@ extract_range_from_binary_expr_1 (value_range *vr, /* Special case explicit division by zero as undefined. */ if (range_is_null (&vr1)) { - set_value_range_to_undefined (vr); + set_value_range_to_undefined (vr, expr_type); return; } @@ -1597,7 +1779,7 @@ extract_range_from_binary_expr_1 (value_range *vr, TYPE_OVERFLOW_WRAPS (expr_type), extra_range_p, extra_min, extra_max)) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } set_value_range (vr, VR_RANGE, @@ -1605,11 +1787,11 @@ extract_range_from_binary_expr_1 (value_range *vr, wide_int_to_tree (expr_type, wmax), NULL); if (extra_range_p) { - value_range extra_range = VR_INITIALIZER; + value_range extra_range (expr_type); set_value_range (&extra_range, VR_RANGE, wide_int_to_tree (expr_type, extra_min), wide_int_to_tree (expr_type, extra_max), NULL); - vrp_meet (vr, &extra_range); + vr->union_ (&extra_range); } return; } @@ -1617,7 +1799,7 @@ extract_range_from_binary_expr_1 (value_range *vr, { if (range_is_null (&vr1)) { - set_value_range_to_undefined (vr); + set_value_range_to_undefined (vr, expr_type); return; } wide_int wmin, wmax, tmp; @@ -1658,7 +1840,7 @@ extract_range_from_binary_expr_1 (value_range *vr, set_value_range (vr, VR_RANGE, min, max, NULL); } else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } else if (code == BIT_IOR_EXPR) @@ -1676,7 +1858,7 @@ extract_range_from_binary_expr_1 (value_range *vr, set_value_range (vr, VR_RANGE, min, max, NULL); } else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } else if (code == BIT_XOR_EXPR) @@ -1692,7 +1874,7 @@ extract_range_from_binary_expr_1 (value_range *vr, set_value_range (vr, VR_RANGE, min, max, NULL); } else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } } @@ -1706,7 +1888,7 @@ extract_range_from_binary_expr_1 (value_range *vr, || max == NULL_TREE || TREE_OVERFLOW_P (max)) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } @@ -1715,7 +1897,7 @@ extract_range_from_binary_expr_1 (value_range *vr, Note that we do accept [-INF, -INF] and [+INF, +INF]. */ if (vrp_val_is_min (min) && vrp_val_is_max (max)) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); return; } @@ -1725,7 +1907,7 @@ extract_range_from_binary_expr_1 (value_range *vr, /* If the new range has its limits swapped around (MIN > MAX), then the operation caused one of them to wrap around, mark the new range VARYING. */ - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, expr_type); } else set_value_range (vr, type, min, max, NULL); @@ -1742,7 +1924,9 @@ extract_range_from_unary_expr (value_range *vr, { signop sign = TYPE_SIGN (type); unsigned int prec = TYPE_PRECISION (type); - value_range vr0 = *vr0_, vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER; + value_range vr0 = *vr0_; + value_range vrtem0 (vr0.type ()); + value_range vrtem1 (vr0.type ()); /* VRP only operates on integral and pointer types. */ if (!(INTEGRAL_TYPE_P (op0_type) @@ -1750,14 +1934,14 @@ extract_range_from_unary_expr (value_range *vr, || !(INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))) { - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); return; } /* If VR0 is UNDEFINED, so is the result. */ - if (vr0.type == VR_UNDEFINED) + if (vr0.undefined_p ()) { - set_value_range_to_undefined (vr); + set_value_range_to_undefined (vr, type); return; } @@ -1772,7 +1956,7 @@ extract_range_from_unary_expr (value_range *vr, { /* -X is simply 0 - X, so re-use existing code that also handles anti-ranges fine. */ - value_range zero = VR_INITIALIZER; + value_range zero (type); set_value_range_to_value (&zero, build_int_cst (type, 0), NULL); extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0); return; @@ -1781,7 +1965,7 @@ extract_range_from_unary_expr (value_range *vr, { /* ~X is simply -1 - X, so re-use existing code that also handles anti-ranges fine. */ - value_range minusone = VR_INITIALIZER; + value_range minusone (type); set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL); extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &minusone, &vr0); @@ -1790,16 +1974,16 @@ extract_range_from_unary_expr (value_range *vr, /* Now canonicalize anti-ranges to ranges when they are not symbolic and express op ~[] as (op []') U (op []''). */ - if (vr0.type == VR_ANTI_RANGE + if (vr0.vrtype () == VR_ANTI_RANGE && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1)) { extract_range_from_unary_expr (vr, code, type, &vrtem0, op0_type); - if (vrtem1.type != VR_UNDEFINED) + if (!vrtem1.undefined_p ()) { - value_range vrres = VR_INITIALIZER; + value_range vrres (type); extract_range_from_unary_expr (&vrres, code, type, &vrtem1, op0_type); - vrp_meet (vr, &vrres); + vr->union_ (&vrres); } return; } @@ -1823,7 +2007,7 @@ extract_range_from_unary_expr (value_range *vr, else if (range_is_null (&vr0)) set_value_range_to_null (vr, type); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); return; } @@ -1831,8 +2015,8 @@ extract_range_from_unary_expr (value_range *vr, pointer anti-ranges. Any remaining anti-ranges at this point will be integer conversions from SSA names that will be normalized into VARYING. For instance: ~[x_55, x_55]. */ - gcc_assert (vr0.type != VR_ANTI_RANGE - || TREE_CODE (vr0.min) != INTEGER_CST); + gcc_assert (vr0.vrtype () != VR_ANTI_RANGE + || TREE_CODE (vr0.min ()) != INTEGER_CST); /* NOTES: Previously we were returning VARYING for all symbolics, but we can do better by treating them as [-MIN, +MAX]. For @@ -1855,10 +2039,10 @@ 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); - set_and_canonicalize_value_range (vr, VR_RANGE, min, max, NULL); + vr->set_and_canonicalize (VR_RANGE, outer_type, min, max, NULL); } else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, outer_type); return; } else if (code == ABS_EXPR) @@ -1872,12 +2056,12 @@ extract_range_from_unary_expr (value_range *vr, wide_int_to_tree (type, wmin), wide_int_to_tree (type, wmax), NULL); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); return; } /* For unhandled operations fall back to varying. */ - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); return; } @@ -1897,39 +2081,39 @@ dump_value_range (FILE *file, const value_range *vr) { if (vr == NULL) fprintf (file, "[]"); - else if (vr->type == VR_UNDEFINED) + else if (vr->undefined_p ()) fprintf (file, "UNDEFINED"); - else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) + else if (vr->vrtype () == VR_RANGE || vr->vrtype () == VR_ANTI_RANGE) { - tree type = TREE_TYPE (vr->min); + tree type = TREE_TYPE (vr->min ()); - fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : ""); + fprintf (file, "%s[", (vr->vrtype () == VR_ANTI_RANGE) ? "~" : ""); if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) - && vrp_val_is_min (vr->min)) + && vrp_val_is_min (vr->min ())) fprintf (file, "-INF"); else - print_generic_expr (file, vr->min); + print_generic_expr (file, vr->min ()); fprintf (file, ", "); if (INTEGRAL_TYPE_P (type) - && vrp_val_is_max (vr->max)) + && vrp_val_is_max (vr->max ())) fprintf (file, "+INF"); else - print_generic_expr (file, vr->max); + print_generic_expr (file, vr->max ()); fprintf (file, "]"); - if (vr->equiv) + if (vr->equiv ()) { bitmap_iterator bi; unsigned i, c = 0; fprintf (file, " EQUIVALENCES: { "); - EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi) + EXECUTE_IF_SET_IN_BITMAP (vr->equiv (), 0, i, bi) { print_generic_expr (file, ssa_name (i)); fprintf (file, " "); @@ -1939,7 +2123,7 @@ dump_value_range (FILE *file, const value_range *vr) fprintf (file, "} (%u elements)", c); } } - else if (vr->type == VR_VARYING) + else if (vr->varying_p ()) fprintf (file, "VARYING"); else fprintf (file, "INVALID RANGE"); @@ -1951,14 +2135,7 @@ dump_value_range (FILE *file, const value_range *vr) DEBUG_FUNCTION void debug_value_range (const value_range *vr) { - dump_value_range (stderr, vr); - fprintf (stderr, "\n"); -} - -void -value_range::dump () const -{ - debug_value_range (this); + vr->dump (); } @@ -4202,14 +4379,14 @@ vrp_prop::check_array_ref (location_t location, tree ref, if (TREE_CODE (low_sub) == SSA_NAME) { vr = get_value_range (low_sub); - if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) + if (!vr->undefined_p () && !vr->varying_p ()) { - low_sub = vr->type == VR_RANGE ? vr->max : vr->min; - up_sub = vr->type == VR_RANGE ? vr->min : vr->max; + low_sub = vr->vrtype () == VR_RANGE ? vr->max () : vr->min (); + up_sub = vr->vrtype () == VR_RANGE ? vr->min () : vr->max (); } } - if (vr && vr->type == VR_ANTI_RANGE) + if (vr && vr->vrtype () == VR_ANTI_RANGE) { if (up_bound && TREE_CODE (up_sub) == INTEGER_CST @@ -4337,21 +4514,20 @@ vrp_prop::check_mem_ref (location_t location, tree ref, break; vr = get_value_range (varoff); - if (!vr || vr->type == VR_UNDEFINED || !vr->min || !vr->max) + if (!vr || vr->undefined_p () || vr->varying_p ()) break; - if (TREE_CODE (vr->min) != INTEGER_CST - || TREE_CODE (vr->max) != INTEGER_CST) + if (!vr->numeric_p ()) break; - if (vr->type == VR_RANGE) + if (vr->vrtype () == VR_RANGE) { - if (tree_int_cst_lt (vr->min, vr->max)) + if (tree_int_cst_lt (vr->min (), vr->max ())) { offset_int min - = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min)); + = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ())); offset_int max - = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max)); + = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ())); if (min < max) { offrange[0] += min; @@ -4969,7 +5145,8 @@ vrp_prop::vrp_initialize () if (!stmt_interesting_for_vrp (phi)) { tree lhs = PHI_RESULT (phi); - set_value_range_to_varying (get_value_range (lhs)); + set_value_range_to_varying (get_value_range (lhs), + TREE_TYPE (lhs)); prop_set_simulate_again (phi, false); } else @@ -5123,8 +5300,8 @@ find_case_label_range (gswitch *stmt, tree min, tree max, size_t *min_idx, enum ssa_prop_result vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p) { - value_range vr = VR_INITIALIZER; tree lhs = gimple_get_lhs (stmt); + value_range vr (lhs ? TREE_TYPE (lhs) : NULL); extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr); if (*output_p) @@ -5140,7 +5317,7 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p) fprintf (dump_file, "\n"); } - if (vr.type == VR_VARYING) + if (vr.varying_p ()) return SSA_PROP_VARYING; return SSA_PROP_INTERESTING; @@ -5164,7 +5341,8 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p) use_operand_p use_p; enum ssa_prop_result res = SSA_PROP_VARYING; - set_value_range_to_varying (get_value_range (lhs)); + set_value_range_to_varying (get_value_range (lhs), + TREE_TYPE (lhs)); FOR_EACH_IMM_USE_FAST (use_p, iter, lhs) { @@ -5193,17 +5371,14 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p) SSA_PROP_NOT_INTERESTING. If there are no {REAL,IMAG}PART_EXPR uses at all, return SSA_PROP_VARYING. */ - value_range new_vr = VR_INITIALIZER; + value_range new_vr (TREE_TYPE (lhs)); extract_range_basic (&new_vr, use_stmt); const value_range *old_vr = get_value_range (use_lhs); - if (old_vr->type != new_vr.type - || !vrp_operand_equal_p (old_vr->min, new_vr.min) - || !vrp_operand_equal_p (old_vr->max, new_vr.max) - || !vrp_bitmap_equal_p (old_vr->equiv, new_vr.equiv)) + if (*old_vr != new_vr) res = SSA_PROP_INTERESTING; else res = SSA_PROP_NOT_INTERESTING; - BITMAP_FREE (new_vr.equiv); + new_vr.equiv_free (); if (res == SSA_PROP_INTERESTING) { *output_p = lhs; @@ -5814,8 +5989,6 @@ intersect_ranges (enum value_range_type *vr0type, *vr0min = vr1min; *vr0max = vr1max; } - - return; } @@ -5823,14 +5996,12 @@ intersect_ranges (enum value_range_type *vr0type, in *VR0. This may not be the smallest possible such range. */ static void -vrp_intersect_ranges_1 (value_range *vr0, const value_range *vr1) +vrp_intersect_1 (value_range *vr0, const value_range *vr1) { - value_range saved; - /* If either range is VR_VARYING the other one wins. */ - if (vr1->type == VR_VARYING) + if (vr1->varying_p ()) return; - if (vr0->type == VR_VARYING) + if (vr0->varying_p ()) { copy_value_range (vr0, vr1); return; @@ -5838,49 +6009,53 @@ vrp_intersect_ranges_1 (value_range *vr0, const value_range *vr1) /* When either range is VR_UNDEFINED the resulting range is VR_UNDEFINED, too. */ - if (vr0->type == VR_UNDEFINED) + if (vr0->undefined_p ()) return; - if (vr1->type == VR_UNDEFINED) + if (vr1->undefined_p ()) { - set_value_range_to_undefined (vr0); + set_value_range_to_undefined (vr0, vr0->type ()); return; } /* Save the original vr0 so we can return it as conservative intersection result when our worker turns things to varying. */ - saved = *vr0; - intersect_ranges (&vr0->type, &vr0->min, &vr0->max, - vr1->type, vr1->min, vr1->max); + value_range saved (*vr0); + + value_range_type vr0type = vr0->vrtype (); + tree vr0min = vr0->min (); + tree vr0max = vr0->max (); + intersect_ranges (&vr0type, &vr0min, &vr0max, + vr1->vrtype (), vr1->min (), vr1->max ()); /* Make sure to canonicalize the result though as the inversion of a VR_RANGE can still be a VR_RANGE. */ - set_and_canonicalize_value_range (vr0, vr0->type, - vr0->min, vr0->max, vr0->equiv); + vr0->set_and_canonicalize (vr0type, vr0->type (), vr0min, vr0max, + vr0->equiv ()); /* If that failed, use the saved original VR0. */ - if (vr0->type == VR_VARYING) + if (vr0->varying_p ()) { *vr0 = saved; return; } /* If the result is VR_UNDEFINED there is no need to mess with the equivalencies. */ - if (vr0->type == VR_UNDEFINED) + if (vr0->undefined_p ()) return; /* The resulting set of equivalences for range intersection is the union of the two sets. */ - if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv) - bitmap_ior_into (vr0->equiv, vr1->equiv); - else if (vr1->equiv && !vr0->equiv) + if (vr0->equiv () && vr1->equiv () && vr0->equiv () != vr1->equiv ()) + vr0->equiv_ior (vr1); + else if (vr1->equiv () && !vr0->equiv ()) { /* All equivalence bitmaps are allocated from the same obstack. So we can use the obstack associated with VR to allocate vr0->equiv. */ - vr0->equiv = BITMAP_ALLOC (vr1->equiv->obstack); - bitmap_copy (vr0->equiv, vr1->equiv); + vr0->set_equiv (BITMAP_ALLOC (vr1->equiv ()->obstack)); + vr0->equiv_copy (vr1); } } -void -vrp_intersect_ranges (value_range *vr0, const value_range *vr1) +static void +vrp_intersect (value_range *vr0, const value_range *vr1) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -5890,7 +6065,7 @@ vrp_intersect_ranges (value_range *vr0, const value_range *vr1) dump_value_range (dump_file, vr1); fprintf (dump_file, "\n"); } - vrp_intersect_ranges_1 (vr0, vr1); + vrp_intersect_1 (vr0, vr1); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "to\n "); @@ -5904,38 +6079,40 @@ vrp_intersect_ranges (value_range *vr0, const value_range *vr1) may not be the smallest possible such range. */ static void -vrp_meet_1 (value_range *vr0, const value_range *vr1) +vrp_union_1 (value_range *vr0, const value_range *vr1) { - value_range saved; - - if (vr0->type == VR_UNDEFINED) + if (vr0->undefined_p ()) { - set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr1->equiv); + vr0->copy_with_equiv_update (vr1); return; } - if (vr1->type == VR_UNDEFINED) + if (vr1->undefined_p ()) { /* VR0 already has the resulting range. */ return; } - if (vr0->type == VR_VARYING) + if (vr0->varying_p ()) { /* Nothing to do. VR0 already has the resulting range. */ return; } - if (vr1->type == VR_VARYING) + if (vr1->varying_p ()) { - set_value_range_to_varying (vr0); + set_value_range_to_varying (vr0, vr0->type ()); return; } - saved = *vr0; - union_ranges (&vr0->type, &vr0->min, &vr0->max, - vr1->type, vr1->min, vr1->max); - if (vr0->type == VR_VARYING) + value_range saved (*vr0); + value_range_type vr0type = vr0->vrtype (); + tree vr0min = vr0->min (); + tree vr0max = vr0->max (); + union_ranges (&vr0type, &vr0min, &vr0max, + vr1->vrtype (), vr1->min (), vr1->max ()); + *vr0 = value_range (vr0type, vr0->type (), vr0min, vr0max); + if (vr0->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 @@ -5943,33 +6120,32 @@ vrp_meet_1 (value_range *vr0, const value_range *vr1) if (range_includes_zero_p (&saved) == 0 && range_includes_zero_p (vr1) == 0) { - set_value_range_to_nonnull (vr0, TREE_TYPE (saved.min)); + 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->equiv) - bitmap_clear (vr0->equiv); + vr0->equiv_clear (); return; } - set_value_range_to_varying (vr0); + set_value_range_to_varying (vr0, vr0->type ()); return; } - set_and_canonicalize_value_range (vr0, vr0->type, vr0->min, vr0->max, - vr0->equiv); - if (vr0->type == VR_VARYING) + vr0->set_and_canonicalize (vr0->vrtype (), vr0->type (), + vr0->min (), vr0->max (), vr0->equiv ()); + if (vr0->varying_p ()) return; /* The resulting set of equivalences is always the intersection of the two sets. */ - if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv) - bitmap_and_into (vr0->equiv, vr1->equiv); - else if (vr0->equiv && !vr1->equiv) - bitmap_clear (vr0->equiv); + if (vr0->equiv () != vr1->equiv ()) + vr0->equiv_and (vr1); + else if (!vr1->equiv ()) + vr0->equiv_clear (); } -void -vrp_meet (value_range *vr0, const value_range *vr1) +static void +vrp_union (value_range *vr0, const value_range *vr1) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -5979,7 +6155,7 @@ vrp_meet (value_range *vr0, const value_range *vr1) dump_value_range (dump_file, vr1); fprintf (dump_file, "\n"); } - vrp_meet_1 (vr0, vr1); + vrp_union_1 (vr0, vr1); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "to\n "); @@ -5988,7 +6164,6 @@ vrp_meet (value_range *vr0, const value_range *vr1) } } - /* Visit all arguments for PHI node PHI that flow through executable edges. If a valid value range can be derived from all the incoming value ranges, set a new range for the LHS of PHI. */ @@ -5997,7 +6172,7 @@ enum ssa_prop_result vrp_prop::visit_phi (gphi *phi) { tree lhs = PHI_RESULT (phi); - value_range vr_result = VR_INITIALIZER; + value_range vr_result (TREE_TYPE (lhs)); extract_range_from_phi_node (phi, &vr_result); if (update_value_range (lhs, &vr_result)) { @@ -6010,7 +6185,7 @@ vrp_prop::visit_phi (gphi *phi) fprintf (dump_file, "\n"); } - if (vr_result.type == VR_VARYING) + if (vr_result.varying_p ()) return SSA_PROP_VARYING; return SSA_PROP_INTERESTING; @@ -6194,16 +6369,17 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt, op = lhs_of_dominating_assert (op, bb, stmt); const value_range *vr = vr_values->get_value_range (op); - if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE) - || symbolic_range_p (vr)) + if (vr->undefined_p () + || vr->varying_p () + || vr->symbolic_p ()) return NULL_TREE; - if (vr->type == VR_RANGE) + if (vr->vrtype () == VR_RANGE) { size_t i, j; /* Get the range of labels that contain a part of the operand's value range. */ - find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j); + find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j); /* Is there only one such label? */ if (i == j) @@ -6213,10 +6389,11 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt, /* The i'th label will be taken only if the value range of the operand is entirely within the bounds of this label. */ if (CASE_HIGH (label) != NULL_TREE - ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0 - && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0) - : (tree_int_cst_equal (CASE_LOW (label), vr->min) - && tree_int_cst_equal (vr->min, vr->max))) + ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0 + && tree_int_cst_compare (CASE_HIGH (label), + vr->max ()) >= 0) + : (tree_int_cst_equal (CASE_LOW (label), vr->min ()) + && tree_int_cst_equal (vr->min (), vr->max ()))) return label; } @@ -6226,7 +6403,7 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt, return gimple_switch_label (switch_stmt, 0); } - if (vr->type == VR_ANTI_RANGE) + if (vr->vrtype () == VR_ANTI_RANGE) { unsigned n = gimple_switch_num_labels (switch_stmt); tree min_label = gimple_switch_label (switch_stmt, 1); @@ -6235,10 +6412,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt, /* The default label will be taken only if the anti-range of the operand is entirely outside the bounds of all the (non-default) case labels. */ - if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0 + if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0 && (CASE_HIGH (max_label) != NULL_TREE - ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0 - : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0)) + ? tree_int_cst_compare (vr->max (), + CASE_HIGH (max_label)) >= 0 + : tree_int_cst_compare (vr->max (), + CASE_LOW (max_label)) >= 0)) return gimple_switch_label (switch_stmt, 0); } @@ -6255,11 +6434,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt, { edge dummy_e; tree dummy_tree; - value_range new_vr = VR_INITIALIZER; + value_range new_vr (TREE_TYPE (lhs)); vr_values->extract_range_from_stmt (stmt, &dummy_e, &dummy_tree, &new_vr); - if (range_int_cst_singleton_p (&new_vr)) - return new_vr.min; + tree singleton = new_vr.singleton (); + if (singleton) + return singleton; } } @@ -6431,20 +6611,16 @@ vrp_prop::vrp_finalize (bool warn_array_bounds_p) continue; const value_range *vr = get_value_range (name); - if (!name - || (vr->type == VR_VARYING) - || (vr->type == VR_UNDEFINED) - || (TREE_CODE (vr->min) != INTEGER_CST) - || (TREE_CODE (vr->max) != INTEGER_CST)) + if (!name || !vr->numeric_p ()) continue; if (POINTER_TYPE_P (TREE_TYPE (name)) && range_includes_zero_p (vr) == 0) set_ptr_nonnull (name); else if (!POINTER_TYPE_P (TREE_TYPE (name))) - set_range_info (name, vr->type, - wi::to_wide (vr->min), - wi::to_wide (vr->max)); + set_range_info (name, vr->vrtype (), + wi::to_wide (vr->min ()), + wi::to_wide (vr->max ())); } /* If we're checking array refs, we want to merge information on @@ -6636,7 +6812,8 @@ determine_value_range_1 (value_range *vr, tree expr) { if (BINARY_CLASS_P (expr)) { - value_range vr0 = VR_INITIALIZER, vr1 = VR_INITIALIZER; + value_range vr0 (TREE_TYPE (TREE_OPERAND (expr, 0))); + value_range vr1 (TREE_TYPE (TREE_OPERAND (expr, 1))); 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), @@ -6644,7 +6821,7 @@ determine_value_range_1 (value_range *vr, tree expr) } else if (UNARY_CLASS_P (expr)) { - value_range vr0 = VR_INITIALIZER; + value_range vr0 (TREE_TYPE (TREE_OPERAND (expr, 0))); determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr), &vr0, TREE_TYPE (TREE_OPERAND (expr, 0))); @@ -6663,7 +6840,7 @@ determine_value_range_1 (value_range *vr, tree expr) set_value_range (vr, kind, wide_int_to_tree (TREE_TYPE (expr), min), wide_int_to_tree (TREE_TYPE (expr), max), NULL); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, TREE_TYPE (expr)); } } @@ -6673,15 +6850,13 @@ determine_value_range_1 (value_range *vr, tree expr) value_range_type determine_value_range (tree expr, wide_int *min, wide_int *max) { - value_range vr = VR_INITIALIZER; + value_range vr (TREE_TYPE (expr)); determine_value_range_1 (&vr, expr); - if ((vr.type == VR_RANGE - || vr.type == VR_ANTI_RANGE) - && !symbolic_range_p (&vr)) + if (vr.numeric_p ()) { - *min = wi::to_wide (vr.min); - *max = wi::to_wide (vr.max); - return vr.type; + *min = wi::to_wide (vr.min ()); + *max = wi::to_wide (vr.max ()); + return vr.vrtype (); } return VR_VARYING; diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h index 655cf055f0a..04e0d0cb4a6 100644 --- a/gcc/tree-vrp.h +++ b/gcc/tree-vrp.h @@ -27,35 +27,140 @@ enum value_range_type { VR_UNDEFINED, VR_RANGE, /* Range of values that can be associated with an SSA_NAME after VRP has executed. */ -struct GTY((for_user)) value_range +class GTY((for_user)) value_range { - /* Lattice value represented by this range. */ - enum value_range_type type; + public: + value_range (); + value_range (tree type); + value_range (value_range_type, tree type, tree, tree, bitmap = NULL); + bool operator== (const value_range &) const; + bool operator!= (const value_range &) const; + void intersect (const value_range *); + void union_ (const value_range *); + /* Like operator== but ignore equivalence bitmap. */ + bool ignore_equivs_equal_p (const value_range &) const; + /* Like a operator= but update equivalence bitmap efficiently. */ + void copy_with_equiv_update (const value_range *); + + /* Types of value ranges. */ + bool undefined_p () const; + bool varying_p () const; + bool symbolic_p () const; + bool numeric_p () const; + void set_undefined (tree = NULL); + void set_varying (tree = NULL); + + /* Equivalence bitmap methods. */ + bitmap equiv () const; + void set_equiv (bitmap); + void equiv_free (); + void equiv_copy (const value_range *); + void equiv_clear (); + void equiv_and (const value_range *); + void equiv_ior (const value_range *); + + /* Misc methods. */ + tree type () const; + bool null_p () const; + bool may_contain_p (tree) const; + tree singleton () const; + void set_and_canonicalize (enum value_range_type, tree, tree, tree, bitmap); + void dump () const; - /* Minimum and maximum values represented by this range. These - values should be interpreted as follows: + /* Temporary accessors that should eventually be removed. */ + enum value_range_type vrtype () const; + tree min () const; + tree max () const; + + private: + void set (value_range_type, tree type, tree, tree, bitmap); + void check (); + bool equal_p (const value_range &, bool ignore_equivs) const; + + enum value_range_type m_vrtype; + public: + /* These should be private, but GTY is a piece of crap. */ + tree m_min; + tree m_max; + tree m_type; + /* Set of SSA names whose value ranges are equivalent to this one. + This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */ + bitmap m_equiv; +}; - - If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must - be NULL. +inline +value_range::value_range () +{ + m_type = m_min = m_max = NULL; + m_vrtype = VR_UNDEFINED; + m_equiv = NULL; +} - - If TYPE == VR_RANGE then MIN holds the minimum value and - MAX holds the maximum value of the range [MIN, MAX]. +inline +value_range::value_range (tree type) +{ + m_vrtype = VR_UNDEFINED; + m_min = m_max = NULL; + m_equiv = NULL; + m_type = type; +} + +inline value_range_type +value_range::vrtype () const +{ + return m_vrtype; +} - - If TYPE == ANTI_RANGE the variable is known to NOT - take any values in the range [MIN, MAX]. */ - tree min; - tree max; +inline tree +value_range::type () const +{ + return m_type; +} - /* Set of SSA names whose value ranges are equivalent to this one. - This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */ - bitmap equiv; +inline bitmap +value_range::equiv () const +{ + return m_equiv; +} - /* Dump value range to stderr. */ - void dump () const; -}; +inline tree +value_range::min () const +{ + return m_min; +} + +inline tree +value_range::max () const +{ + return m_max; +} + +inline bool +value_range::varying_p () const +{ + return m_vrtype == VR_VARYING; +} + +inline bool +value_range::undefined_p () const +{ + return m_vrtype == VR_UNDEFINED; +} + +inline void +value_range::set_equiv (bitmap b) +{ + m_equiv = b; +} + +inline bool +value_range::null_p () const +{ + return (m_vrtype == VR_RANGE + && integer_zerop (m_min) + && integer_zerop (m_max)); +} -extern void vrp_intersect_ranges (value_range *vr0, const value_range *vr1); -extern void vrp_meet (value_range *vr0, const value_range *vr1); extern void dump_value_range (FILE *, const value_range *); extern void extract_range_from_unary_expr (value_range *vr, enum tree_code code, @@ -85,19 +190,17 @@ struct assert_info extern void register_edge_assert_for (tree, edge, enum tree_code, tree, tree, vec &); extern bool stmt_interesting_for_vrp (gimple *); -extern void set_value_range_to_varying (value_range *); +extern void set_value_range_to_varying (value_range *, tree); extern bool range_includes_zero_p (const value_range *); 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 (value_range *, enum value_range_type, tree, tree, bitmap); -extern void set_and_canonicalize_value_range (value_range *, - enum value_range_type, - tree, tree, bitmap); +extern void set_value_range (value_range *, tree, enum value_range_type, tree, + tree, bitmap); extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap); extern tree value_range_constant_singleton (const value_range *); -extern bool symbolic_range_p (const value_range *); extern int compare_values (tree, tree); extern int compare_values_warnv (tree, tree, bool *); extern bool vrp_val_is_min (const_tree); diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 32392a11618..984cc16ddc0 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -55,7 +55,7 @@ static inline void set_value_range_to_nonnegative (value_range *vr, tree type) { tree zero = build_int_cst (type, 0); - set_value_range (vr, VR_RANGE, zero, vrp_val_max (type), vr->equiv); + set_value_range (vr, VR_RANGE, zero, vrp_val_max (type), vr->equiv ()); } /* Set value range VR to a range of a truthvalue of type TYPE. */ @@ -64,11 +64,11 @@ static inline void set_value_range_to_truthvalue (value_range *vr, tree type) { if (TYPE_PRECISION (type) == 1) - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); else set_value_range (vr, VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1), - vr->equiv); + vr->equiv ()); } @@ -80,8 +80,8 @@ set_value_range_to_truthvalue (value_range *vr, tree type) value_range * vr_values::get_value_range (const_tree var) { - static const value_range vr_const_varying - = { VR_VARYING, NULL_TREE, NULL_TREE, NULL }; + static const value_range vr_const_varying (VR_VARYING, TREE_TYPE (var), + NULL, NULL); value_range *vr; tree sym; unsigned ver = SSA_NAME_VERSION (var); @@ -106,10 +106,7 @@ vr_values::get_value_range (const_tree var) /* Create a default value range. */ vr_value[ver] = vr = vrp_value_range_pool.allocate (); - memset (vr, 0, sizeof (*vr)); - - /* Defer allocating the equivalence set. */ - vr->equiv = NULL; + *vr = value_range (TREE_TYPE (var)); /* If VAR is a default definition of a parameter, the variable can take any value in VAR's type. */ @@ -135,10 +132,10 @@ vr_values::get_value_range (const_tree var) wide_int_to_tree (TREE_TYPE (var), max), NULL); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, TREE_TYPE (var)); } else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, TREE_TYPE (sym)); } else if (TREE_CODE (sym) == RESULT_DECL && DECL_BY_REFERENCE (sym)) @@ -159,8 +156,8 @@ vr_values::set_defs_to_varying (gimple *stmt) { value_range *vr = get_value_range (def); /* Avoid writing to vr_const_varying get_value_range may return. */ - if (vr->type != VR_VARYING) - set_value_range_to_varying (vr); + if (!vr->varying_p ()) + set_value_range_to_varying (vr, vr->type ()); } } @@ -191,18 +188,19 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) tree nr_min, nr_max; nr_min = wide_int_to_tree (TREE_TYPE (var), min); nr_max = wide_int_to_tree (TREE_TYPE (var), max); - value_range nr = VR_INITIALIZER; - set_and_canonicalize_value_range (&nr, rtype, nr_min, nr_max, NULL); - vrp_intersect_ranges (new_vr, &nr); + value_range nr (TREE_TYPE (var)); + nr.set_and_canonicalize (rtype, TREE_TYPE (var), nr_min, nr_max, + NULL); + new_vr->intersect (&nr); } } /* Update the value range, if necessary. */ old_vr = get_value_range (var); - is_new = old_vr->type != new_vr->type - || !vrp_operand_equal_p (old_vr->min, new_vr->min) - || !vrp_operand_equal_p (old_vr->max, new_vr->max) - || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv); + is_new = old_vr->vrtype () != new_vr->vrtype () + || !vrp_operand_equal_p (old_vr->min (), new_vr->min ()) + || !vrp_operand_equal_p (old_vr->max (), new_vr->max ()) + || !vrp_bitmap_equal_p (old_vr->equiv (), new_vr->equiv ()); if (is_new) { @@ -212,19 +210,20 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) the same. We may not have is_new when transitioning to UNDEFINED. If old_vr->type is VARYING, we shouldn't be called. */ - if (new_vr->type == VR_UNDEFINED) + if (new_vr->undefined_p ()) { - BITMAP_FREE (new_vr->equiv); - set_value_range_to_varying (old_vr); - set_value_range_to_varying (new_vr); + new_vr->equiv_free (); + set_value_range_to_varying (old_vr, TREE_TYPE (var)); + set_value_range_to_varying (new_vr, TREE_TYPE (var)); return true; } else - set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max, - new_vr->equiv); + set_value_range (old_vr, new_vr->type (), new_vr->vrtype (), + new_vr->min (), new_vr->max (), + new_vr->equiv ()); } - BITMAP_FREE (new_vr->equiv); + new_vr->equiv_free (); return is_new; } @@ -233,17 +232,19 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) /* Add VAR and VAR's equivalence set to EQUIV. This is the central point where equivalence processing can be turned on/off. */ -void -vr_values::add_equivalence (bitmap *equiv, const_tree var) +bitmap +vr_values::add_equivalence (bitmap equiv, const_tree var) { unsigned ver = SSA_NAME_VERSION (var); value_range *vr = get_value_range (var); + bitmap ret = equiv; - if (*equiv == NULL) - *equiv = BITMAP_ALLOC (&vrp_equiv_obstack); - bitmap_set_bit (*equiv, ver); - if (vr && vr->equiv) - bitmap_ior_into (*equiv, vr->equiv); + if (ret == NULL) + ret = BITMAP_ALLOC (&vrp_equiv_obstack); + bitmap_set_bit (ret, ver); + if (vr && vr->equiv ()) + bitmap_ior_into (ret, vr->equiv ()); + return ret; } /* Return true if value range VR involves exactly one symbol SYM. */ @@ -254,16 +255,16 @@ symbolic_range_based_on_p (value_range *vr, const_tree sym) bool neg, min_has_symbol, max_has_symbol; tree inv; - if (is_gimple_min_invariant (vr->min)) + if (is_gimple_min_invariant (vr->min ())) min_has_symbol = false; - else if (get_single_symbol (vr->min, &neg, &inv) == sym) + else if (get_single_symbol (vr->min (), &neg, &inv) == sym) min_has_symbol = true; else return false; - if (is_gimple_min_invariant (vr->max)) + if (is_gimple_min_invariant (vr->max ())) max_has_symbol = false; - else if (get_single_symbol (vr->max, &neg, &inv) == sym) + else if (get_single_symbol (vr->max (), &neg, &inv) == sym) max_has_symbol = true; else return false; @@ -403,9 +404,9 @@ vr_values::op_with_boolean_value_range_p (tree op) return false; vr = get_value_range (op); - return (vr->type == VR_RANGE - && integer_zerop (vr->min) - && integer_onep (vr->max)); + return (vr->vrtype () == VR_RANGE + && integer_zerop (vr->min ()) + && integer_onep (vr->max ())); } /* Extract value range information for VAR when (OP COND_CODE LIMIT) is @@ -427,7 +428,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR) || limit == var) { - set_value_range_to_varying (vr_p); + set_value_range_to_varying (vr_p, type); return; } @@ -438,12 +439,13 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, /* LIMIT's range is only interesting if it has any useful information. */ if (! limit_vr - || limit_vr->type == VR_UNDEFINED - || limit_vr->type == VR_VARYING - || (symbolic_range_p (limit_vr) - && ! (limit_vr->type == VR_RANGE - && (limit_vr->min == limit_vr->max - || operand_equal_p (limit_vr->min, limit_vr->max, 0))))) + || limit_vr->undefined_p () + || limit_vr->varying_p () + || (limit_vr->symbolic_p () + && ! (limit_vr->vrtype () == VR_RANGE + && (limit_vr->min () == limit_vr->max () + || operand_equal_p (limit_vr->min (), + limit_vr->max (), 0))))) limit_vr = NULL; /* Initially, the new range has the same set of equivalences of @@ -451,8 +453,8 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, value. Since assertions may be chained via mutually exclusive predicates, we will need to trim the set of equivalences before we are done. */ - gcc_assert (vr_p->equiv == NULL); - add_equivalence (&vr_p->equiv, var); + gcc_assert (vr_p->equiv () == NULL); + vr_p->set_equiv (add_equivalence (vr_p->equiv (), var)); /* Extract a new range based on the asserted comparison for VAR and LIMIT's value range. Notice that if LIMIT has an anti-range, we @@ -488,14 +490,14 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, max = force_fit_type (TREE_TYPE (var), wi::to_widest (max), 0, false); /* We can transform a max, min range to an anti-range or - vice-versa. Use set_and_canonicalize_value_range which does - this for us. */ + vice-versa. Use set_and_canonicalize which does this for + us. */ if (cond_code == LE_EXPR) - set_and_canonicalize_value_range (vr_p, VR_RANGE, - min, max, vr_p->equiv); + vr_p->set_and_canonicalize (VR_RANGE, TREE_TYPE (min), min, max, + vr_p->equiv ()); else if (cond_code == GT_EXPR) - set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE, - min, max, vr_p->equiv); + vr_p->set_and_canonicalize (VR_ANTI_RANGE, TREE_TYPE (min), min, max, + vr_p->equiv ()); else gcc_unreachable (); } @@ -505,9 +507,9 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, if (limit_vr) { - range_type = limit_vr->type; - min = limit_vr->min; - max = limit_vr->max; + range_type = limit_vr->vrtype (); + min = limit_vr->min (); + max = limit_vr->max (); } else { @@ -516,13 +518,13 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, max = limit; } - set_value_range (vr_p, range_type, min, max, vr_p->equiv); + set_value_range (vr_p, range_type, min, max, vr_p->equiv ()); /* When asserting the equality VAR == LIMIT and LIMIT is another SSA name, the new range will also inherit the equivalence set from LIMIT. */ if (TREE_CODE (limit) == SSA_NAME) - add_equivalence (&vr_p->equiv, limit); + vr_p->set_equiv (add_equivalence (vr_p->equiv (), limit)); } else if (cond_code == NE_EXPR) { @@ -547,11 +549,11 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX). In that case, build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX]. */ if (limit_vr - && limit_vr->type == VR_RANGE - && compare_values (limit_vr->min, limit_vr->max) == 0) + && limit_vr->vrtype () == VR_RANGE + && compare_values (limit_vr->min (), limit_vr->max ()) == 0) { - min = limit_vr->min; - max = limit_vr->max; + min = limit_vr->min (); + max = limit_vr->max (); } else { @@ -567,21 +569,21 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, && vrp_val_is_max (max)) min = max = limit; - set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE, - min, max, vr_p->equiv); + vr_p->set_and_canonicalize (VR_ANTI_RANGE, TREE_TYPE (min), min, max, + vr_p->equiv ()); } else if (cond_code == LE_EXPR || cond_code == LT_EXPR) { min = TYPE_MIN_VALUE (type); - if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE) + if (limit_vr == NULL || limit_vr->vrtype () == VR_ANTI_RANGE) max = limit; else { /* If LIMIT_VR is of the form [N1, N2], we need to build the range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for LT_EXPR. */ - max = limit_vr->max; + max = limit_vr->max (); } /* If the maximum value forces us to be out of bounds, simply punt. @@ -589,7 +591,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, all should be optimized away above us. */ if (cond_code == LT_EXPR && compare_values (max, min) == 0) - set_value_range_to_varying (vr_p); + set_value_range_to_varying (vr_p, type); else { /* For LT_EXPR, we create the range [MIN, MAX - 1]. */ @@ -607,21 +609,21 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, TREE_NO_WARNING (max) = 1; } - set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv); + set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv ()); } } else if (cond_code == GE_EXPR || cond_code == GT_EXPR) { max = TYPE_MAX_VALUE (type); - if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE) + if (limit_vr == NULL || limit_vr->vrtype () == VR_ANTI_RANGE) min = limit; else { /* If LIMIT_VR is of the form [N1, N2], we need to build the range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for GT_EXPR. */ - min = limit_vr->min; + min = limit_vr->min (); } /* If the minimum value forces us to be out of bounds, simply punt. @@ -629,7 +631,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, all should be optimized away above us. */ if (cond_code == GT_EXPR && compare_values (min, max) == 0) - set_value_range_to_varying (vr_p); + set_value_range_to_varying (vr_p, type); else { /* For GT_EXPR, we create the range [MIN + 1, MAX]. */ @@ -647,14 +649,14 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, TREE_NO_WARNING (min) = 1; } - set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv); + set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv ()); } } else gcc_unreachable (); /* Finally intersect the new range with what we already know about var. */ - vrp_intersect_ranges (vr_p, get_value_range (var)); + vr_p->intersect (get_value_range (var)); } /* Extract value range information from an ASSERT_EXPR EXPR and store @@ -711,12 +713,12 @@ vr_values::extract_range_from_ssa_name (value_range *vr, tree var) { value_range *var_vr = get_value_range (var); - if (var_vr->type != VR_VARYING) + if (!var_vr->varying_p ()) copy_value_range (vr, var_vr); else set_value_range (vr, VR_RANGE, var, var, NULL); - add_equivalence (&vr->equiv, var); + vr->set_equiv (add_equivalence (vr->equiv (), var)); } /* Extract range information from a binary expression OP0 CODE OP1 based on @@ -728,8 +730,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, enum tree_code code, tree expr_type, tree op0, tree op1) { - value_range vr0 = VR_INITIALIZER; - value_range vr1 = VR_INITIALIZER; + value_range vr0 (expr_type), vr1 (expr_type); /* Get value ranges for each operand. For constant operands, create a new value range with the operand to simplify processing. */ @@ -738,32 +739,28 @@ vr_values::extract_range_from_binary_expr (value_range *vr, else if (is_gimple_min_invariant (op0)) set_value_range_to_value (&vr0, op0, NULL); else - set_value_range_to_varying (&vr0); + set_value_range_to_varying (&vr0, expr_type); 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); else - set_value_range_to_varying (&vr1); + set_value_range_to_varying (&vr1, expr_type); /* If one argument is varying, we can sometimes still deduce a range for the output: any + [3, +INF] is in [MIN+3, +INF]. */ if (INTEGRAL_TYPE_P (TREE_TYPE (op0)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))) { - if (vr0.type == VR_VARYING && vr1.type != VR_VARYING) - { - vr0.type = VR_RANGE; - vr0.min = vrp_val_min (expr_type); - vr0.max = vrp_val_max (expr_type); - } - else if (vr1.type == VR_VARYING && vr0.type != VR_VARYING) - { - vr1.type = VR_RANGE; - vr1.min = vrp_val_min (expr_type); - vr1.max = vrp_val_max (expr_type); - } + if (vr0.varying_p () && !vr1.varying_p ()) + vr0 = value_range (VR_RANGE, vr0.type (), + vrp_val_min (expr_type), + vrp_val_max (expr_type)); + else if (vr1.varying_p () && !vr0.varying_p ()) + vr1 = value_range (VR_RANGE, vr1.type (), + vrp_val_min (expr_type), + vrp_val_max (expr_type)); } extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1); @@ -773,7 +770,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, n = def - arg Here the range for n can be set to [0, PTRDIFF_MAX - 1]. */ - if (vr->type == VR_VARYING + if (vr->varying_p () && code == POINTER_DIFF_EXPR && TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME) @@ -806,21 +803,21 @@ vr_values::extract_range_from_binary_expr (value_range *vr, symbolic comparison. When a bound of the range of the first operand is invariant, we set the corresponding bound of the new range to INF in order to avoid recursing on the range of the second operand. */ - if (vr->type == VR_VARYING + if (vr->varying_p () && (code == PLUS_EXPR || code == MINUS_EXPR) && TREE_CODE (op1) == SSA_NAME - && vr0.type == VR_RANGE + && vr0.vrtype () == VR_RANGE && symbolic_range_based_on_p (&vr0, op1)) { const bool minus_p = (code == MINUS_EXPR); - value_range n_vr1 = VR_INITIALIZER; + value_range n_vr1 (expr_type); /* Try with VR0 and [-INF, OP1]. */ - if (is_gimple_min_invariant (minus_p ? vr0.max : vr0.min)) + 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); /* Try with VR0 and [OP1, +INF]. */ - else if (is_gimple_min_invariant (minus_p ? vr0.min : vr0.max)) + 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); /* Try with VR0 and [OP1, OP1]. */ @@ -830,21 +827,21 @@ vr_values::extract_range_from_binary_expr (value_range *vr, extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &n_vr1); } - if (vr->type == VR_VARYING + if (vr->varying_p () && (code == PLUS_EXPR || code == MINUS_EXPR) && TREE_CODE (op0) == SSA_NAME - && vr1.type == VR_RANGE + && vr1.vrtype () == VR_RANGE && symbolic_range_based_on_p (&vr1, op0)) { const bool minus_p = (code == MINUS_EXPR); - value_range n_vr0 = VR_INITIALIZER; + value_range n_vr0 (expr_type); /* Try with [-INF, OP0] and VR1. */ - if (is_gimple_min_invariant (minus_p ? vr1.max : vr1.min)) + 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); /* Try with [OP0, +INF] and VR1. */ - else if (is_gimple_min_invariant (minus_p ? vr1.min : vr1.max)) + 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); /* Try with [OP0, OP0] and VR1. */ @@ -858,15 +855,15 @@ vr_values::extract_range_from_binary_expr (value_range *vr, op1's range is ~[op0,op0] or vice-versa, then we can derive a non-null range. This happens often for pointer subtraction. */ - if (vr->type == VR_VARYING + if (vr->varying_p () && (code == MINUS_EXPR || code == POINTER_DIFF_EXPR) && TREE_CODE (op0) == SSA_NAME - && ((vr0.type == VR_ANTI_RANGE - && vr0.min == op1 - && vr0.min == vr0.max) - || (vr1.type == VR_ANTI_RANGE - && vr1.min == op0 - && vr1.min == vr1.max))) + && ((vr0.vrtype () == VR_ANTI_RANGE + && vr0.min () == op1 + && vr0.min () == vr0.max ()) + || (vr1.vrtype () == VR_ANTI_RANGE + && vr1.min () == op0 + && vr1.min () == vr1.max ()))) set_value_range_to_nonnull (vr, expr_type); } @@ -878,7 +875,7 @@ void vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code, tree type, tree op0) { - value_range vr0 = VR_INITIALIZER; + value_range vr0 (TREE_TYPE (op0)); /* Get value ranges for the operand. For constant operands, create a new value range with the operand to simplify processing. */ @@ -887,7 +884,7 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code, else if (is_gimple_min_invariant (op0)) set_value_range_to_value (&vr0, op0, NULL); else - set_value_range_to_varying (&vr0); + set_value_range_to_varying (&vr0, TREE_TYPE (op0)); ::extract_range_from_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0)); } @@ -899,31 +896,29 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code, void vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt) { - tree op0, op1; - value_range vr0 = VR_INITIALIZER; - value_range vr1 = VR_INITIALIZER; - /* Get value ranges for each operand. For constant operands, create a new value range with the operand to simplify processing. */ - op0 = gimple_assign_rhs2 (stmt); + tree op0 = gimple_assign_rhs2 (stmt); + value_range vr0 (TREE_TYPE (op0)); 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); else - set_value_range_to_varying (&vr0); + set_value_range_to_varying (&vr0, TREE_TYPE (op0)); - op1 = gimple_assign_rhs3 (stmt); + tree op1 = gimple_assign_rhs3 (stmt); + value_range vr1 (TREE_TYPE (op1)); 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); else - set_value_range_to_varying (&vr1); + set_value_range_to_varying (&vr1, TREE_TYPE (op1)); /* The resulting value range is the union of the operand ranges */ copy_value_range (vr, &vr0); - vrp_meet (vr, &vr1); + vr->union_ (&vr1); } @@ -946,9 +941,9 @@ 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, vr->equiv); + set_value_range_to_value (vr, val, vr->equiv ()); else - set_value_range (vr, VR_RANGE, val, val, vr->equiv); + set_value_range (vr, VR_RANGE, val, val, vr->equiv ()); } else /* The result of a comparison is always true or false. */ @@ -965,45 +960,47 @@ bool vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type, tree op0, tree op1, bool *ovf) { - value_range vr0 = VR_INITIALIZER; - value_range vr1 = VR_INITIALIZER; + value_range vr0 (type); + value_range vr1 (type); 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); else - set_value_range_to_varying (&vr0); + set_value_range_to_varying (&vr0, TREE_TYPE (op0)); 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); else - set_value_range_to_varying (&vr1); + set_value_range_to_varying (&vr1, TREE_TYPE (op1)); + tree vr0min = vr0.min (), vr0max = vr0.max (); + tree vr1min = vr1.min (), vr1max = vr1.max (); if (!range_int_cst_p (&vr0) - || TREE_OVERFLOW (vr0.min) - || TREE_OVERFLOW (vr0.max)) + || TREE_OVERFLOW (vr0min) + || TREE_OVERFLOW (vr0max)) { - vr0.min = vrp_val_min (TREE_TYPE (op0)); - vr0.max = vrp_val_max (TREE_TYPE (op0)); + vr0min = vrp_val_min (TREE_TYPE (op0)); + vr0max = vrp_val_max (TREE_TYPE (op0)); } if (!range_int_cst_p (&vr1) - || TREE_OVERFLOW (vr1.min) - || TREE_OVERFLOW (vr1.max)) + || TREE_OVERFLOW (vr1min) + || TREE_OVERFLOW (vr1max)) { - vr1.min = vrp_val_min (TREE_TYPE (op1)); - vr1.max = vrp_val_max (TREE_TYPE (op1)); + vr1min = vrp_val_min (TREE_TYPE (op1)); + vr1max = vrp_val_max (TREE_TYPE (op1)); } - *ovf = arith_overflowed_p (subcode, type, vr0.min, - subcode == MINUS_EXPR ? vr1.max : vr1.min); - if (arith_overflowed_p (subcode, type, vr0.max, - subcode == MINUS_EXPR ? vr1.min : vr1.max) != *ovf) + *ovf = arith_overflowed_p (subcode, type, vr0min, + subcode == MINUS_EXPR ? vr1max : vr1min); + if (arith_overflowed_p (subcode, type, vr0max, + subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf) return false; if (subcode == MULT_EXPR) { - if (arith_overflowed_p (subcode, type, vr0.min, vr1.max) != *ovf - || arith_overflowed_p (subcode, type, vr0.max, vr1.min) != *ovf) + if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf + || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf) return false; } if (*ovf) @@ -1016,10 +1013,10 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type, widest_int wmin, wmax; widest_int w[4]; int i; - w[0] = wi::to_widest (vr0.min); - w[1] = wi::to_widest (vr0.max); - w[2] = wi::to_widest (vr1.min); - w[3] = wi::to_widest (vr1.max); + w[0] = wi::to_widest (vr0min); + w[1] = wi::to_widest (vr0max); + w[2] = wi::to_widest (vr1min); + w[3] = wi::to_widest (vr1max); for (i = 0; i < 4; i++) { widest_int wt; @@ -1113,11 +1110,11 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) mini = 1; /* If some high bits are known to be zero, we can decrease the maximum. */ - if (vr0->type == VR_RANGE - && TREE_CODE (vr0->max) == INTEGER_CST - && !operand_less_p (vr0->min, - build_zero_cst (TREE_TYPE (vr0->min)))) - maxi = tree_floor_log2 (vr0->max) + 1; + if (vr0->vrtype () == VR_RANGE + && TREE_CODE (vr0->max ()) == INTEGER_CST + && !operand_less_p (vr0->min (), + build_zero_cst (TREE_TYPE (vr0->min ())))) + maxi = tree_floor_log2 (vr0->max ()) + 1; } goto bitop_builtin; /* __builtin_parity* returns [0, 1]. */ @@ -1148,15 +1145,15 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) value_range *vr0 = get_value_range (arg); /* From clz of VR_RANGE minimum we can compute result maximum. */ - if (vr0->type == VR_RANGE - && TREE_CODE (vr0->min) == INTEGER_CST) + if (vr0->vrtype () == VR_RANGE + && TREE_CODE (vr0->min ()) == INTEGER_CST) { - maxi = prec - 1 - tree_floor_log2 (vr0->min); + maxi = prec - 1 - tree_floor_log2 (vr0->min ()); if (maxi != prec) mini = 0; } - else if (vr0->type == VR_ANTI_RANGE - && integer_zerop (vr0->min)) + else if (vr0->vrtype () == VR_ANTI_RANGE + && integer_zerop (vr0->min ())) { maxi = prec - 1; mini = 0; @@ -1165,10 +1162,10 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) break; /* From clz of VR_RANGE maximum we can compute result minimum. */ - if (vr0->type == VR_RANGE - && TREE_CODE (vr0->max) == INTEGER_CST) + if (vr0->vrtype () == VR_RANGE + && TREE_CODE (vr0->max ()) == INTEGER_CST) { - mini = prec - 1 - tree_floor_log2 (vr0->max); + mini = prec - 1 - tree_floor_log2 (vr0->max ()); if (mini == prec) break; } @@ -1204,20 +1201,20 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) { value_range *vr0 = get_value_range (arg); /* If arg is non-zero, then use [0, prec - 1]. */ - if ((vr0->type == VR_RANGE - && integer_nonzerop (vr0->min)) - || (vr0->type == VR_ANTI_RANGE - && integer_zerop (vr0->min))) + if ((vr0->vrtype () == VR_RANGE + && integer_nonzerop (vr0->min ())) + || (vr0->vrtype () == VR_ANTI_RANGE + && integer_zerop (vr0->min ()))) { mini = 0; maxi = prec - 1; } /* If some high bits are known to be zero, we can decrease the result maximum. */ - if (vr0->type == VR_RANGE - && TREE_CODE (vr0->max) == INTEGER_CST) + if (vr0->vrtype () == VR_RANGE + && TREE_CODE (vr0->max ()) == INTEGER_CST) { - maxi = tree_floor_log2 (vr0->max); + maxi = tree_floor_log2 (vr0->max ()); /* For vr0 [0, 0] give up. */ if (maxi == -1) break; @@ -1302,10 +1299,10 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) this should have been already folded and if not, it wasn't folded because of overflow. Avoid removing the UBSAN_CHECK_* calls in that case. */ - if (vr->type == VR_RANGE - && (vr->min == vr->max - || operand_equal_p (vr->min, vr->max, 0))) - set_value_range_to_varying (vr); + if (vr->vrtype () == VR_RANGE + && (vr->min () == vr->max () + || operand_equal_p (vr->min (), vr->max (), 0))) + set_value_range_to_varying (vr, vr->type ()); return; } } @@ -1363,7 +1360,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) NULL); else if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); else set_value_range (vr, VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1), NULL); @@ -1381,8 +1378,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) } else { - value_range vr0 = VR_INITIALIZER; - value_range vr1 = VR_INITIALIZER; + value_range vr0 (type), vr1 (type); bool saved_flag_wrapv = flag_wrapv; /* Pretend the arithmetics is wrapping. If there is any overflow, IMAGPART_EXPR will be set. */ @@ -1406,7 +1402,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) else if (vrp_stmt_computes_nonzero (stmt)) set_value_range_to_nonnull (vr, type); else - set_value_range_to_varying (vr); + set_value_range_to_varying (vr, type); } @@ -1442,9 +1438,12 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt) && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL); else - set_value_range_to_varying (vr); + { + tree type = TREE_TYPE (gimple_assign_lhs (stmt)); + set_value_range_to_varying (vr, type); + } - if (vr->type == VR_VARYING) + if (vr->varying_p ()) extract_range_basic (vr, stmt); } @@ -1467,18 +1466,18 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, bool *strict_overflow_p) { /* VARYING or UNDEFINED ranges cannot be compared. */ - if (vr0->type == VR_VARYING - || vr0->type == VR_UNDEFINED - || vr1->type == VR_VARYING - || vr1->type == VR_UNDEFINED) + if (vr0->varying_p () + || vr0->undefined_p () + || vr1->varying_p () + || vr1->undefined_p ()) return NULL_TREE; /* Anti-ranges need to be handled separately. */ - if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE) + if (vr0->vrtype () == VR_ANTI_RANGE || vr1->vrtype () == VR_ANTI_RANGE) { /* If both are anti-ranges, then we cannot compute any comparison. */ - if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE) + if (vr0->vrtype () == VR_ANTI_RANGE && vr1->vrtype () == VR_ANTI_RANGE) return NULL_TREE; /* These comparisons are never statically computable. */ @@ -1490,7 +1489,7 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, /* Equality can be computed only between a range and an anti-range. ~[VAL1, VAL2] == [VAL1, VAL2] is always false. */ - if (vr0->type == VR_RANGE) + if (vr0->vrtype () == VR_RANGE) { /* To simplify processing, make VR0 the anti-range. */ value_range *tmp = vr0; @@ -1500,8 +1499,8 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, gcc_assert (comp == NE_EXPR || comp == EQ_EXPR); - if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0 - && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0) + if (compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p) == 0 + && compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p) == 0) return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node; return NULL_TREE; @@ -1519,12 +1518,12 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, { /* Equality may only be computed if both ranges represent exactly one value. */ - if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0 - && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0) + if (compare_values_warnv (vr0->min (), vr0->max (), strict_overflow_p) == 0 + && compare_values_warnv (vr1->min (), vr1->max (), strict_overflow_p) == 0) { - int cmp_min = compare_values_warnv (vr0->min, vr1->min, + int cmp_min = compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p); - int cmp_max = compare_values_warnv (vr0->max, vr1->max, + int cmp_max = compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p); if (cmp_min == 0 && cmp_max == 0) return boolean_true_node; @@ -1532,9 +1531,9 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, return boolean_false_node; } /* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1. */ - else if (compare_values_warnv (vr0->min, vr1->max, + else if (compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p) == 1 - || compare_values_warnv (vr1->min, vr0->max, + || compare_values_warnv (vr1->min (), vr0->max (), strict_overflow_p) == 1) return boolean_false_node; @@ -1549,20 +1548,20 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, make sure that both comparisons yield similar results to avoid comparing values that cannot be compared at compile-time. */ - cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p); - cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p); + cmp1 = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p); + cmp2 = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p); if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1)) return boolean_true_node; /* If VR0 and VR1 represent a single value and are identical, return false. */ - else if (compare_values_warnv (vr0->min, vr0->max, + else if (compare_values_warnv (vr0->min (), vr0->max (), strict_overflow_p) == 0 - && compare_values_warnv (vr1->min, vr1->max, + && compare_values_warnv (vr1->min (), vr1->max (), strict_overflow_p) == 0 - && compare_values_warnv (vr0->min, vr1->min, + && compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p) == 0 - && compare_values_warnv (vr0->max, vr1->max, + && compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p) == 0) return boolean_false_node; @@ -1575,13 +1574,13 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1, int tst; /* If VR0 is to the left of VR1, return true. */ - tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p); + tst = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p); if ((comp == LT_EXPR && tst == -1) || (comp == LE_EXPR && (tst == -1 || tst == 0))) return boolean_true_node; /* If VR0 is to the right of VR1, return false. */ - tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p); + tst = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p); if ((comp == LT_EXPR && (tst == 0 || tst == 1)) || (comp == LE_EXPR && tst == 1)) return boolean_false_node; @@ -1605,11 +1604,11 @@ static tree compare_range_with_value (enum tree_code comp, value_range *vr, tree val, bool *strict_overflow_p) { - if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED) + if (vr->varying_p () || vr->undefined_p ()) return NULL_TREE; /* Anti-ranges need to be handled separately. */ - if (vr->type == VR_ANTI_RANGE) + if (vr->vrtype () == VR_ANTI_RANGE) { /* For anti-ranges, the only predicates that we can compute at compile time are equality and inequality. */ @@ -1620,7 +1619,7 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val, return NULL_TREE; /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2. */ - if (value_inside_range (val, vr->min, vr->max) == 1) + if (value_inside_range (val, vr->min (), vr->max ()) == 1) return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node; return NULL_TREE; @@ -1630,16 +1629,16 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val, { /* EQ_EXPR may only be computed if VR represents exactly one value. */ - if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0) + if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0) { - int cmp = compare_values_warnv (vr->min, val, strict_overflow_p); + int cmp = compare_values_warnv (vr->min (), val, strict_overflow_p); if (cmp == 0) return boolean_true_node; else if (cmp == -1 || cmp == 1 || cmp == 2) return boolean_false_node; } - else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1 - || compare_values_warnv (vr->max, val, strict_overflow_p) == -1) + else if (compare_values_warnv (val, vr->min (), strict_overflow_p) == -1 + || compare_values_warnv (vr->max (), val, strict_overflow_p) == -1) return boolean_false_node; return NULL_TREE; @@ -1647,14 +1646,14 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val, else if (comp == NE_EXPR) { /* If VAL is not inside VR, then they are always different. */ - if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1 - || compare_values_warnv (vr->min, val, strict_overflow_p) == 1) + if (compare_values_warnv (vr->max (), val, strict_overflow_p) == -1 + || compare_values_warnv (vr->min (), val, strict_overflow_p) == 1) return boolean_true_node; /* If VR represents exactly one value equal to VAL, then return false. */ - if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0 - && compare_values_warnv (vr->min, val, strict_overflow_p) == 0) + if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0 + && compare_values_warnv (vr->min (), val, strict_overflow_p) == 0) return boolean_false_node; /* Otherwise, they may or may not be different. */ @@ -1665,13 +1664,13 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val, int tst; /* If VR is to the left of VAL, return true. */ - tst = compare_values_warnv (vr->max, val, strict_overflow_p); + tst = compare_values_warnv (vr->max (), val, strict_overflow_p); if ((comp == LT_EXPR && tst == -1) || (comp == LE_EXPR && (tst == -1 || tst == 0))) return boolean_true_node; /* If VR is to the right of VAL, return false. */ - tst = compare_values_warnv (vr->min, val, strict_overflow_p); + tst = compare_values_warnv (vr->min (), val, strict_overflow_p); if ((comp == LT_EXPR && (tst == 0 || tst == 1)) || (comp == LE_EXPR && tst == 1)) return boolean_false_node; @@ -1684,13 +1683,13 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val, int tst; /* If VR is to the right of VAL, return true. */ - tst = compare_values_warnv (vr->min, val, strict_overflow_p); + tst = compare_values_warnv (vr->min (), val, strict_overflow_p); if ((comp == GT_EXPR && tst == 1) || (comp == GE_EXPR && (tst == 0 || tst == 1))) return boolean_true_node; /* If VR is to the left of VAL, return false. */ - tst = compare_values_warnv (vr->max, val, strict_overflow_p); + tst = compare_values_warnv (vr->max (), val, strict_overflow_p); if ((comp == GT_EXPR && (tst == -1 || tst == 0)) || (comp == GE_EXPR && tst == -1)) return boolean_false_node; @@ -1714,7 +1713,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, /* TODO. Don't adjust anti-ranges. An anti-range may provide better opportunities than a regular range, but I'm not sure. */ - if (vr->type == VR_ANTI_RANGE) + if (vr->vrtype () == VR_ANTI_RANGE) return; chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var)); @@ -1722,7 +1721,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, vr->equiv); + set_value_range_to_value (vr, chrec, vr->equiv ()); return; } @@ -1771,7 +1770,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, if (TREE_CODE (step) == INTEGER_CST && is_gimple_val (init) && (TREE_CODE (init) != SSA_NAME - || get_value_range (init)->type == VR_RANGE)) + || get_value_range (init)->vrtype () == VR_RANGE)) { widest_int nit; @@ -1779,7 +1778,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, the number of latch executions is the correct thing to use. */ if (max_loop_iterations (loop, &nit)) { - value_range maxvr = VR_INITIALIZER; + value_range maxvr (TREE_TYPE (init)); signop sgn = TYPE_SIGN (TREE_TYPE (step)); wi::overflow_type overflow; @@ -1799,9 +1798,9 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, extract_range_from_binary_expr (&maxvr, PLUS_EXPR, TREE_TYPE (init), init, tem); /* Likewise if the addition did. */ - if (maxvr.type == VR_RANGE) + if (maxvr.vrtype () == VR_RANGE) { - value_range initvr = VR_INITIALIZER; + value_range initvr (TREE_TYPE (init)); if (TREE_CODE (init) == SSA_NAME) initvr = *(get_value_range (init)); @@ -1815,19 +1814,19 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, because the loop may exit immediately. Overflow could happen in the plus expression in this case. */ if ((dir == EV_DIR_DECREASES - && compare_values (maxvr.min, initvr.min) != -1) + && compare_values (maxvr.min (), initvr.min ()) != -1) || (dir == EV_DIR_GROWS - && compare_values (maxvr.max, initvr.max) != 1)) + && compare_values (maxvr.max (), initvr.max ()) != 1)) return; - tmin = maxvr.min; - tmax = maxvr.max; + tmin = maxvr.min (); + tmax = maxvr.max (); } } } } - if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED) + if (vr->varying_p () || vr->undefined_p ()) { min = tmin; max = tmax; @@ -1840,15 +1839,15 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, else min = init; } - else if (vr->type == VR_RANGE) + else if (vr->vrtype () == VR_RANGE) { - min = vr->min; - max = vr->max; + min = vr->min (); + max = vr->max (); if (dir == EV_DIR_DECREASES) { - /* INIT is the maximum value. If INIT is lower than VR->MAX - but no smaller than VR->MIN, set VR->MAX to INIT. */ + /* INIT is the maximum value. If INIT is lower than VR->MAX () + but no smaller than VR->MIN (), set VR->MAX () to INIT. */ if (compare_values (init, max) == -1) max = init; @@ -1860,7 +1859,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, } else { - /* If INIT is bigger than VR->MIN, set VR->MIN to INIT. */ + /* If INIT is bigger than VR->MIN (), set VR->MIN () to INIT. */ if (compare_values (init, min) == 1) min = init; @@ -1886,7 +1885,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, if (TREE_OVERFLOW_P (max)) max = drop_tree_overflow (max); - set_value_range (vr, VR_RANGE, min, max, vr->equiv); + set_value_range (vr, VR_RANGE, min, max, vr->equiv ()); } /* Dump value ranges of all SSA_NAMEs to FILE. */ @@ -1957,11 +1956,11 @@ vrp_valueize (tree name) if (TREE_CODE (name) == SSA_NAME) { value_range *vr = x_vr_values->get_value_range (name); - if (vr->type == VR_RANGE - && (TREE_CODE (vr->min) == SSA_NAME - || is_gimple_min_invariant (vr->min)) - && vrp_operand_equal_p (vr->min, vr->max)) - return vr->min; + if (vr->vrtype () == VR_RANGE + && (TREE_CODE (vr->min ()) == SSA_NAME + || is_gimple_min_invariant (vr->min ())) + && vrp_operand_equal_p (vr->min (), vr->max ())) + return vr->min (); } return name; } @@ -1982,8 +1981,9 @@ vrp_valueize_1 (tree name) && prop_simulate_again_p (def_stmt)) return NULL_TREE; value_range *vr = x_vr_values->get_value_range (name); - if (range_int_cst_singleton_p (vr)) - return vr->min; + tree singleton = vr->singleton (); + if (singleton) + return singleton; } return name; } @@ -2066,12 +2066,9 @@ vr_values::get_vr_for_comparison (int 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.type == VR_VARYING || vr.type == VR_UNDEFINED) - { - vr.type = VR_RANGE; - vr.min = ssa_name (i); - vr.max = ssa_name (i); - } + if (vr.varying_p () || vr.undefined_p ()) + vr = value_range (VR_RANGE, vr.type (), ssa_name (i), ssa_name (i), + vr.equiv ()); return vr; } @@ -2094,7 +2091,7 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, value_range equiv_vr; /* Get the set of equivalences for VAR. */ - e = get_value_range (var)->equiv; + e = 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. */ @@ -2180,8 +2177,8 @@ vr_values::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. */ - e1 = get_value_range (n1)->equiv; - e2 = get_value_range (n2)->equiv; + e1 = get_value_range (n1)->equiv (); + e2 = get_value_range (n2)->equiv (); /* Use the fake bitmaps if e1 or e2 are not available. */ if (s_obstack == NULL) @@ -2440,10 +2437,10 @@ vr_values::vrp_evaluate_conditional (tree_code code, tree op0, tree type = TREE_TYPE (op0); value_range *vr0 = get_value_range (op0); - if (vr0->type == VR_RANGE + if (vr0->vrtype () == VR_RANGE && INTEGRAL_TYPE_P (type) - && vrp_val_is_min (vr0->min) - && vrp_val_is_max (vr0->max) + && vrp_val_is_min (vr0->min ()) + && vrp_val_is_max (vr0->max ()) && is_gimple_min_invariant (op1)) { location_t location; @@ -2572,9 +2569,9 @@ find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1, unsigned int n = gimple_switch_num_labels (stmt); bool take_default; tree case_low, case_high; - tree min = vr->min, max = vr->max; + tree min = vr->min (), max = vr->max (); - gcc_checking_assert (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE); + gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ()); take_default = !find_case_label_range (stmt, min, max, &i, &j); @@ -2582,7 +2579,7 @@ find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1, *min_idx2 = 1; *max_idx2 = 0; - if (vr->type == VR_RANGE) + if (vr->vrtype () == VR_RANGE) { *min_idx1 = i; *max_idx1 = j; @@ -2663,9 +2660,9 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p) fprintf (dump_file, "\n"); } - if ((vr->type != VR_RANGE - && vr->type != VR_ANTI_RANGE) - || symbolic_range_p (vr)) + if (vr->undefined_p () + || vr->varying_p () + || vr->symbolic_p ()) return; /* Find the single edge that is taken from the switch expression. */ @@ -2809,29 +2806,20 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) See PR53465 and PR54767. */ if (e->flags & EDGE_DFS_BACK) { - if (vr_arg.type == VR_RANGE - || vr_arg.type == VR_ANTI_RANGE) + if (!vr_arg.varying_p () + && !vr_arg.undefined_p ()) { - vr_arg.equiv = NULL; - if (symbolic_range_p (&vr_arg)) - { - vr_arg.type = VR_VARYING; - vr_arg.min = NULL_TREE; - vr_arg.max = NULL_TREE; - } + vr_arg.equiv_clear (); + if (vr_arg.symbolic_p ()) + vr_arg.set_varying (); } } else { /* If the non-backedge arguments range is VR_VARYING then we can still try recording a simple equivalence. */ - if (vr_arg.type == VR_VARYING) - { - vr_arg.type = VR_RANGE; - vr_arg.min = arg; - vr_arg.max = arg; - vr_arg.equiv = NULL; - } + if (vr_arg.varying_p ()) + vr_arg.equiv_clear (); } } else @@ -2839,10 +2827,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) if (TREE_OVERFLOW_P (arg)) arg = drop_tree_overflow (arg); - vr_arg.type = VR_RANGE; - vr_arg.min = arg; - vr_arg.max = arg; - vr_arg.equiv = NULL; + vr_arg = value_range (VR_RANGE, TREE_TYPE (arg), arg, arg); } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2857,17 +2842,17 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) if (first) copy_value_range (vr_result, &vr_arg); else - vrp_meet (vr_result, &vr_arg); + vr_result->union_ (&vr_arg); first = false; - if (vr_result->type == VR_VARYING) + if (vr_result->varying_p ()) break; } } - if (vr_result->type == VR_VARYING) + if (vr_result->varying_p ()) goto varying; - else if (vr_result->type == VR_UNDEFINED) + else if (vr_result->undefined_p ()) goto update_range; old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)]; @@ -2883,21 +2868,21 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) if (edges > 0 && gimple_phi_num_args (phi) > 1 && edges == old_edges - && lhs_vr->type != VR_UNDEFINED + && !lhs_vr->undefined_p () && may_simulate_backedge_again) { /* Compare old and new ranges, fall back to varying if the values are not comparable. */ - int cmp_min = compare_values (lhs_vr->min, vr_result->min); + int cmp_min = compare_values (lhs_vr->min (), vr_result->min ()); if (cmp_min == -2) goto varying; - int cmp_max = compare_values (lhs_vr->max, vr_result->max); + int cmp_max = compare_values (lhs_vr->max (), vr_result->max ()); if (cmp_max == -2) goto varying; /* For non VR_RANGE or for pointers fall back to varying if the range changed. */ - if ((lhs_vr->type != VR_RANGE || vr_result->type != VR_RANGE + if ((lhs_vr->vrtype () != VR_RANGE || vr_result->vrtype () != VR_RANGE || POINTER_TYPE_P (TREE_TYPE (lhs))) && (cmp_min != 0 || cmp_max != 0)) goto varying; @@ -2910,24 +2895,27 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) times to reach -INF. Going to -INF + 1 also lets the following iteration compute whether there will be any overflow, at the expense of one additional iteration. */ + tree new_min = vr_result->min (); + tree new_max = vr_result->max (); if (cmp_min < 0) - vr_result->min = lhs_vr->min; + new_min = lhs_vr->min (); else if (cmp_min > 0 - && !vrp_val_is_min (vr_result->min)) - vr_result->min - = int_const_binop (PLUS_EXPR, - vrp_val_min (TREE_TYPE (vr_result->min)), - build_int_cst (TREE_TYPE (vr_result->min), 1)); + && !vrp_val_is_min (vr_result->min ())) + new_min = int_const_binop (PLUS_EXPR, + vrp_val_min (vr_result->type ()), + build_int_cst (vr_result->type (), 1)); /* Similarly for the maximum value. */ if (cmp_max > 0) - vr_result->max = lhs_vr->max; + new_max = lhs_vr->max (); else if (cmp_max < 0 - && !vrp_val_is_max (vr_result->max)) - vr_result->max - = int_const_binop (MINUS_EXPR, - vrp_val_max (TREE_TYPE (vr_result->min)), - build_int_cst (TREE_TYPE (vr_result->min), 1)); + && !vrp_val_is_max (vr_result->max ())) + new_max = int_const_binop (MINUS_EXPR, + vrp_val_max (vr_result->type ()), + build_int_cst (vr_result->type (), 1)); + + *vr_result = value_range (vr_result->vrtype (), vr_result->type (), + new_min, new_max, vr_result->equiv ()); /* If we dropped either bound to +-INF then if this is a loop PHI node SCEV may known more about its value-range. */ @@ -2941,7 +2929,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) goto update_range; varying: - set_value_range_to_varying (vr_result); + set_value_range_to_varying (vr_result, TREE_TYPE (lhs)); scev_check: /* If this is a loop PHI node SCEV may known more about its value-range. @@ -2957,12 +2945,12 @@ infinite_check: /* If we will end up with a (-INF, +INF) range, set it to VARYING. Same if the previous max value was invalid for the type and we end up with vr_result.min > vr_result.max. */ - if ((vr_result->type == VR_RANGE || vr_result->type == VR_ANTI_RANGE) - && !((vrp_val_is_max (vr_result->max) && vrp_val_is_min (vr_result->min)) - || compare_values (vr_result->min, vr_result->max) > 0)) + if ((!vr_result->varying_p () && !vr_result->undefined_p ()) + && !((vrp_val_is_max (vr_result->max ()) && vrp_val_is_min (vr_result->min ())) + || compare_values (vr_result->min (), vr_result->max ()) > 0)) ; else - set_value_range_to_varying (vr_result); + set_value_range_to_varying (vr_result, TREE_TYPE (lhs)); /* If the new range is different than the previous value, keep iterating. */ @@ -3071,8 +3059,8 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, vr = get_value_range (op0); if (range_int_cst_p (vr)) { - op0min = vr->min; - op0max = vr->max; + op0min = vr->min (); + op0max = vr->max (); } } @@ -3081,7 +3069,7 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, { value_range *vr1 = get_value_range (op1); if (range_int_cst_p (vr1)) - op1min = vr1->min; + op1min = vr1->min (); } if (rhs_code == TRUNC_MOD_EXPR && TREE_CODE (op1min) == INTEGER_CST @@ -3285,8 +3273,8 @@ 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 = VR_INITIALIZER; - value_range vr1 = VR_INITIALIZER; + value_range vr0 (TREE_TYPE (op0)); + value_range vr1 (TREE_TYPE (op1)); wide_int may_be_nonzero0, may_be_nonzero1; wide_int must_be_nonzero0, must_be_nonzero1; wide_int mask; @@ -3405,10 +3393,10 @@ test_for_singularity (enum tree_code cond_code, tree op0, value range information we have for op0. */ if (min && max) { - if (compare_values (vr->min, min) == 1) - min = vr->min; - if (compare_values (vr->max, max) == -1) - max = vr->max; + if (compare_values (vr->min (), min) == 1) + min = vr->min (); + if (compare_values (vr->max (), max) == -1) + max = vr->max (); /* If the new min/max values have converged to a single value, then there is only one value which can satisfy the condition, @@ -3431,14 +3419,14 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn) signop src_sgn; /* We can only handle integral and pointer types. */ - src_type = TREE_TYPE (vr->min); + src_type = vr->type (); if (!INTEGRAL_TYPE_P (src_type) && !POINTER_TYPE_P (src_type)) return false; /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED, and so is an identity transform. */ - src_precision = TYPE_PRECISION (TREE_TYPE (vr->min)); + src_precision = TYPE_PRECISION (vr->type ()); src_sgn = TYPE_SIGN (src_type); if ((src_precision < dest_precision && !(dest_sgn == UNSIGNED && src_sgn == SIGNED)) @@ -3446,9 +3434,7 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn) return true; /* Now we can only handle ranges with constant bounds. */ - if (vr->type != VR_RANGE - || TREE_CODE (vr->min) != INTEGER_CST - || TREE_CODE (vr->max) != INTEGER_CST) + if (!range_int_cst_p (vr)) return false; /* For sign changes, the MSB of the wide_int has to be clear. @@ -3456,17 +3442,17 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn) a signed wide_int, while a negative value cannot be represented by an unsigned wide_int. */ if (src_sgn != dest_sgn - && (wi::lts_p (wi::to_wide (vr->min), 0) - || wi::lts_p (wi::to_wide (vr->max), 0))) + && (wi::lts_p (wi::to_wide (vr->min ()), 0) + || wi::lts_p (wi::to_wide (vr->max ()), 0))) return false; /* Then we can perform the conversion on both ends and compare the result for equality. */ - tem = wi::ext (wi::to_widest (vr->min), dest_precision, dest_sgn); - if (tem != wi::to_widest (vr->min)) + tem = wi::ext (wi::to_widest (vr->min ()), dest_precision, dest_sgn); + if (tem != wi::to_widest (vr->min ())) return false; - tem = wi::ext (wi::to_widest (vr->max), dest_precision, dest_sgn); - if (tem != wi::to_widest (vr->max)) + tem = wi::ext (wi::to_widest (vr->max ()), dest_precision, dest_sgn); + if (tem != wi::to_widest (vr->max ())) return false; return true; @@ -3493,7 +3479,7 @@ vr_values::simplify_cond_using_ranges_1 (gcond *stmt) /* If we have range information for OP0, then we might be able to simplify this conditional. */ - if (vr->type == VR_RANGE) + if (vr->vrtype () == VR_RANGE) { tree new_tree = test_for_singularity (cond_code, op0, op1, vr); if (new_tree) @@ -3636,9 +3622,9 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt) vr = get_value_range (op); /* We can only handle integer ranges. */ - if ((vr->type != VR_RANGE - && vr->type != VR_ANTI_RANGE) - || symbolic_range_p (vr)) + if (vr->varying_p () + || vr->undefined_p () + || vr->symbolic_p ()) return false; /* Find case label for min/max of the value range. */ @@ -3666,7 +3652,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt) value range. */ size_t min_idx = 1, max_idx = 0; if (vr != NULL) - find_case_label_range (stmt, vr->min, vr->max, &min_idx, &max_idx); + find_case_label_range (stmt, vr->min (), vr->max (), &min_idx, &max_idx); if (min_idx <= max_idx) { tree min_label = gimple_switch_label (stmt, min_idx); @@ -3674,10 +3660,10 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt) /* Avoid changing the type of the case labels when truncating. */ tree case_label_type = TREE_TYPE (CASE_LOW (min_label)); - tree vr_min = fold_convert (case_label_type, vr->min); - tree vr_max = fold_convert (case_label_type, vr->max); + tree vr_min = fold_convert (case_label_type, vr->min ()); + tree vr_max = fold_convert (case_label_type, vr->max ()); - if (vr->type == VR_RANGE) + if (vr->vrtype () == VR_RANGE) { /* If OP's value range is [2,8] and the low label range is 0 ... 3, truncate the label's range to 2 .. 3. */ @@ -3693,7 +3679,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt) && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) CASE_HIGH (max_label) = vr_max; } - else if (vr->type == VR_ANTI_RANGE) + else if (vr->vrtype () == VR_ANTI_RANGE) { tree one_cst = build_one_cst (case_label_type); @@ -3930,9 +3916,7 @@ vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, gassign *conv; /* We can only handle constant ranges. */ - if (vr->type != VR_RANGE - || TREE_CODE (vr->min) != INTEGER_CST - || TREE_CODE (vr->max) != INTEGER_CST) + if (!range_int_cst_p (vr)) return false; /* First check if we can use a signed type in place of an unsigned. */ @@ -4088,26 +4072,26 @@ bool vr_values::two_valued_val_range_p (tree var, tree *a, tree *b) { value_range *vr = get_value_range (var); - if ((vr->type != VR_RANGE - && vr->type != VR_ANTI_RANGE) - || TREE_CODE (vr->min) != INTEGER_CST - || TREE_CODE (vr->max) != INTEGER_CST) + if (vr->varying_p () + || vr->undefined_p () + || TREE_CODE (vr->min ()) != INTEGER_CST + || TREE_CODE (vr->max ()) != INTEGER_CST) return false; - if (vr->type == VR_RANGE - && wi::to_wide (vr->max) - wi::to_wide (vr->min) == 1) + if (vr->vrtype () == VR_RANGE + && wi::to_wide (vr->max ()) - wi::to_wide (vr->min ()) == 1) { - *a = vr->min; - *b = vr->max; + *a = vr->min (); + *b = vr->max (); return true; } /* ~[TYPE_MIN + 1, TYPE_MAX - 1] */ - if (vr->type == VR_ANTI_RANGE - && (wi::to_wide (vr->min) + if (vr->vrtype () == VR_ANTI_RANGE + && (wi::to_wide (vr->min ()) - wi::to_wide (vrp_val_min (TREE_TYPE (var)))) == 1 && (wi::to_wide (vrp_val_max (TREE_TYPE (var))) - - wi::to_wide (vr->max)) == 1) + - wi::to_wide (vr->max ())) == 1) { *a = vrp_val_min (TREE_TYPE (var)); *b = vrp_val_max (TREE_TYPE (var)); diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 487a800c1ea..496707856c3 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -72,7 +72,7 @@ class vr_values void cleanup_edges_and_switches (void); private: - void add_equivalence (bitmap *, const_tree); + bitmap add_equivalence (bitmap, const_tree); 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 *); @@ -142,7 +142,5 @@ class vr_values vec to_update_switch_stmts; }; -#define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL } - extern tree get_output_for_vrp (gimple *); #endif /* GCC_VR_VALUES_H */