From patchwork Fri May 21 11:39:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1482191 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=DtLsMax4; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FmlNJ2ZTCz9sV5 for ; Fri, 21 May 2021 21:52:48 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5F3AD3847811; Fri, 21 May 2021 11:52:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5F3AD3847811 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1621597960; bh=JTt+mOZIFo9/qPyaH2wo66yzC2FPQsfEy5oXqzd9gek=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=DtLsMax4bznlsloWsMRxhx9nDDEbTYFRe9OUK3LLmw+1COM05PBwTmWjvQHOXF93G TIC8ZVAKglmTDqQNZXnS6XVKrgTmq+4FeXr1HLd1mF3DY690pQXkMiL58h05XzDiut yKNqFEAO/zbrccWnLxputzIC38eRjQ8G69U0vvkI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id EA21E3847811 for ; Fri, 21 May 2021 11:52:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EA21E3847811 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-454-xAUVd0JCMU-k_EEs_e6uPw-1; Fri, 21 May 2021 07:52:32 -0400 X-MC-Unique: xAUVd0JCMU-k_EEs_e6uPw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 38264801817; Fri, 21 May 2021 11:52:31 +0000 (UTC) Received: from abulafia.quesejoda.com (ovpn-113-127.ams2.redhat.com [10.36.113.127]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 81F1F19C45; Fri, 21 May 2021 11:52:30 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.16.1/8.15.2) with ESMTPS id 14LBqSHA1148412 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 21 May 2021 13:52:28 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.16.1/8.16.1/Submit) id 14LBqR5Z1148411; Fri, 21 May 2021 13:52:27 +0200 To: GCC patches , Andrew MacLeod Subject: [PATCH 1/5] Common API for accessing global and on-demand ranges. Date: Fri, 21 May 2021 13:39:50 +0200 Message-Id: <20210521113954.1148075-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Cc: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch provides a generic API for accessing global ranges. It is meant to replace get_range_info() and get_ptr_nonnull() with one common interface. It uses the same API as the ranger (class range_query), so there will now be one API for accessing local and global ranges alike. Follow-up patches will convert all users of get_range_info and get_ptr_nonnull to this API. For get_range_info, instead of: if (!POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_RANGE_INFO (name)) get_range_info (name, vr); You can now do: RANGE_QUERY (cfun)->range_of_expr (vr, name, [stmt]); ...as well as any other of the range_query methods (range_on_edge, range_of_stmt, value_of_expr, value_on_edge, value_on_stmt, etc). As per the API, range_of_expr will work on constants, SSA names, and anything we support in irange::supports_type_p(). For pointers, the interface is the same, so instead of: else if (POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_PTR_INFO (name)) { if (get_ptr_nonnull (name)) stuff(); } One can do: RANGE_QUERY (cfun)->range_of_expr (vr, name, [stmt]); if (vr.nonzero_p ()) stuff (); Along with this interface, we are providing a mechanism by which a pass can use an on-demand ranger transparently, without having to change its code. Of course, this assumes all get_range_info() and get_ptr_nonnull() users have been converted to the new API, which follow-up patches will do. If a pass would prefer to use an on-demand ranger with finer grained and context aware ranges, all it would have to do is call enable_ranger() at the beginning of the pass, and disable_ranger() at the end of the pass. Note, that to use context aware ranges, any user of range_of_expr() would need to pass additional context. For example, the optional gimple statement (or perhaps use range_on_edge or range_of_stmt). The observant reader will note that RANGE_QUERY is tied to cfun, which may not be available in certain contexts, such as at RTL time, gimple-fold, or some other places where we may or may not have cfun set. For cases where we are sure there is no cfun, you can use GLOBAL_RANGE_QUERY instead of RANGE_QUERY(cfun). The API is the same. For cases where a function may be called with or without a function, you could use the following idiom: range_query *query = cfun ? RANGE_QUERY (cfun) : GLOBAL_RANGE_QUERY; query->range_of_expr (range, expr, [stmt]); By default RANGE_QUERY uses GLOBAL_RANGE_QUERY, unless the user has enabled an on-demand ranger with enable_ranger(), in which case it will use the currently active ranger. That is, until disable_ranger() is called, at which point, we revert back to GLOBAL_RANGE_QUERY. We think this provides a generic way of accessing ranges, both globally and locally, without having to keep track of types, SSA_NAME_RANGE_INFO, and SSA_NAME_PTR_INFO. We also hope this can be used to transition passes from global to on-demand ranges when appropriate. Tested on x86-64 Linux. OK? gcc/ChangeLog: * function.c (allocate_struct_function): Set cfun->x_range_query. * function.h (struct function): Declare x_range_query. (RANGE_QUERY): New. (get_global_range_query): New. (GLOBAL_RANGE_QUERY): New. * gimple-range-cache.cc (ssa_global_cache::ssa_global_cache): Remove call to safe_grow_cleared. * gimple-range.cc (get_range_global): New. (gimple_range_global): Move from gimple-range.h. (get_global_range_query): New. (global_range_query::range_of_expr): New. (enable_ranger): New. (disable_ranger): New. * gimple-range.h (gimple_range_global): Move to gimple-range.cc. (class global_range_query): New. (enable_ranger): New. (disable_ranger): New. * gimple-ssa-evrp.c (evrp_folder::~evrp_folder): Rename dump_all_value_ranges to dump. * tree-vrp.c (vrp_prop::finalize): Same. * value-query.cc (range_query::dump): New. * value-query.h (range_query::dump): New. * vr-values.c (vr_values::dump_all_value_ranges): Rename to... (vr_values::dump): ...this. * vr-values.h (class vr_values): Rename dump_all_value_ranges to dump and make virtual. --- gcc/function.c | 4 ++ gcc/function.h | 16 +++++ gcc/gimple-range-cache.cc | 1 - gcc/gimple-range.cc | 130 ++++++++++++++++++++++++++++++++++++++ gcc/gimple-range.h | 60 +++++------------- gcc/gimple-ssa-evrp.c | 2 +- gcc/tree-vrp.c | 2 +- gcc/value-query.cc | 5 ++ gcc/value-query.h | 1 + gcc/vr-values.c | 2 +- gcc/vr-values.h | 2 +- 11 files changed, 175 insertions(+), 50 deletions(-) diff --git a/gcc/function.c b/gcc/function.c index fc7b147b5f1..67576950983 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "options.h" #include "function-abi.h" +#include "value-range.h" +#include "gimple-range.h" /* So we can assign to cfun in this file. */ #undef cfun @@ -4856,6 +4858,8 @@ allocate_struct_function (tree fndecl, bool abstract_p) binding annotations among them. */ cfun->debug_nonbind_markers = lang_hooks.emits_begin_stmt && MAY_HAVE_DEBUG_MARKER_STMTS; + + cfun->x_range_query = &global_ranges; } /* This is like allocate_struct_function, but pushes a new cfun for FNDECL diff --git a/gcc/function.h b/gcc/function.h index 66cfa973808..41b446bfe7c 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -157,6 +157,7 @@ struct GTY(()) rtl_eh { struct gimple_df; struct call_site_record_d; struct dw_fde_node; +class range_query; struct GTY(()) varasm_status { /* If we're using a per-function constant pool, this is it. */ @@ -309,6 +310,11 @@ struct GTY(()) function { debugging is enabled. */ struct dw_fde_node *fde; + /* Range query mechanism for functions. The default is to pick up + global ranges. If a pass wants on-demand ranges OTOH, it must + call enable/disable_ranger(). */ + range_query * GTY ((skip)) x_range_query; + /* Last statement uid. */ int last_stmt_uid; @@ -712,4 +718,14 @@ extern const char *current_function_name (void); extern void used_types_insert (tree); +extern range_query *get_global_range_query (); + +// Returns the currently active range access class. This is meant to be used +// with the `class range_query' API. When there is no active range class, +// global ranges are used. +#define RANGE_QUERY(fun) (fun)->x_range_query + +// As above, but for accessing global ranges between passes. +#define GLOBAL_RANGE_QUERY get_global_range_query () + #endif /* GCC_FUNCTION_H */ diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 2c922e32913..c645d15f5af 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -384,7 +384,6 @@ block_range_cache::dump (FILE *f, basic_block bb, bool print_varying) ssa_global_cache::ssa_global_cache () { m_tab.create (0); - m_tab.safe_grow_cleared (num_ssa_names); m_irange_allocator = new irange_allocator; } diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 710bc7f9632..4e1aeee8ed0 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1402,3 +1402,133 @@ trace_ranger::range_of_expr (irange &r, tree name, gimple *s) return trailer (idx, "range_of_expr", res, name, r); } + +// Return the legacy global range for NAME if it has one, otherwise +// return VARYING. + +static void +get_range_global (irange &r, tree name) +{ + tree type = TREE_TYPE (name); + + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + tree sym = SSA_NAME_VAR (name); + // Adapted from vr_values::get_lattice_entry(). + // Use a range from an SSA_NAME's available range. + if (TREE_CODE (sym) == PARM_DECL) + { + // Try to use the "nonnull" attribute to create ~[0, 0] + // anti-ranges for pointers. Note that this is only valid with + // default definitions of PARM_DECLs. + if (POINTER_TYPE_P (type) + && ((cfun && nonnull_arg_p (sym)) || get_ptr_nonnull (name))) + r.set_nonzero (type); + else if (INTEGRAL_TYPE_P (type)) + { + get_range_info (name, r); + if (r.undefined_p ()) + r.set_varying (type); + } + else + r.set_varying (type); + } + // If this is a local automatic with no definition, use undefined. + else if (TREE_CODE (sym) != RESULT_DECL) + r.set_undefined (); + else + r.set_varying (type); + } + else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name)) + { + get_range_info (name, r); + if (r.undefined_p ()) + r.set_varying (type); + } + else if (POINTER_TYPE_P (type) && SSA_NAME_PTR_INFO (name)) + { + if (get_ptr_nonnull (name)) + r.set_nonzero (type); + else + r.set_varying (type); + } + else + r.set_varying (type); +} + +// ?? Like above, but only for default definitions of NAME. This is +// so VRP passes using ranger do not start with known ranges, +// otherwise we'd eliminate builtin_unreachables too early because of +// inlining. +// +// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has +// all of its unreachable calls removed too early. We should +// investigate whether we should just adjust the test above. + +value_range +gimple_range_global (tree name) +{ + gcc_checking_assert (gimple_range_ssa_p (name)); + tree type = TREE_TYPE (name); + + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + value_range vr; + get_range_global (vr, name); + return vr; + } + return value_range (type); +} + +// ---------------------------------------------- +// global_range_query implementation. + +global_range_query global_ranges; + +range_query * +get_global_range_query () +{ + if (cfun) + return RANGE_QUERY (cfun); + + return &global_ranges; +} + +bool +global_range_query::range_of_expr (irange &r, tree expr, gimple *) +{ + tree type = TREE_TYPE (expr); + + if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr)) + return get_tree_range (r, expr); + + get_range_global (r, expr); + + return true; +} + +void +enable_ranger () +{ + gimple_ranger *r; + + if (param_evrp_mode & EVRP_MODE_TRACE) + r = new trace_ranger; + else + r = new gimple_ranger; + + RANGE_QUERY (cfun) = r; +} + +void +disable_ranger (bool export_ranges) +{ + gimple_ranger *r = (gimple_ranger *) RANGE_QUERY (cfun); + + if (export_ranges) + r->export_global_ranges (); + + delete r; + + RANGE_QUERY (cfun) = &global_ranges; +} diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index f33156181bf..1ba073820a6 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -53,7 +53,7 @@ public: virtual void range_on_entry (irange &r, basic_block bb, tree name); virtual void range_on_exit (irange &r, basic_block bb, tree name); void export_global_ranges (); - void dump (FILE *f); + virtual void dump (FILE *f) OVERRIDE; protected: bool calc_stmt (irange &r, gimple *s, tree name = NULL_TREE); bool range_of_range_op (irange &r, gimple *s); @@ -130,50 +130,6 @@ range_compatible_p (tree type1, tree type2) && TYPE_SIGN (type1) == TYPE_SIGN (type2)); } -// Return the legacy GCC global range for NAME if it has one, otherwise -// return VARYING. - -static inline value_range -gimple_range_global (tree name) -{ - gcc_checking_assert (gimple_range_ssa_p (name)); - tree type = TREE_TYPE (name); - - if (SSA_NAME_IS_DEFAULT_DEF (name)) - { - tree sym = SSA_NAME_VAR (name); - // Adapted from vr_values::get_lattice_entry(). - // Use a range from an SSA_NAME's available range. - if (TREE_CODE (sym) == PARM_DECL) - { - // Try to use the "nonnull" attribute to create ~[0, 0] - // anti-ranges for pointers. Note that this is only valid with - // default definitions of PARM_DECLs. - if (POINTER_TYPE_P (type) - && (nonnull_arg_p (sym) || get_ptr_nonnull (name))) - { - value_range r; - r.set_nonzero (type); - return r; - } - else if (INTEGRAL_TYPE_P (type)) - { - value_range r; - get_range_info (name, r); - if (r.undefined_p ()) - r.set_varying (type); - return r; - } - } - // If this is a local automatic with no definition, use undefined. - else if (TREE_CODE (sym) != RESULT_DECL) - return value_range (); - } - // Otherwise return range for the type. - return value_range (type); -} - - // This class overloads the ranger routines to provide tracing facilties // Entry and exit values to each of the APIs is placed in the dumpfile. @@ -202,4 +158,18 @@ private: // Temporary external interface to share with vr_values. bool range_of_builtin_call (range_query &query, irange &r, gcall *call); +// Global ranges for SSA names using SSA_NAME_RANGE_INFO. + +class global_range_query : public range_query +{ +public: + bool range_of_expr (irange &r, tree expr, gimple * = NULL) OVERRIDE; +}; + +extern global_range_query global_ranges; +extern value_range gimple_range_global (tree name); + +extern void enable_ranger (); +extern void disable_ranger (bool export_ranges = true); + #endif // GCC_GIMPLE_RANGE_STMT_H diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 5f566ae0958..829fdcdaef2 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -60,7 +60,7 @@ public: if (dump_file) { fprintf (dump_file, "\nValue ranges after Early VRP:\n\n"); - m_range_analyzer.dump_all_value_ranges (dump_file); + m_range_analyzer.dump (dump_file); fprintf (dump_file, "\n"); } } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 12e6e6f3e22..b0f1c47f05c 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4044,7 +4044,7 @@ vrp_prop::finalize () if (dump_file) { fprintf (dump_file, "\nValue ranges after VRP:\n\n"); - m_vr_values->dump_all_value_ranges (dump_file); + m_vr_values->dump (dump_file); fprintf (dump_file, "\n"); } diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 4bb0897c446..509d2d33cc5 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -135,6 +135,11 @@ range_query::value_of_stmt (gimple *stmt, tree name) } +void +range_query::dump (FILE *) +{ +} + // valuation_query support routines for value_range_equiv's. class equiv_allocator : public object_allocator diff --git a/gcc/value-query.h b/gcc/value-query.h index e2cbc6852b0..5eff9317ed5 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -95,6 +95,7 @@ public: // rewrite all uses of it to the above API. virtual const class value_range_equiv *get_value_range (const_tree, gimple * = NULL); + virtual void dump (FILE *); protected: class value_range_equiv *allocate_value_range_equiv (); diff --git a/gcc/vr-values.c b/gcc/vr-values.c index b1bf53af9e0..a89f0b646ae 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1819,7 +1819,7 @@ vr_values::adjust_range_with_scev (value_range_equiv *vr, class loop *loop, /* Dump value ranges of all SSA_NAMEs to FILE. */ void -vr_values::dump_all_value_ranges (FILE *file) +vr_values::dump (FILE *file) { size_t i; diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 8c1b2e0a292..81b9131f7f1 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -116,7 +116,7 @@ class vr_values : public range_query tree op_with_constant_singleton_value_range (tree); void adjust_range_with_scev (value_range_equiv *, class loop *, gimple *, tree); - void dump_all_value_ranges (FILE *); + virtual void dump (FILE *) OVERRIDE; void extract_range_for_var_from_comparison_expr (tree, enum tree_code, tree, tree, From patchwork Fri May 21 11:39:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1482190 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=S61zRote; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FmlND3WBtz9sV5 for ; Fri, 21 May 2021 21:52:43 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9FD49384783C; Fri, 21 May 2021 11:52:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9FD49384783C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1621597959; bh=BWkUvIKyOA1nPnHLDpnXLdYRsg9t3ShCKmWK9fpgsC0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=S61zRotejsRF7IfpOyuHrfGjAdnjZHApDujC3oVAPFfmtKiHnAeLT4JBJ4OELZx1E lisnpllUOCYj73ocBJTYQjdad+MehBrp/VjA9d3msMNQjx6doKE5mUIrQHIETAz2fn txYyC1tYamd84pDnXiqsuTsKHRU49eXg4/h4Urq0= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id E7E273847810 for ; Fri, 21 May 2021 11:52:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E7E273847810 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-140-JW-0QjS3NPmxLhMNGOCyuQ-1; Fri, 21 May 2021 07:52:34 -0400 X-MC-Unique: JW-0QjS3NPmxLhMNGOCyuQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4B4AF100945E; Fri, 21 May 2021 11:52:33 +0000 (UTC) Received: from abulafia.quesejoda.com (ovpn-113-127.ams2.redhat.com [10.36.113.127]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D616B5C1C4; Fri, 21 May 2021 11:52:32 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.16.1/8.15.2) with ESMTPS id 14LBqUle1148419 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 21 May 2021 13:52:31 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.16.1/8.16.1/Submit) id 14LBqUep1148418; Fri, 21 May 2021 13:52:30 +0200 To: GCC patches , Andrew MacLeod Subject: [PATCH 2/5] Convert Walloca pass to RANGE_QUERY(cfun). Date: Fri, 21 May 2021 13:39:51 +0200 Message-Id: <20210521113954.1148075-2-aldyh@redhat.com> In-Reply-To: <20210521113954.1148075-1-aldyh@redhat.com> References: <20210521113954.1148075-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Cc: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch converts the Walloca pass to use an on-demand ranger accesible with RANGE_QUERY instead of having to create a ranger and pass it around. Tested on x86-64 Linux. OK? gcc/ChangeLog: * gimple-ssa-warn-alloca.c (alloca_call_type): Use RANGE_QUERY instead of query argument. (pass_walloca::execute): Enable and disable global ranger. --- gcc/gimple-ssa-warn-alloca.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c index e9a24d4d1d0..12f4bce3be8 100644 --- a/gcc/gimple-ssa-warn-alloca.c +++ b/gcc/gimple-ssa-warn-alloca.c @@ -165,7 +165,7 @@ adjusted_warn_limit (bool idx) // call was created by the gimplifier for a VLA. static class alloca_type_and_limit -alloca_call_type (range_query &query, gimple *stmt, bool is_vla) +alloca_call_type (gimple *stmt, bool is_vla) { gcc_assert (gimple_alloca_call_p (stmt)); tree len = gimple_call_arg (stmt, 0); @@ -217,7 +217,7 @@ alloca_call_type (range_query &query, gimple *stmt, bool is_vla) int_range_max r; if (warn_limit_specified_p (is_vla) && TREE_CODE (len) == SSA_NAME - && query.range_of_expr (r, len, stmt) + && RANGE_QUERY (cfun)->range_of_expr (r, len, stmt) && !r.varying_p ()) { // The invalid bits are anything outside of [0, MAX_SIZE]. @@ -256,7 +256,7 @@ in_loop_p (gimple *stmt) unsigned int pass_walloca::execute (function *fun) { - gimple_ranger ranger; + enable_ranger (); basic_block bb; FOR_EACH_BB_FN (bb, fun) { @@ -290,7 +290,7 @@ pass_walloca::execute (function *fun) continue; class alloca_type_and_limit t - = alloca_call_type (ranger, stmt, is_vla); + = alloca_call_type (stmt, is_vla); unsigned HOST_WIDE_INT adjusted_alloca_limit = adjusted_warn_limit (false); @@ -383,6 +383,7 @@ pass_walloca::execute (function *fun) } } } + disable_ranger (); return 0; } From patchwork Fri May 21 11:39:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1482192 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=i7P/EIYC; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FmlNT0ZTkz9sVt for ; Fri, 21 May 2021 21:52:57 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AD867398B870; Fri, 21 May 2021 11:52:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AD867398B870 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1621597961; bh=W8NuFH3ybScuVq5MtygSNDW7QAE2rMhOF2wEPT/wY/k=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=i7P/EIYCDYfjiyl9XwukkyQkuioUk+xHyJnYXkh4+Td9WqbZ+/RDLdv50EysKpdV7 PmmkdyuKvrcKPowYxdeAz5P69ueXoXFbpwVKfCHFw1t4Z9+IbyrOq0mpuTrpvi4j2E +9JkXIuMXL5fD4K5Zdrv/oqfCIk1M+6Qis71qW78= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id C3DB53847810 for ; Fri, 21 May 2021 11:52:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C3DB53847810 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-368-8IEQt4ENNmWVQBrcdnGcIA-1; Fri, 21 May 2021 07:52:35 -0400 X-MC-Unique: 8IEQt4ENNmWVQBrcdnGcIA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DE308801106; Fri, 21 May 2021 11:52:34 +0000 (UTC) Received: from abulafia.quesejoda.com (ovpn-113-127.ams2.redhat.com [10.36.113.127]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7DB965D9D5; Fri, 21 May 2021 11:52:34 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.16.1/8.15.2) with ESMTPS id 14LBqWBX1148423 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 21 May 2021 13:52:32 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.16.1/8.16.1/Submit) id 14LBqWAw1148422; Fri, 21 May 2021 13:52:32 +0200 To: GCC patches , Andrew MacLeod Subject: [PATCH 3/5] Convert evrp pass to RANGE_QUERY(cfun). Date: Fri, 21 May 2021 13:39:52 +0200 Message-Id: <20210521113954.1148075-3-aldyh@redhat.com> In-Reply-To: <20210521113954.1148075-1-aldyh@redhat.com> References: <20210521113954.1148075-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Cc: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Some tests required tweaking, as exporting global ranges from evrp will now provide better ranges for subsequent passes. Tested on x86-64 Linux. OK? gcc/ChangeLog: * gimple-ssa-evrp.c (rvrp_folder): Call enable_ranger. Use RANGE_QUERY. (~rvrp_folder): Call disable_ranger. (hybrid_folder::value_of_expr): Use global ranger. (hybrid_folder::value_on_edge): Same. (hybrid_folder::value_of_stmt): Same. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-55.c: Remove xfail. * gcc.dg/pr80776-1.c: Same. --- gcc/gimple-ssa-evrp.c | 43 +++++++++----------- gcc/testsuite/gcc.dg/Wstringop-overflow-55.c | 8 ++-- gcc/testsuite/gcc.dg/pr80776-1.c | 4 +- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 829fdcdaef2..bd4c7634b3e 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -117,34 +117,33 @@ class rvrp_folder : public substitute_and_fold_engine public: rvrp_folder () : substitute_and_fold_engine (), m_simplifier () - { - if (param_evrp_mode & EVRP_MODE_TRACE) - m_ranger = new trace_ranger (); - else - m_ranger = new gimple_ranger (); - m_simplifier.set_range_query (m_ranger); + { + enable_ranger (); + + m_simplifier.set_range_query (RANGE_QUERY (cfun)); } ~rvrp_folder () { if (dump_file && (dump_flags & TDF_DETAILS)) - m_ranger->dump (dump_file); - delete m_ranger; + RANGE_QUERY (cfun)->dump (dump_file); + + disable_ranger (); } tree value_of_expr (tree name, gimple *s = NULL) OVERRIDE { - return m_ranger->value_of_expr (name, s); + return RANGE_QUERY (cfun)->value_of_expr (name, s); } tree value_on_edge (edge e, tree name) OVERRIDE { - return m_ranger->value_on_edge (e, name); + return RANGE_QUERY (cfun)->value_on_edge (e, name); } tree value_of_stmt (gimple *s, tree name = NULL) OVERRIDE { - return m_ranger->value_of_stmt (s, name); + return RANGE_QUERY (cfun)->value_of_stmt (s, name); } bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE @@ -154,7 +153,6 @@ public: private: DISABLE_COPY_AND_ASSIGN (rvrp_folder); - gimple_ranger *m_ranger; simplify_using_ranges m_simplifier; }; @@ -175,19 +173,16 @@ class hybrid_folder : public evrp_folder public: hybrid_folder (bool evrp_first) { - if (param_evrp_mode & EVRP_MODE_TRACE) - m_ranger = new trace_ranger (); - else - m_ranger = new gimple_ranger (); + enable_ranger (); if (evrp_first) { first = &m_range_analyzer; - second = m_ranger; + second = RANGE_QUERY (cfun); } else { - first = m_ranger; + first = RANGE_QUERY (cfun); second = &m_range_analyzer; } } @@ -195,8 +190,9 @@ public: ~hybrid_folder () { if (dump_file && (dump_flags & TDF_DETAILS)) - m_ranger->dump (dump_file); - delete m_ranger; + RANGE_QUERY (cfun)->dump (dump_file); + + disable_ranger (); } bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE @@ -221,7 +217,6 @@ public: private: DISABLE_COPY_AND_ASSIGN (hybrid_folder); - gimple_ranger *m_ranger; range_query *first; range_query *second; tree choose_value (tree evrp_val, tree ranger_val); @@ -232,7 +227,7 @@ tree hybrid_folder::value_of_expr (tree op, gimple *stmt) { tree evrp_ret = evrp_folder::value_of_expr (op, stmt); - tree ranger_ret = m_ranger->value_of_expr (op, stmt); + tree ranger_ret = RANGE_QUERY (cfun)->value_of_expr (op, stmt); return choose_value (evrp_ret, ranger_ret); } @@ -242,7 +237,7 @@ hybrid_folder::value_on_edge (edge e, tree op) // Call evrp::value_of_expr directly. Otherwise another dual call is made // via hybrid_folder::value_of_expr, but without an edge. tree evrp_ret = evrp_folder::value_of_expr (op, NULL); - tree ranger_ret = m_ranger->value_on_edge (e, op); + tree ranger_ret = RANGE_QUERY (cfun)->value_on_edge (e, op); return choose_value (evrp_ret, ranger_ret); } @@ -257,7 +252,7 @@ hybrid_folder::value_of_stmt (gimple *stmt, tree op) else evrp_ret = NULL_TREE; - tree ranger_ret = m_ranger->value_of_stmt (stmt, op); + tree ranger_ret = RANGE_QUERY (cfun)->value_of_stmt (stmt, op); return choose_value (evrp_ret, ranger_ret); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index 25f5b82d9be..8df5cb629ae 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -66,7 +66,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -74,7 +74,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } @@ -83,7 +83,7 @@ void warn_int_anti_range (int i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -91,7 +91,7 @@ void warn_int_anti_range (int i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index af41c0c2ffa..f3a120b6744 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,7 +17,5 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - /* The correctness bits for [E]VRP cannot handle chained conditionals - when deciding to ignore a unreachable branch for setting SSA range info. */ - sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ } From patchwork Fri May 21 11:39:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1482194 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=DnruyzjN; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FmlNb2rBJz9sV5 for ; Fri, 21 May 2021 21:53:03 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 06EE03847828; Fri, 21 May 2021 11:52:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 06EE03847828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1621597967; bh=UBupb4C3ZmevZvJ3wExKEhalqGhkeZyCQjp0I7kVX48=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=DnruyzjNFViKzPG3AbNbrkBeOI0vZgB1O+D9C/Q508AM1KOvKjVYR5z5tpaLnJbcT sJawmj6mgA9a8ZG7JHmdmUWZrtZEjyngbcjZcAYyxDRmOo4VZPzfpxAmWWyPeGOgeZ pofE5t0INUjE4MGPMmKbtVyMcac2AmQPU6gxVT0s= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id AEBCA3847810 for ; Fri, 21 May 2021 11:52:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org AEBCA3847810 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-175-jijmv94jO-GqMH77ylvUOA-1; Fri, 21 May 2021 07:52:37 -0400 X-MC-Unique: jijmv94jO-GqMH77ylvUOA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 11D0C180FD6B; Fri, 21 May 2021 11:52:36 +0000 (UTC) Received: from abulafia.quesejoda.com (ovpn-113-127.ams2.redhat.com [10.36.113.127]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 38479421F; Fri, 21 May 2021 11:52:35 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.16.1/8.15.2) with ESMTPS id 14LBqXeh1148428 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 21 May 2021 13:52:33 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.16.1/8.16.1/Submit) id 14LBqXnP1148427; Fri, 21 May 2021 13:52:33 +0200 To: GCC patches , Andrew MacLeod Subject: [PATCH 4/5] Convert remaining passes to RANGE_QUERY. Date: Fri, 21 May 2021 13:39:53 +0200 Message-Id: <20210521113954.1148075-4-aldyh@redhat.com> In-Reply-To: <20210521113954.1148075-1-aldyh@redhat.com> References: <20210521113954.1148075-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Cc: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch converts the remaining users of get_range_info and get_ptr_nonnull to the range_query API. No effort was made to move passes away from VR_ANTI_RANGE, or any other use of deprecated methods. This was a straight up conversion to the new API, nothing else. Tested on x86-64 Linux. OK? gcc/ChangeLog: * builtins.c (check_nul_terminated_array): Convert to RANGE_QUERY. (expand_builtin_strnlen): Same. (determine_block_size): Same. * fold-const.c (expr_not_equal_to): Same. * gimple-fold.c (size_must_be_zero_p): Same. * gimple-match-head.c: Include gimple-range.h. * gimple-pretty-print.c (dump_ssaname_info): Convert to RANGE_QUERY. * gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): Same. * graphite-sese-to-poly.c (add_param_constraints): Same. * internal-fn.c (get_min_precision): Same. * ipa-fnsummary.c (set_switch_stmt_execution_predicate): Same. * ipa-prop.c (ipa_compute_jump_functions_for_edge): Same. * match.pd: Same. * tree-data-ref.c (split_constant_offset): Same. (dr_step_indicator): Same. * tree-dfa.c (get_ref_base_and_extent): Same. * tree-scalar-evolution.c (iv_can_overflow_p): Same. * tree-ssa-loop-niter.c (refine_value_range_using_guard): Same. (determine_value_range): Same. (record_nonwrapping_iv): Same. (infer_loop_bounds_from_signedness): Same. (scev_var_range_cant_overflow): Same. * tree-ssa-phiopt.c (two_value_replacement): Same. * tree-ssa-pre.c (insert_into_preds_of_block): Same. * tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Same. * tree-ssa-strlen.c (handle_builtin_stxncpy_strncat): Same. (get_range): Same. (dump_strlen_info): Same. (set_strlen_range): Same. (maybe_diag_stxncpy_trunc): Same. (get_len_or_size): Same. (handle_integral_assign): Same. * tree-ssa-structalias.c (find_what_p_points_to): Same. * tree-ssa-uninit.c (find_var_cmp_const): Same. * tree-switch-conversion.c (bit_test_cluster::emit): Same. * tree-vect-patterns.c (vect_get_range_info): Same. (vect_recog_divmod_pattern): Same. * tree-vrp.c (intersect_range_with_nonzero_bits): Same. (register_edge_assert_for_2): Same. (determine_value_range_1): Same. * tree.c (get_range_pos_neg): Same. * vr-values.c (vr_values::get_lattice_entry): Same. (vr_values::update_value_range): Same. (simplify_conversion_using_ranges): Same. --- gcc/builtins.c | 40 ++++++++++------ gcc/fold-const.c | 8 +++- gcc/gimple-fold.c | 7 ++- gcc/gimple-match-head.c | 1 + gcc/gimple-pretty-print.c | 12 ++++- gcc/gimple-ssa-warn-restrict.c | 8 +++- gcc/graphite-sese-to-poly.c | 9 +++- gcc/internal-fn.c | 14 +++--- gcc/ipa-fnsummary.c | 11 ++++- gcc/ipa-prop.c | 16 +++---- gcc/match.pd | 19 ++++++-- gcc/tree-data-ref.c | 24 ++++++++-- gcc/tree-dfa.c | 14 +++++- gcc/tree-scalar-evolution.c | 13 +++++- gcc/tree-ssa-loop-niter.c | 81 +++++++++++++++++++++----------- gcc/tree-ssa-phiopt.c | 11 ++++- gcc/tree-ssa-pre.c | 19 ++++---- gcc/tree-ssa-reassoc.c | 9 ++-- gcc/tree-ssa-strlen.c | 85 ++++++++++++++++++++-------------- gcc/tree-ssa-structalias.c | 8 ++-- gcc/tree-ssa-uninit.c | 8 +++- gcc/tree-switch-conversion.c | 10 ++-- gcc/tree-vect-patterns.c | 18 +++++-- gcc/tree-vrp.c | 21 ++++----- gcc/tree.c | 13 +++--- gcc/vr-values.c | 12 +++-- 26 files changed, 332 insertions(+), 159 deletions(-) diff --git a/gcc/builtins.c b/gcc/builtins.c index e1b284846b1..deb7c083315 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-outof-ssa.h" #include "attr-fnspec.h" #include "demangle.h" +#include "gimple-range.h" struct target_builtins default_target_builtins; #if SWITCHABLE_TARGET @@ -1214,14 +1215,15 @@ check_nul_terminated_array (tree expr, tree src, wide_int bndrng[2]; if (bound) { - if (TREE_CODE (bound) == INTEGER_CST) - bndrng[0] = bndrng[1] = wi::to_wide (bound); - else - { - value_range_kind rng = get_range_info (bound, bndrng, bndrng + 1); - if (rng != VR_RANGE) - return true; - } + value_range r; + + GLOBAL_RANGE_QUERY->range_of_expr (r, bound); + + if (r.kind () != VR_RANGE) + return true; + + bndrng[0] = r.lower_bound (); + bndrng[1] = r.upper_bound (); if (exact) { @@ -3827,9 +3829,12 @@ expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode) return NULL_RTX; wide_int min, max; - enum value_range_kind rng = get_range_info (bound, &min, &max); - if (rng != VR_RANGE) + value_range r; + GLOBAL_RANGE_QUERY->range_of_expr (r, bound); + if (r.kind () != VR_RANGE) return NULL_RTX; + min = r.lower_bound (); + max = r.upper_bound (); if (!len || TREE_CODE (len) != INTEGER_CST) { @@ -3897,7 +3902,16 @@ determine_block_size (tree len, rtx len_rtx, *probable_max_size = *max_size = GET_MODE_MASK (GET_MODE (len_rtx)); if (TREE_CODE (len) == SSA_NAME) - range_type = get_range_info (len, &min, &max); + { + value_range r; + GLOBAL_RANGE_QUERY->range_of_expr (r, len); + range_type = r.kind (); + if (range_type != VR_UNDEFINED) + { + min = wi::to_wide (r.min ()); + max = wi::to_wide (r.max ()); + } + } if (range_type == VR_RANGE) { if (wi::fits_uhwi_p (min) && *min_size < min.to_uhwi ()) @@ -4914,8 +4928,8 @@ check_read_access (tree exp, tree src, tree bound /* = NULL_TREE */, /* If STMT is a call to an allocation function, returns the constant maximum size of the object allocated by the call represented as sizetype. If nonnull, sets RNG1[] to the range of the size. - When nonnull, uses RVALS for range information, otherwise calls - get_range_info to get it. + When nonnull, uses RVALS for range information, otherwise gets global + range info. Returns null when STMT is not a call to a valid allocation function. */ tree diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5a41524702b..d680ba1442f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vector-builder.h" #include "vec-perm-indices.h" #include "asan.h" +#include "gimple-range.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -10686,7 +10687,12 @@ expr_not_equal_to (tree t, const wide_int &w) case SSA_NAME: if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) return false; - get_range_info (t, vr); + + if (cfun) + RANGE_QUERY (cfun)->range_of_expr (vr, t); + else + GLOBAL_RANGE_QUERY->range_of_expr (vr, t); + if (!vr.undefined_p () && !vr.contains_p (wide_int_to_tree (TREE_TYPE (t), w))) return true; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 68717cf1542..228fa1b357f 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -873,7 +873,12 @@ size_must_be_zero_p (tree size) value_range valid_range (build_int_cst (type, 0), wide_int_to_tree (type, ssize_max)); value_range vr; - get_range_info (size, vr); + if (cfun) + RANGE_QUERY (cfun)->range_of_expr (vr, size); + else + GLOBAL_RANGE_QUERY->range_of_expr (vr, size); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (size)); vr.intersect (&valid_range); return vr.zero_p (); } diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index b084a31572a..7112c116835 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "dbgcnt.h" #include "tm.h" +#include "gimple-range.h" /* Forward declarations of the private auto-generated matchers. They expect valueized operands in canonical order and do not diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 0ef01e6420b..62d895d1625 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "asan.h" #include "cfgloop.h" +#include "gimple-range.h" /* Disable warnings about quoting issues in the pp_xxx calls below that (intentionally) don't follow GCC diagnostic conventions. */ @@ -2263,8 +2264,17 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc) && SSA_NAME_RANGE_INFO (node)) { wide_int min, max, nonzero_bits; - value_range_kind range_type = get_range_info (node, &min, &max); + value_range r; + GLOBAL_RANGE_QUERY->range_of_expr (r, node); + value_range_kind range_type = r.kind (); + if (!r.undefined_p ()) + { + min = wi::to_wide (r.min ()); + max = wi::to_wide (r.max ()); + } + + // FIXME: Use irange::dump() instead. if (range_type == VR_VARYING) pp_printf (buffer, "# RANGE VR_VARYING"); else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE) diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index ad37f20afaa..a59731c2bc2 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -349,7 +349,13 @@ builtin_memref::extend_offset_range (tree offset) /* There is a global version here because check_bounds_or_overlap may be called from gimple fold during gimple lowering. */ - rng = get_range_info (offset, &min, &max); + RANGE_QUERY (cfun)->range_of_expr (vr, offset, stmt); + rng = vr.kind (); + if (!vr.undefined_p ()) + { + min = wi::to_wide (vr.min ()); + max = wi::to_wide (vr.max ()); + } } if (rng == VR_ANTI_RANGE && wi::lts_p (max, min)) { diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index eebf2e02cfc..2d332f69a92 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -418,13 +418,18 @@ static void add_param_constraints (scop_p scop, graphite_dim_t p, tree parameter) { tree type = TREE_TYPE (parameter); + value_range r; wide_int min, max; gcc_assert (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)); if (INTEGRAL_TYPE_P (type) - && get_range_info (parameter, &min, &max) == VR_RANGE) - ; + && RANGE_QUERY (cfun)->range_of_expr (r, parameter) + && !r.undefined_p ()) + { + min = r.lower_bound (); + max = r.upper_bound (); + } else { min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)); diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index d209a52f823..dd1f204863e 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "ssa-iterators.h" #include "explow.h" #include "rtl-iter.h" +#include "gimple-range.h" /* The names of each internal function, indexed by function number. */ const char *const internal_fn_name_array[] = { @@ -680,8 +681,9 @@ get_min_precision (tree arg, signop sign) } if (TREE_CODE (arg) != SSA_NAME) return prec + (orig_sign != sign); - wide_int arg_min, arg_max; - while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE) + value_range r; + while (!GLOBAL_RANGE_QUERY->range_of_expr (r, arg) + || r.kind () != VR_RANGE) { gimple *g = SSA_NAME_DEF_STMT (arg); if (is_gimple_assign (g) @@ -709,14 +711,14 @@ get_min_precision (tree arg, signop sign) } if (sign == TYPE_SIGN (TREE_TYPE (arg))) { - int p1 = wi::min_precision (arg_min, sign); - int p2 = wi::min_precision (arg_max, sign); + int p1 = wi::min_precision (r.lower_bound (), sign); + int p2 = wi::min_precision (r.upper_bound (), sign); p1 = MAX (p1, p2); prec = MIN (prec, p1); } - else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED)) + else if (sign == UNSIGNED && !wi::neg_p (r.lower_bound (), SIGNED)) { - int p = wi::min_precision (arg_max, UNSIGNED); + int p = wi::min_precision (r.upper_bound (), UNSIGNED); prec = MIN (prec, p); } return prec + (orig_sign != sign); diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 4e5be812734..299d7fc1f60 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "tree-into-ssa.h" #include "symtab-clones.h" +#include "gimple-range.h" /* Summaries. */ fast_function_summary *ipa_fn_summaries; @@ -1687,8 +1688,14 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, int bound_limit = opt_for_fn (fbi->node->decl, param_ipa_max_switch_predicate_bounds); int bound_count = 0; - wide_int vr_wmin, vr_wmax; - value_range_kind vr_type = get_range_info (op, &vr_wmin, &vr_wmax); + value_range vr; + + RANGE_QUERY (cfun)->range_of_expr (vr, op); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (op)); + value_range_kind vr_type = vr.kind (); + wide_int vr_wmin = wi::to_wide (vr.min ()); + wide_int vr_wmax = wi::to_wide (vr.max ()); FOR_EACH_EDGE (e, ei, bb->succs) { diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 0591ef1b569..02f422bdbf3 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see #include "options.h" #include "symtab-clones.h" #include "attr-fnspec.h" +#include "gimple-range.h" /* Function summary where the parameter infos are actually stored. */ ipa_node_params_t *ipa_node_params_sum = NULL; @@ -2237,6 +2238,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, gcall *call = cs->call_stmt; int n, arg_num = gimple_call_num_args (call); bool useful_context = false; + value_range vr; if (arg_num == 0 || args->jump_functions) return; @@ -2274,7 +2276,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, if (TREE_CODE (arg) == SSA_NAME && param_type - && get_ptr_nonnull (arg)) + && RANGE_QUERY (cfun)->range_of_expr (vr, arg) + && vr.nonzero_p ()) addr_nonzero = true; else if (tree_single_nonzero_warnv_p (arg, &strict_overflow)) addr_nonzero = true; @@ -2289,19 +2292,14 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, } else { - wide_int min, max; - value_range_kind kind; if (TREE_CODE (arg) == SSA_NAME && param_type - && (kind = get_range_info (arg, &min, &max)) - && (kind == VR_RANGE || kind == VR_ANTI_RANGE)) + && RANGE_QUERY (cfun)->range_of_expr (vr, arg) + && !vr.undefined_p ()) { value_range resvr; - value_range tmpvr (wide_int_to_tree (TREE_TYPE (arg), min), - wide_int_to_tree (TREE_TYPE (arg), max), - kind); range_fold_unary_expr (&resvr, NOP_EXPR, param_type, - &tmpvr, TREE_TYPE (arg)); + &vr, TREE_TYPE (arg)); if (!resvr.undefined_p () && !resvr.varying_p ()) ipa_set_jfunc_vr (jfunc, &resvr); else diff --git a/gcc/match.pd b/gcc/match.pd index cdb87636951..9dddf5ebd0a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -663,11 +663,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { bool overflowed = true; - wide_int wmin0, wmax0, wmin1, wmax1; + value_range vr0, vr1; if (INTEGRAL_TYPE_P (type) - && get_range_info (@0, &wmin0, &wmax0) == VR_RANGE - && get_range_info (@1, &wmin1, &wmax1) == VR_RANGE) + && GLOBAL_RANGE_QUERY->range_of_expr (vr0, @0) + && GLOBAL_RANGE_QUERY->range_of_expr (vr1, @1) + && vr0.kind () == VR_RANGE + && vr1.kind () == VR_RANGE) { + wide_int wmin0 = vr0.lower_bound (); + wide_int wmax0 = vr0.upper_bound (); + wide_int wmin1 = vr1.lower_bound (); + wide_int wmax1 = vr1.upper_bound (); /* If the multiplication can't overflow/wrap around, then it can be optimized too. */ wi::overflow_type min_ovf, max_ovf; @@ -2509,9 +2515,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type), TYPE_SIGN (inner_type)); - wide_int wmin0, wmax0; - if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE) + value_range vr; + if (GLOBAL_RANGE_QUERY->range_of_expr (vr, @0) + && vr.kind () == VR_RANGE) { + wide_int wmin0 = vr.lower_bound (); + wide_int wmax0 = vr.upper_bound (); wi::add (wmin0, w1, TYPE_SIGN (inner_type), &min_ovf); wi::add (wmax0, w1, TYPE_SIGN (inner_type), &max_ovf); } diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index e6dd5f15bed..5ba41e2c73d 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1035,14 +1035,23 @@ split_constant_offset (tree exp, tree *var, tree *off, value_range *exp_range, *exp_range = type; if (code == SSA_NAME) { - wide_int var_min, var_max; - value_range_kind vr_kind = get_range_info (exp, &var_min, &var_max); + value_range vr; + RANGE_QUERY (cfun)->range_of_expr (vr, exp); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (exp)); + wide_int var_min = wi::to_wide (vr.min ()); + wide_int var_max = wi::to_wide (vr.max ()); + value_range_kind vr_kind = vr.kind (); wide_int var_nonzero = get_nonzero_bits (exp); vr_kind = intersect_range_with_nonzero_bits (vr_kind, &var_min, &var_max, var_nonzero, TYPE_SIGN (type)); - if (vr_kind == VR_RANGE) + /* This check for VR_VARYING is here because the old code + using get_range_info would return VR_RANGE for the entire + domain, instead of VR_VARYING. The new code normalizes + full-domain ranges to VR_VARYING. */ + if (vr_kind == VR_RANGE || vr_kind == VR_VARYING) *exp_range = value_range (type, var_min, var_max); } } @@ -6298,12 +6307,19 @@ dr_step_indicator (struct data_reference *dr, int useful_min) /* Get the range of values that the unconverted step actually has. */ wide_int step_min, step_max; + value_range vr; if (TREE_CODE (step) != SSA_NAME - || get_range_info (step, &step_min, &step_max) != VR_RANGE) + || !RANGE_QUERY (cfun)->range_of_expr (vr, step) + || vr.kind () != VR_RANGE) { step_min = wi::to_wide (TYPE_MIN_VALUE (type)); step_max = wi::to_wide (TYPE_MAX_VALUE (type)); } + else + { + step_min = vr.lower_bound (); + step_max = vr.upper_bound (); + } /* Check whether the unconverted step has an acceptable range. */ signop sgn = TYPE_SIGN (type); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 0482b05e26c..e9cf4bfa706 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "gimple-walk.h" #include "tree-dfa.h" +#include "gimple-range.h" /* Build and maintain data flow information for trees. */ @@ -530,14 +531,23 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, index. */ seen_variable_array_ref = true; - wide_int min, max; + value_range vr; + range_query *query; + if (cfun) + query = RANGE_QUERY (cfun); + else + query = GLOBAL_RANGE_QUERY; + if (TREE_CODE (index) == SSA_NAME && (low_bound = array_ref_low_bound (exp), poly_int_tree_p (low_bound)) && (unit_size = array_ref_element_size (exp), TREE_CODE (unit_size) == INTEGER_CST) - && get_range_info (index, &min, &max) == VR_RANGE) + && query->range_of_expr (vr, index) + && vr.kind () == VR_RANGE) { + wide_int min = vr.lower_bound (); + wide_int max = vr.upper_bound (); poly_offset_int lbound = wi::to_poly_offset (low_bound); /* Try to constrain maxsize with range information. */ offset_int omax diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index ff052be1021..f0f28f26042 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -3039,18 +3039,27 @@ iv_can_overflow_p (class loop *loop, tree type, tree base, tree step) widest_int nit; wide_int base_min, base_max, step_min, step_max, type_min, type_max; signop sgn = TYPE_SIGN (type); + value_range r; if (integer_zerop (step)) return false; if (!INTEGRAL_TYPE_P (TREE_TYPE (base)) - || get_range_info (base, &base_min, &base_max) != VR_RANGE) + || !RANGE_QUERY (cfun)->range_of_expr (r, base) + || r.kind () != VR_RANGE) return true; + base_min = r.lower_bound (); + base_max = r.upper_bound (); + if (!INTEGRAL_TYPE_P (TREE_TYPE (step)) - || get_range_info (step, &step_min, &step_max) != VR_RANGE) + || !RANGE_QUERY (cfun)->range_of_expr (r, step) + || r.kind () != VR_RANGE) return true; + step_min = r.lower_bound (); + step_max = r.upper_bound (); + if (!get_max_loop_iterations (loop, &nit)) return true; diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 3817ec423e7..bfbb11c59c5 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-chrec.h" #include "tree-scalar-evolution.h" #include "tree-dfa.h" +#include "gimple-range.h" /* The maximum number of dominator BBs we search for conditions @@ -121,7 +122,6 @@ refine_value_range_using_guard (tree type, tree var, tree varc0, varc1, ctype; mpz_t offc0, offc1; mpz_t mint, maxt, minc1, maxc1; - wide_int minv, maxv; bool no_wrap = nowrap_type_p (type); bool c0_ok, c1_ok; signop sgn = TYPE_SIGN (type); @@ -221,6 +221,7 @@ refine_value_range_using_guard (tree type, tree var, get_type_static_bounds (type, mint, maxt); mpz_init (minc1); mpz_init (maxc1); + value_range r; /* Setup range information for varc1. */ if (integer_zerop (varc1)) { @@ -229,11 +230,12 @@ refine_value_range_using_guard (tree type, tree var, } else if (TREE_CODE (varc1) == SSA_NAME && INTEGRAL_TYPE_P (type) - && get_range_info (varc1, &minv, &maxv) == VR_RANGE) + && RANGE_QUERY (cfun)->range_of_expr (r, varc1) + && r.kind () == VR_RANGE) { - gcc_assert (wi::le_p (minv, maxv, sgn)); - wi::to_mpz (minv, minc1, sgn); - wi::to_mpz (maxv, maxc1, sgn); + gcc_assert (wi::le_p (r.lower_bound (), r.upper_bound (), sgn)); + wi::to_mpz (r.lower_bound (), minc1, sgn); + wi::to_mpz (r.upper_bound (), maxc1, sgn); } else { @@ -372,34 +374,50 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off, gphi_iterator gsi; /* Either for VAR itself... */ - rtype = get_range_info (var, &minv, &maxv); + value_range var_range; + RANGE_QUERY (cfun)->range_of_expr (var_range, var); + rtype = var_range.kind (); + if (!var_range.undefined_p ()) + { + minv = var_range.lower_bound (); + maxv = var_range.upper_bound (); + } + /* Or for PHI results in loop->header where VAR is used as PHI argument from the loop preheader edge. */ for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) { gphi *phi = gsi.phi (); - wide_int minc, maxc; + value_range phi_range; if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var - && (get_range_info (gimple_phi_result (phi), &minc, &maxc) - == VR_RANGE)) + && RANGE_QUERY (cfun)->range_of_expr (phi_range, + gimple_phi_result (phi)) + && phi_range.kind () == VR_RANGE) { if (rtype != VR_RANGE) { rtype = VR_RANGE; - minv = minc; - maxv = maxc; + minv = phi_range.lower_bound (); + maxv = phi_range.upper_bound (); } else { - minv = wi::max (minv, minc, sgn); - maxv = wi::min (maxv, maxc, sgn); + minv = wi::max (minv, phi_range.lower_bound (), sgn); + maxv = wi::min (maxv, phi_range.upper_bound (), sgn); /* If the PHI result range are inconsistent with the VAR range, give up on looking at the PHI results. This can happen if VR_UNDEFINED is involved. */ if (wi::gt_p (minv, maxv, sgn)) { - rtype = get_range_info (var, &minv, &maxv); + value_range vr; + RANGE_QUERY (cfun)->range_of_expr (vr, var); + rtype = vr.kind (); + if (!vr.undefined_p ()) + { + minv = vr.lower_bound (); + maxv = vr.upper_bound (); + } break; } } @@ -3545,12 +3563,16 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt, if (tree_int_cst_sign_bit (step)) { - wide_int min, max; + wide_int max; + value_range base_range; + if (RANGE_QUERY (cfun)->range_of_expr (base_range, orig_base) + && !base_range.undefined_p ()) + max = base_range.upper_bound (); extreme = fold_convert (unsigned_type, low); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (high) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (orig_base)) - && (get_range_info (orig_base, &min, &max) == VR_RANGE + && (base_range.kind () == VR_RANGE || get_cst_init_from_scev (orig_base, &max, false)) && wi::gts_p (wi::to_wide (high), max)) base = wide_int_to_tree (unsigned_type, max); @@ -3563,12 +3585,16 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt, } else { - wide_int min, max; + wide_int min; + value_range base_range; + if (RANGE_QUERY (cfun)->range_of_expr (base_range, orig_base) + && !base_range.undefined_p ()) + min = base_range.lower_bound (); extreme = fold_convert (unsigned_type, high); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (low) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (orig_base)) - && (get_range_info (orig_base, &min, &max) == VR_RANGE + && (base_range.kind () == VR_RANGE || get_cst_init_from_scev (orig_base, &min, true)) && wi::gts_p (min, wi::to_wide (low))) base = wide_int_to_tree (unsigned_type, min); @@ -3835,11 +3861,12 @@ infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt) low = lower_bound_in_type (type, type); high = upper_bound_in_type (type, type); - wide_int minv, maxv; - if (get_range_info (def, &minv, &maxv) == VR_RANGE) + value_range r; + RANGE_QUERY (cfun)->range_of_expr (r, def); + if (r.kind () == VR_RANGE) { - low = wide_int_to_tree (type, minv); - high = wide_int_to_tree (type, maxv); + low = wide_int_to_tree (type, r.lower_bound ()); + high = wide_int_to_tree (type, r.upper_bound ()); } record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true); @@ -4873,7 +4900,6 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop) { tree type; wide_int minv, maxv, diff, step_wi; - enum value_range_kind rtype; if (TREE_CODE (step) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (var))) return false; @@ -4884,8 +4910,9 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop) if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb)) return false; - rtype = get_range_info (var, &minv, &maxv); - if (rtype != VR_RANGE) + value_range r; + RANGE_QUERY (cfun)->range_of_expr (r, var); + if (r.kind () != VR_RANGE) return false; /* VAR is a scev whose evolution part is STEP and value range info @@ -4899,11 +4926,11 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop) type = TREE_TYPE (var); if (tree_int_cst_sign_bit (step)) { - diff = minv - wi::to_wide (lower_bound_in_type (type, type)); + diff = r.lower_bound () - wi::to_wide (lower_bound_in_type (type, type)); step_wi = - step_wi; } else - diff = wi::to_wide (upper_bound_in_type (type, type)) - maxv; + diff = wi::to_wide (upper_bound_in_type (type, type)) - r.upper_bound (); return (wi::geu_p (diff, step_wi)); } diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 8e8a08bc679..d464c84f164 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "gimple-fold.h" #include "internal-fn.h" +#include "gimple-range.h" static unsigned int tree_ssa_phiopt_worker (bool, bool, bool); static bool two_value_replacement (basic_block, basic_block, edge, gphi *, @@ -684,7 +685,15 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb, return false; wide_int min, max; - if (get_range_info (lhs, &min, &max) != VR_RANGE) + value_range r; + RANGE_QUERY (cfun)->range_of_expr (r, lhs); + + if (r.kind () == VR_RANGE) + { + min = r.lower_bound (); + max = r.upper_bound (); + } + else { int prec = TYPE_PRECISION (TREE_TYPE (lhs)); signop sgn = TYPE_SIGN (TREE_TYPE (lhs)); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 2d22535af87..870d3cba9ff 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-dce.h" #include "tree-cfgcleanup.h" #include "alias.h" +#include "gimple-range.h" /* Even though this file is called tree-ssa-pre.c, we actually implement a bit more than just PRE here. All of them piggy-back @@ -3234,16 +3235,18 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, >= TYPE_PRECISION (TREE_TYPE (expr->u.nary->op[0]))) && SSA_NAME_RANGE_INFO (expr->u.nary->op[0])) { - wide_int min, max; - if (get_range_info (expr->u.nary->op[0], &min, &max) == VR_RANGE - && !wi::neg_p (min, SIGNED) - && !wi::neg_p (max, SIGNED)) + value_range r; + if (RANGE_QUERY (cfun)->range_of_expr (r, expr->u.nary->op[0]) + && r.kind () == VR_RANGE + && !wi::neg_p (r.lower_bound (), SIGNED) + && !wi::neg_p (r.upper_bound (), SIGNED)) /* Just handle extension and sign-changes of all-positive ranges. */ - set_range_info (temp, - SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]), - wide_int_storage::from (min, TYPE_PRECISION (type), + set_range_info (temp, VR_RANGE, + wide_int_storage::from (r.lower_bound (), + TYPE_PRECISION (type), TYPE_SIGN (type)), - wide_int_storage::from (max, TYPE_PRECISION (type), + wide_int_storage::from (r.upper_bound (), + TYPE_PRECISION (type), TYPE_SIGN (type))); } diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 32e1632705b..cc098369e2e 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "case-cfn-macros.h" #include "tree-ssa-reassoc.h" #include "tree-ssa-math-opts.h" +#include "gimple-range.h" /* This is a simple global reassociation pass. It is, in part, based on the LLVM pass of the same name (They do some things more/less @@ -3221,12 +3222,14 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length, amount, then we can merge the entry test in the bit test. In this case, if we would need otherwise 2 or more comparisons, then use the bit test; in the other cases, the threshold is 3 comparisons. */ - wide_int min, max; bool entry_test_needed; + value_range r; if (TREE_CODE (exp) == SSA_NAME - && get_range_info (exp, &min, &max) == VR_RANGE - && wi::leu_p (max - min, prec - 1)) + && RANGE_QUERY (cfun)->range_of_expr (r, exp) + && r.kind () == VR_RANGE + && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1)) { + wide_int min = r.lower_bound (); wide_int ilowi = wi::to_wide (lowi); if (wi::lt_p (min, ilowi, TYPE_SIGN (TREE_TYPE (lowi)))) { diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index c7b5e2c6e6b..2f85a609107 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -196,7 +196,7 @@ static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *); /* Sets MINMAX to either the constant value or the range VAL is in and returns either the constant value or VAL on success or null when the range couldn't be determined. Uses RVALS when nonnull - to determine the range, otherwise get_range_info. */ + to determine the range, otherwise uses global range info. */ tree get_range (tree val, gimple *stmt, wide_int minmax[2], @@ -211,9 +211,9 @@ get_range (tree val, gimple *stmt, wide_int minmax[2], if (TREE_CODE (val) != SSA_NAME) return NULL_TREE; + value_range vr; if (rvals && stmt) { - value_range vr; if (!rvals->range_of_expr (vr, val, stmt)) return NULL_TREE; value_range_kind rng = vr.kind (); @@ -225,7 +225,15 @@ get_range (tree val, gimple *stmt, wide_int minmax[2], return val; } - value_range_kind rng = get_range_info (val, minmax, minmax + 1); + // ?? This entire function should use RANGE_QUERY or GLOBAL_RANGE_QUERY, + // instead of doing something different for RVALS and global ranges. + + if (!GLOBAL_RANGE_QUERY->range_of_expr (vr, val) || vr.undefined_p ()) + return NULL_TREE; + + minmax[0] = wi::to_wide (vr.min ()); + minmax[1] = wi::to_wide (vr.max ()); + value_range_kind rng = vr.kind (); if (rng == VR_RANGE) /* This may be an inverted range whose MINMAX[1] < MINMAX[0]. */ return val; @@ -929,7 +937,17 @@ dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals) rng = VR_UNDEFINED; } else - rng = get_range_info (si->nonzero_chars, &min, &max); + { + value_range vr; + GLOBAL_RANGE_QUERY->range_of_expr (vr, + si->nonzero_chars); + rng = vr.kind (); + if (!vr.undefined_p ()) + { + min = wi::to_wide (vr.min ()); + max = wi::to_wide (vr.max ()); + } + } if (rng == VR_RANGE || rng == VR_ANTI_RANGE) { @@ -1809,18 +1827,17 @@ set_strlen_range (tree lhs, wide_int min, wide_int max, } else if (TREE_CODE (bound) == SSA_NAME) { - wide_int minbound, maxbound; - // FIXME: Use range_query instead of global ranges. - value_range_kind rng = get_range_info (bound, &minbound, &maxbound); - if (rng == VR_RANGE) + value_range r; + RANGE_QUERY (cfun)->range_of_expr (r, bound); + if (!r.undefined_p ()) { /* For a bound in a known range, adjust the range determined above as necessary. For a bound in some anti-range or in an unknown range, use the range determined by callers. */ - if (wi::ltu_p (minbound, min)) - min = minbound; - if (wi::ltu_p (maxbound, max)) - max = maxbound; + if (wi::ltu_p (r.lower_bound (), min)) + min = r.lower_bound (); + if (wi::ltu_p (r.upper_bound (), max)) + max = r.upper_bound (); } } } @@ -2780,12 +2797,15 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, return false; wide_int cntrange[2]; + value_range r; + if (!RANGE_QUERY (cfun)->range_of_expr (r, cnt) + || r.varying_p () + || r.undefined_p ()) + return false; - // FIXME: Use range_query instead of global ranges. - enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1); - if (rng == VR_RANGE) - ; - else if (rng == VR_ANTI_RANGE) + cntrange[0] = wi::to_wide (r.min ()); + cntrange[1] = wi::to_wide (r.max ()); + if (r.kind () == VR_ANTI_RANGE) { wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)); @@ -2800,8 +2820,6 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt))); } } - else - return false; /* Negative value is the constant string length. If it's less than the lower bound there is no truncation. Avoid calling get_stridx() @@ -3923,13 +3941,12 @@ get_len_or_size (gimple *stmt, tree arg, int idx, } else if (TREE_CODE (si->nonzero_chars) == SSA_NAME) { - wide_int min, max; - // FIXME: Use range_query instead of global ranges. - value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max); - if (rng == VR_RANGE) + value_range r; + RANGE_QUERY (cfun)->range_of_expr (r, si->nonzero_chars); + if (r.kind () == VR_RANGE) { - lenrng[0] = min.to_uhwi (); - lenrng[1] = max.to_uhwi (); + lenrng[0] = r.lower_bound ().to_uhwi (); + lenrng[1] = r.upper_bound ().to_uhwi (); *nulterm = si->full_string_p; } } @@ -5301,17 +5318,13 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh, /* Reading a character before the final '\0' character. Just set the value range to ~[0, 0] if we don't have anything better. */ - wide_int min, max; - signop sign = TYPE_SIGN (lhs_type); - int prec = TYPE_PRECISION (lhs_type); - // FIXME: Use range_query instead of global ranges. - value_range_kind vr = get_range_info (lhs, &min, &max); - if (vr == VR_VARYING - || (vr == VR_RANGE - && min == wi::min_value (prec, sign) - && max == wi::max_value (prec, sign))) - set_range_info (lhs, VR_ANTI_RANGE, - wi::zero (prec), wi::zero (prec)); + value_range r; + if (!RANGE_QUERY (cfun)->range_of_expr (r, lhs) + || r.varying_p ()) + { + r.set_nonzero (lhs_type); + set_range_info (lhs, r); + } } } } diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index a0238710e72..514cec1d927 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -43,6 +43,7 @@ #include "attribs.h" #include "tree-ssa.h" #include "tree-cfg.h" +#include "gimple-range.h" /* The idea behind this analyzer is to generate set constraints from the program, then solve the resulting constraints in order to generate the @@ -6740,7 +6741,9 @@ find_what_p_points_to (tree fndecl, tree p) struct ptr_info_def *pi; tree lookup_p = p; varinfo_t vi; - bool nonnull = get_ptr_nonnull (p); + value_range vr; + GLOBAL_RANGE_QUERY->range_of_expr (vr, p); + bool nonnull = vr.nonzero_p (); /* For parameters, get at the points-to set for the actual parm decl. */ @@ -6758,8 +6761,7 @@ find_what_p_points_to (tree fndecl, tree p) pi->pt = find_what_var_points_to (fndecl, vi); /* Conservatively set to NULL from PTA (to true). */ pi->pt.null = 1; - /* Preserve pointer nonnull computed by VRP. See get_ptr_nonnull - in gcc/tree-ssaname.c for more information. */ + /* Preserve pointer nonnull globally computed. */ if (nonnull) set_ptr_nonnull (p); } diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index f55ce1939ac..b352f68b1b7 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "builtins.h" #include "calls.h" +#include "gimple-range.h" /* This implements the pass that does predicate aware warning on uses of possibly uninitialized variables. The pass first collects the set of @@ -1606,11 +1607,14 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def, flag_var <= [min, max] -> flag_var < [min, max+1] flag_var >= [min, max] -> flag_var > [min-1, max] if no overflow/wrap. */ - wide_int min, max; tree type = TREE_TYPE (cond_lhs); + value_range r; if (!INTEGRAL_TYPE_P (type) - || get_range_info (cond_rhs, &min, &max) != VR_RANGE) + || !RANGE_QUERY (cfun)->range_of_expr (r, cond_rhs) + || r.kind () != VR_RANGE) continue; + wide_int min = r.lower_bound (); + wide_int max = r.upper_bound (); if (code == LE_EXPR && max != wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type))) { diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 7f65c4ce839..225d831003f 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -50,6 +50,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "target.h" #include "tree-into-ssa.h" #include "omp-general.h" +#include "gimple-range.h" /* ??? For lang_hooks.types.type_for_mode, but is there a word_mode type in the GIMPLE type system that is language-independent? */ @@ -1553,12 +1554,15 @@ bit_test_cluster::emit (tree index_expr, tree index_type, /* If every possible relative value of the index expression is a valid shift amount, then we can merge the entry test in the bit test. */ - wide_int min, max; bool entry_test_needed; + value_range r; if (TREE_CODE (index_expr) == SSA_NAME - && get_range_info (index_expr, &min, &max) == VR_RANGE - && wi::leu_p (max - min, prec - 1)) + && RANGE_QUERY (cfun)->range_of_expr (r, index_expr) + && r.kind () == VR_RANGE + && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1)) { + wide_int min = r.lower_bound (); + wide_int max = r.upper_bound (); tree index_type = TREE_TYPE (index_expr); minval = fold_convert (index_type, minval); wide_int iminval = wi::to_wide (minval); diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 803de3fc287..99be2314029 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "predict.h" #include "tree-vector-builder.h" #include "vec-perm-indices.h" +#include "gimple-range.h" /* Return true if we have a useful VR_RANGE range for VAR, storing it in *MIN_VALUE and *MAX_VALUE if so. Note the range in the dump files. */ @@ -55,7 +56,13 @@ along with GCC; see the file COPYING3. If not see static bool vect_get_range_info (tree var, wide_int *min_value, wide_int *max_value) { - value_range_kind vr_type = get_range_info (var, min_value, max_value); + value_range vr; + RANGE_QUERY (cfun)->range_of_expr (vr, var); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (var)); + *min_value = wi::to_wide (vr.min ()); + *max_value = wi::to_wide (vr.max ()); + value_range_kind vr_type = vr.kind (); wide_int nonzero = get_nonzero_bits (var); signop sgn = TYPE_SIGN (TREE_TYPE (var)); if (intersect_range_with_nonzero_bits (vr_type, min_value, max_value, @@ -3437,13 +3444,14 @@ vect_recog_divmod_pattern (vec_info *vinfo, else t3 = t2; - wide_int oprnd0_min, oprnd0_max; int msb = 1; - if (get_range_info (oprnd0, &oprnd0_min, &oprnd0_max) == VR_RANGE) + value_range r; + RANGE_QUERY (cfun)->range_of_expr (r, oprnd0); + if (r.kind () == VR_RANGE) { - if (!wi::neg_p (oprnd0_min, TYPE_SIGN (itype))) + if (!wi::neg_p (r.lower_bound (), TYPE_SIGN (itype))) msb = 0; - else if (wi::neg_p (oprnd0_max, TYPE_SIGN (itype))) + else if (wi::neg_p (r.upper_bound (), TYPE_SIGN (itype))) msb = -1; } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b0f1c47f05c..6a723efc0d8 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -228,7 +228,7 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type, vr_type = VR_RANGE; } } - if (vr_type == VR_RANGE) + if (vr_type == VR_RANGE || vr_type == VR_VARYING) { *max = wi::round_down_for_mask (*max, nonzero_bits); @@ -1717,7 +1717,7 @@ register_edge_assert_for_2 (tree name, edge e, simply register the same assert for it. */ if (CONVERT_EXPR_CODE_P (rhs_code)) { - wide_int rmin, rmax; + value_range vr; tree rhs1 = gimple_assign_rhs1 (def_stmt); if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) && TREE_CODE (rhs1) == SSA_NAME @@ -1739,13 +1739,14 @@ register_edge_assert_for_2 (tree name, edge e, && int_fits_type_p (val, TREE_TYPE (rhs1)) && ((TYPE_PRECISION (TREE_TYPE (name)) > TYPE_PRECISION (TREE_TYPE (rhs1))) - || (get_range_info (rhs1, &rmin, &rmax) == VR_RANGE + || ((RANGE_QUERY (cfun)->range_of_expr (vr, rhs1) + && vr.kind () == VR_RANGE) && wi::fits_to_tree_p - (widest_int::from (rmin, + (widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (rhs1))), TREE_TYPE (name)) && wi::fits_to_tree_p - (widest_int::from (rmax, + (widest_int::from (vr.upper_bound (), TYPE_SIGN (TREE_TYPE (rhs1))), TREE_TYPE (name))))) add_assert_info (asserts, rhs1, rhs1, @@ -4631,16 +4632,14 @@ determine_value_range_1 (value_range *vr, tree expr) vr->set (expr); else { - value_range_kind kind; - wide_int min, max; + value_range r; /* For SSA names try to extract range info computed by VRP. Otherwise fall back to varying. */ if (TREE_CODE (expr) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (expr)) - && (kind = get_range_info (expr, &min, &max)) != VR_VARYING) - vr->set (wide_int_to_tree (TREE_TYPE (expr), min), - wide_int_to_tree (TREE_TYPE (expr), max), - kind); + && RANGE_QUERY (cfun)->range_of_expr (r, expr) + && !r.undefined_p ()) + *vr = r; else vr->set_varying (TREE_TYPE (expr)); } diff --git a/gcc/tree.c b/gcc/tree.c index 31ac4245c9c..3d5111628b5 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vector-builder.h" #include "gimple-fold.h" #include "escaped_string.h" +#include "gimple-range.h" /* Tree code classes. */ @@ -13834,8 +13835,8 @@ get_range_pos_neg (tree arg) if (TREE_CODE (arg) != SSA_NAME) return 3; - wide_int arg_min, arg_max; - while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE) + value_range r; + while (!GLOBAL_RANGE_QUERY->range_of_expr (r, arg) || r.kind () != VR_RANGE) { gimple *g = SSA_NAME_DEF_STMT (arg); if (is_gimple_assign (g) @@ -13861,16 +13862,16 @@ get_range_pos_neg (tree arg) { /* For unsigned values, the "positive" range comes below the "negative" range. */ - if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED)) + if (!wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED)) return 1; - if (wi::neg_p (wi::sext (arg_min, prec), SIGNED)) + if (wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED)) return 2; } else { - if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED)) + if (!wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED)) return 1; - if (wi::neg_p (wi::sext (arg_max, prec), SIGNED)) + if (wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED)) return 2; } return 3; diff --git a/gcc/vr-values.c b/gcc/vr-values.c index a89f0b646ae..02acb46cb20 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -117,14 +117,16 @@ vr_values::get_lattice_entry (const_tree var) default definitions of PARM_DECLs. */ if (POINTER_TYPE_P (TREE_TYPE (sym)) && (nonnull_arg_p (sym) - || get_ptr_nonnull (var))) + || (GLOBAL_RANGE_QUERY->range_of_expr (*vr, + const_cast (var)) + && vr->nonzero_p ()))) { vr->set_nonzero (TREE_TYPE (sym)); vr->equiv_clear (); } else if (INTEGRAL_TYPE_P (TREE_TYPE (sym))) { - get_range_info (var, *vr); + GLOBAL_RANGE_QUERY->range_of_expr (*vr, const_cast (var)); if (vr->undefined_p ()) vr->set_varying (TREE_TYPE (sym)); } @@ -262,7 +264,7 @@ vr_values::update_value_range (const_tree var, value_range_equiv *new_vr) if (INTEGRAL_TYPE_P (TREE_TYPE (var))) { value_range_equiv nr; - get_range_info (var, nr); + GLOBAL_RANGE_QUERY->range_of_expr (nr, const_cast (var)); if (!nr.undefined_p ()) new_vr->intersect (&nr); } @@ -3829,13 +3831,13 @@ simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)) return false; - /* Get the value-range of the inner operand. Use get_range_info in + /* Get the value-range of the inner operand. Use global ranges in case innerop was created during substitute-and-fold. */ wide_int imin, imax; value_range vr; if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop))) return false; - get_range_info (innerop, vr); + RANGE_QUERY (cfun)->range_of_expr (vr, innerop, stmt); if (vr.undefined_p () || vr.varying_p ()) return false; innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop))); From patchwork Fri May 21 11:39:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1482193 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=IKWQIPSH; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FmlNW5mzrz9sVt for ; Fri, 21 May 2021 21:52:59 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 50238398B425; Fri, 21 May 2021 11:52:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 50238398B425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1621597963; bh=oBv09CA5cXD4rmJm5l6717zrYpC8bMVGZ9iQd02Wb1o=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=IKWQIPSHkYqWb8dCR+/NWm8triAMJJJys5MNu0QM8+AGpG7ZahvwwD7ovwoBE3Hf8 Ahmr5NzjzKUWyV37TApzPWwW5Ywtd2e6zViiSOxG8FgmOEbtFfmgFb61UOO48C11ye YT+2MPg9XvQwFvQFx48DWWitNednGSUdo0RaYS3c= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id D18EA398B855 for ; Fri, 21 May 2021 11:52:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D18EA398B855 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-231-WmFQ6BjaO4u_VInbw6DQSw-1; Fri, 21 May 2021 07:52:37 -0400 X-MC-Unique: WmFQ6BjaO4u_VInbw6DQSw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D9476801817; Fri, 21 May 2021 11:52:36 +0000 (UTC) Received: from abulafia.quesejoda.com (ovpn-113-127.ams2.redhat.com [10.36.113.127]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6797D5D9D5; Fri, 21 May 2021 11:52:36 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.16.1/8.15.2) with ESMTPS id 14LBqYgM1148432 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 21 May 2021 13:52:34 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.16.1/8.16.1/Submit) id 14LBqYdC1148431; Fri, 21 May 2021 13:52:34 +0200 To: GCC patches , Andrew MacLeod Subject: [PATCH 5/5] Cleanup get_range_info Date: Fri, 21 May 2021 13:39:54 +0200 Message-Id: <20210521113954.1148075-5-aldyh@redhat.com> In-Reply-To: <20210521113954.1148075-1-aldyh@redhat.com> References: <20210521113954.1148075-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Cc: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Now that there is only one user of get_range_info() we can clean this up to always return a range instead of pairs of wide_ints. A follow-up patch will inline both get_range_info and get_ptr_nonnull into its only remaining user. Tested on x86-64 Linux. OK? gcc/ChangeLog: * tree-ssanames.c (get_range_info): Merge both copies of get_range_info into one that works with irange. * tree-ssanames.h (get_range_info): Remove version that works on wide_ints. --- gcc/tree-ssanames.c | 57 +++++++++++---------------------------------- gcc/tree-ssanames.h | 2 -- 2 files changed, 14 insertions(+), 45 deletions(-) diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 51a26d2fce1..5329c0a4187 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -423,58 +423,29 @@ set_range_info (tree name, const value_range &vr) set_range_info (name, vr.kind (), min, max); } -/* Gets range information MIN, MAX and returns enum value_range_kind - corresponding to tree ssa_name NAME. enum value_range_kind returned - is used to determine if MIN and MAX are valid values. */ +/* Gets range information corresponding to ssa_name NAME and stores it + in a value_range VR. Returns the value_range_kind. */ enum value_range_kind -get_range_info (const_tree expr, wide_int *min, wide_int *max) +get_range_info (const_tree name, irange &vr) { - gcc_assert (!POINTER_TYPE_P (TREE_TYPE (expr))); - gcc_assert (min && max); - if (TREE_CODE (expr) == INTEGER_CST) - { - *min = wi::to_wide (expr); - *max = *min; - return VR_RANGE; - } - if (TREE_CODE (expr) != SSA_NAME) - return VR_VARYING; + tree type = TREE_TYPE (name); + gcc_checking_assert (!POINTER_TYPE_P (type)); + gcc_checking_assert (TREE_CODE (name) == SSA_NAME); - range_info_def *ri = SSA_NAME_RANGE_INFO (expr); + range_info_def *ri = SSA_NAME_RANGE_INFO (name); /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */ - if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (expr))) + if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (name))) > 2 * HOST_BITS_PER_WIDE_INT)) - return VR_VARYING; - - *min = ri->get_min (); - *max = ri->get_max (); - return SSA_NAME_RANGE_TYPE (expr); -} - -/* Gets range information corresponding to ssa_name NAME and stores it - in a value_range VR. Returns the value_range_kind. */ - -enum value_range_kind -get_range_info (const_tree name, irange &vr) -{ - tree min, max; - wide_int wmin, wmax; - enum value_range_kind kind = get_range_info (name, &wmin, &wmax); - - if (kind == VR_VARYING) - vr.set_varying (TREE_TYPE (name)); - else if (kind == VR_UNDEFINED) - vr.set_undefined (); + vr.set_varying (type); else - { - min = wide_int_to_tree (TREE_TYPE (name), wmin); - max = wide_int_to_tree (TREE_TYPE (name), wmax); - vr.set (min, max, kind); - } - return kind; + vr.set (wide_int_to_tree (type, ri->get_min ()), + wide_int_to_tree (type, ri->get_max ()), + SSA_NAME_RANGE_TYPE (name)); + + return vr.kind (); } /* Set nonnull attribute to pointer NAME. */ diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index cce2d2c22e8..166f921f04c 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -71,8 +71,6 @@ extern void set_range_info (tree, enum value_range_kind, const wide_int_ref &, const wide_int_ref &); extern void set_range_info (tree, const value_range &); /* Gets the value range from SSA. */ -extern enum value_range_kind get_range_info (const_tree, wide_int *, - wide_int *); extern enum value_range_kind get_range_info (const_tree, irange &); extern void set_nonzero_bits (tree, const wide_int_ref &); extern wide_int get_nonzero_bits (const_tree);