From patchwork Thu May 23 20:53:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 1938592 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RIKJDgcp; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.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 ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VlgSs38Lsz20KL for ; Fri, 24 May 2024 06:56:29 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B4496386D61A for ; Thu, 23 May 2024 20:56:27 +0000 (GMT) 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 ESMTPS id 12CBF386C59E for ; Thu, 23 May 2024 20:53:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 12CBF386C59E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 12CBF386C59E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716497604; cv=none; b=PxYSxoPhAadDM4gAzoGQBNHQa02nVwZjUfOy7HtOIUcCXHiTyxSJCFpRukIJcW/RXSTJwkdfZXrumLqv4VwoKTBiTU2Z9zBkKpwH3erndhr/HJW7Ys1Gu4HyNY2CW/vmf+4L/iF5Csab0o5N/EGlD3K7pdRikXy+5UCFS8PwwME= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716497604; c=relaxed/simple; bh=zQabLYsHRIfbnK507rsfT5x1hFckHIwTaC6yBN7ji2o=; h=DKIM-Signature:Message-ID:Date:MIME-Version:To:From:Subject; b=BxuoLixnZpDT/51KoqCc8wEWIz7FCMq9MDc2rn+iM1LEE9bcezHxct4jGG2E1k+Ys1PdXvWqn7H9CW1bpuIF4j/xGqHMu6n+v+1/GhdcogE6wT9gHqpxuSQa4qNCeFMuMJ8i1sPZrrEbSyIhjgA7tQCWXCy4yy0Hn7TeswphFQQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1716497599; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=WpdV7lfg93BORrY/pZWT/s/5Xcz4stQd3p753UUS2CI=; b=RIKJDgcprfAjYoSDUsgV5I2JXWQk4neiWr7zk5wnxcNmfeFGVqUIOk5d9FzwN+UwZ1DJNN r9QK1JgfuUBx+2PTvcUlZ3UqiugxrDxnoivii58hG3muL0fv8hOZ+t02cjwDro64j+vDsK qg8WsJohglEWlHEugzymZcqVi+hcKeU= Received: from mail-oi1-f200.google.com (mail-oi1-f200.google.com [209.85.167.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-650-uvFgC28yNTal0o8AiMuKGw-1; Thu, 23 May 2024 16:53:18 -0400 X-MC-Unique: uvFgC28yNTal0o8AiMuKGw-1 Received: by mail-oi1-f200.google.com with SMTP id 5614622812f47-3c9a9094719so1308603b6e.0 for ; Thu, 23 May 2024 13:53:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716497597; x=1717102397; h=subject:from:cc:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=JuZWq/mcgmg7rsmRnb4g5Xaj28YTAUGHUkKfu2uYf5U=; b=TQPfDd17cLRS3uEVN0H/iXZSgwyvYPHCxZzHzf5TMuYv+IHRzMLl/5RrjswymbtvsG LrmhWVrcyXnES25b7peXAHyCpfPahs/97zPi8sroLC48k33tMkCu0OH0UBvO+J4sFwB9 o+x96wWsHIFp91deg1DhexPj+DAI4QCgHj8rf6FAUrmCBbNBatfquwI/csQmcnkMGT9x rkYDqFPmR9MCS4DO0GcljznAykzW7UFpXdCNRpnQus2G0KuuH9JlHZKjpNYY2PBYp+8Y 1htIJYYdte2Gp7T/qWi6Hy8MFPudIUcqDs/xwcx367QwmLY3XTNickAuBkGHgUvxx3IO /qFg== X-Gm-Message-State: AOJu0Yw6d5MxK1yQop++OYEN5X1dT7UjKilbZYz7k+IEdJTBv2fh6/Bk MLRZcGcMPTbrnLPVcj1NLRxSSxH5Hpbtp7/jXID+ghn8VPAtjNKbYNNCGxpF+2IvsK5QsE1AGNv h4/5NGge9cl9ZiqyNCdMd2CHMVH0vi+rQAgDH0jJAQxPvQlkV2QLLae/wmz78rH/OrY1QiXS27A fRLLmkj67W7dYJkmU2Ca7T4AFwUjYZigHItu/uHLg= X-Received: by 2002:a05:6808:219d:b0:3c9:6a5b:51cf with SMTP id 5614622812f47-3d1a538c770mr665041b6e.9.1716497597191; Thu, 23 May 2024 13:53:17 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFpn/TtJFfdpn+SelYxpF4t20RJholHAOKLn8sI8ouyKVP9Zg3mXnQAAQAYQqjoSnCp0qd+4Q== X-Received: by 2002:a05:6808:219d:b0:3c9:6a5b:51cf with SMTP id 5614622812f47-3d1a538c770mr665025b6e.9.1716497596813; Thu, 23 May 2024 13:53:16 -0700 (PDT) Received: from [192.168.0.174] ([104.219.121.64]) by smtp.gmail.com with ESMTPSA id af79cd13be357-794abd48978sm202985a.132.2024.05.23.13.53.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 23 May 2024 13:53:16 -0700 (PDT) Message-ID: <2293adc5-4dcd-45a6-a173-ca610f1e5e77@redhat.com> Date: Thu, 23 May 2024 16:53:15 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: gcc-patches Cc: "hernandez, aldy" From: Andrew MacLeod Subject: [COMMITTED 05/12] - Move infer_manager to a range_query oracle. X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Turn the infer_manager class into an always available oracle accessible via a range_query object.   This will make it easier to share and query inferred range info between objects and also makes the information easily accessible to any pass that is interested. This again removes the need to check for a non-null object, and again makes for a slight performance improvement. Documentation on the inferred range manager can be found at : https://gcc.gnu.org/wiki/AndrewMacLeod/InferredRanges It also associates each inferred range with it's originating stmt which was missing before (we only knew what block it came from). Future functionality will make use of the more specific information. Bootstrapped on x86_64-pc-linux-gnu with no regressions.  Pushed. From 837ce8a2d75231b68f13da00d9be8d2fd404804e Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Fri, 17 May 2024 10:50:24 -0400 Subject: [PATCH 05/12] Move infer_manager to a range_query oracle. Turn the infer_manager class into an always available oracle accessible via a range_query object. Also assocaite each inferrred range with it's originating stmt. * gimple-range-cache.cc (ranger_cache::ranger_cache): Create an infer oracle instead of a local member. (ranger_cache::~ranger_cache): Destroy the oracle. (ranger_cache::edge_range): Use oracle. (ranger_cache::fill_block_cache): Likewise. (ranger_cache::range_from_dom): Likewise. (ranger_cache::apply_inferred_ranges): Likewise. * gimple-range-cache.h (ranger_cache::m_exit): Delete. * gimple-range-infer.cc (infer_oracle): New static object; (class infer_oracle): New. (non_null_wrapper::non_null_wrapper): New. (non_null_wrapper::add_nonzero): New. (non_null_wrapper::add_range): New. (non_null_loadstore): Use nonnull_wrapper. (gimple_infer_range::gimple_infer_range): New alternate constructor. (exit_range::stmt): New. (infer_range_manager::has_range_p): Combine seperate methods. (infer_range_manager::maybe_adjust_range): Adjust has_range_p call. (infer_range_manager::add_ranges): New. (infer_range_manager::add_range): Take stmt rather than BB. (infer_range_manager::add_nonzero): Adjust from BB to stmt. * gimple-range-infer.h (class gimple_infer_range): Adjust methods. (infer_range_oracle): New. (class infer_range_manager): Inherit from infer_range_oracle. Adjust methods. * gimple-range-path.cc (path_range_query::range_defined_in_block): Use oracle. (path_range_query::adjust_for_non_null_uses): Likewise. * gimple-range.cc (gimple_ranger::range_on_edge): Likewise (gimple_ranger::register_transitive_inferred_ranges): Likewise. * value-query.cc (default_infer_oracle): New. (range_query::create_infer_oracle): New. (range_query::destroy_infer_oracle): New. (range_query::share_query): Copy infer pointer. (range_query::range_query): Initialize infer pointer. (range_query::~range_query): destroy infer object. * value-query.h (range_query::infer_oracle): New. (range_query::create_infer_oracle): New prototype. (range_query::destroy_infer_oracle): New prototype. (range_query::m_infer): New. --- gcc/gimple-range-cache.cc | 24 +++++------ gcc/gimple-range-cache.h | 1 - gcc/gimple-range-infer.cc | 90 +++++++++++++++++++++++++++------------ gcc/gimple-range-infer.h | 31 ++++++++++---- gcc/gimple-range-path.cc | 4 +- gcc/gimple-range.cc | 14 +++--- gcc/value-query.cc | 20 +++++++++ gcc/value-query.h | 5 +++ 8 files changed, 131 insertions(+), 58 deletions(-) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 55277ea8af1..34dc9c4a3ec 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -950,8 +950,7 @@ update_list::pop () // -------------------------------------------------------------------------- ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) - : m_gori (not_executable_flag), - m_exit (use_imm_uses) + : m_gori (not_executable_flag) { m_workback.create (0); m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun)); @@ -960,6 +959,7 @@ ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) // If DOM info is available, spawn an oracle as well. create_relation_oracle (); + create_infer_oracle (use_imm_uses); unsigned x, lim = last_basic_block_for_fn (cfun); // Calculate outgoing range info upfront. This will fully populate the @@ -977,6 +977,7 @@ ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) ranger_cache::~ranger_cache () { delete m_update; + destroy_infer_oracle (); destroy_relation_oracle (); delete m_temporal; m_workback.release (); @@ -1175,7 +1176,7 @@ ranger_cache::edge_range (vrange &r, edge e, tree name, enum rfd_mode mode) exit_range (r, name, e->src, mode); // If this is not an abnormal edge, check for inferred ranges on exit. if ((e->flags & (EDGE_EH | EDGE_ABNORMAL)) == 0) - m_exit.maybe_adjust_range (r, name, e->src); + infer_oracle ().maybe_adjust_range (r, name, e->src); Value_Range er (TREE_TYPE (name)); if (m_gori.outgoing_edge_range_p (er, e, name, *this)) r.intersect (er); @@ -1544,7 +1545,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb) // Regardless of whether we have visited pred or not, if the // pred has inferred ranges, revisit this block. // Don't search the DOM tree. - if (m_exit.has_range_p (name, pred)) + if (infer_oracle ().has_range_p (pred, name)) { if (DEBUG_RANGE_CACHE) fprintf (dump_file, "Inferred range: update "); @@ -1667,7 +1668,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, for ( ; bb; prev_bb = bb, bb = get_immediate_dominator (CDI_DOMINATORS, bb)) { // Accumulate any block exit inferred ranges. - m_exit.maybe_adjust_range (infer, name, bb); + infer_oracle ().maybe_adjust_range (infer, name, bb); // This block has an outgoing range. if (m_gori.has_edge_range_p (name, bb)) @@ -1742,7 +1743,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, r.intersect (er); // If this is a normal edge, apply any inferred ranges. if ((e->flags & (EDGE_EH | EDGE_ABNORMAL)) == 0) - m_exit.maybe_adjust_range (r, name, bb); + infer_oracle ().maybe_adjust_range (r, name, bb); if (DEBUG_RANGE_CACHE) { @@ -1811,11 +1812,8 @@ ranger_cache::apply_inferred_ranges (gimple *s) update = false; } - for (unsigned x = 0; x < infer.num (); x++) - { - tree name = infer.name (x); - m_exit.add_range (name, bb, infer.range (x)); - if (update) - register_inferred_value (infer.range (x), name, bb); - } + infer_oracle ().add_ranges (s, infer); + if (update) + for (unsigned x = 0; x < infer.num (); x++) + register_inferred_value (infer.range (x), infer.name (x), bb); } diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h index bdf07cd007c..e3ab89de02e 100644 --- a/gcc/gimple-range-cache.h +++ b/gcc/gimple-range-cache.h @@ -115,7 +115,6 @@ public: void register_inferred_value (const vrange &r, tree name, basic_block bb); void apply_inferred_ranges (gimple *s); gori_compute m_gori; - infer_range_manager m_exit; void dump_bb (FILE *f, basic_block bb); virtual void dump (FILE *f) override; diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc index d5e1aa14275..757a2013c58 100644 --- a/gcc/gimple-range-infer.cc +++ b/gcc/gimple-range-infer.cc @@ -37,6 +37,25 @@ along with GCC; see the file COPYING3. If not see #include "cfganal.h" #include "tree-dfa.h" +// Create the global oracle. + +infer_range_oracle infer_oracle; + +// This class is merely an accessor which is granted internals to +// gimple_infer_range such that non_null_loadstore as a static callback can +// call the protected add_nonzero (). +// Static functions ccannot be friends, so we do it through a class wrapper. + +class non_null_wrapper +{ +public: + inline non_null_wrapper (gimple_infer_range *infer) : m_infer (infer) { } + inline void add_nonzero (tree name) { m_infer->add_nonzero (name); } + inline void add_range (tree t, vrange &r) { m_infer->add_range (t, r); } +private: + gimple_infer_range *m_infer; +}; + // Adapted from infer_nonnull_range_by_dereference and check_loadstore // to process nonnull ssa_name OP in S. DATA contains a pointer to a // stmt range inference instance. @@ -50,8 +69,8 @@ non_null_loadstore (gimple *, tree op, tree, void *data) addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op)); if (!targetm.addr_space.zero_address_valid (as)) { - tree ssa = TREE_OPERAND (op, 0); - ((gimple_infer_range *)data)->add_nonzero (ssa); + non_null_wrapper wrapper ((gimple_infer_range *)data); + wrapper.add_nonzero (TREE_OPERAND (op, 0)); } } return false; @@ -173,6 +192,14 @@ gimple_infer_range::gimple_infer_range (gimple *s) } +// Create an single inferred range for NAMe using range R. + +gimple_infer_range::gimple_infer_range (tree name, vrange &r) +{ + num_args = 0; + add_range (name, r); +} + // ------------------------------------------------------------------------- // This class is an element in the list of inferred ranges. @@ -181,10 +208,12 @@ class exit_range { public: tree name; + gimple *stmt; vrange_storage *range; exit_range *next; }; + // If there is an element which matches SSA, return a pointer to the element. // Otherwise return NULL. @@ -253,33 +282,26 @@ infer_range_manager::get_nonzero (tree name) return *(m_nonzero[v]); } -// Return TRUE if there are any range inferences in block BB. - -bool -infer_range_manager::has_range_p (basic_block bb) -{ - if (bb->index >= (int)m_on_exit.length ()) - return false; - bitmap b = m_on_exit[bb->index].m_names; - return b && !bitmap_empty_p (b); -} - -// Return TRUE if NAME has a range inference in block BB. +// Return TRUE if NAME has a range inference in block BB. If NAME is NULL, +// return TRUE if there are any name sin BB. bool -infer_range_manager::has_range_p (tree name, basic_block bb) +infer_range_manager::has_range_p (basic_block bb, tree name) { // Check if this is an immediate use search model. - if (m_seen && !bitmap_bit_p (m_seen, SSA_NAME_VERSION (name))) + if (name && m_seen && !bitmap_bit_p (m_seen, SSA_NAME_VERSION (name))) register_all_uses (name); if (bb->index >= (int)m_on_exit.length ()) return false; - if (!m_on_exit[bb->index].m_names) - return false; - if (!bitmap_bit_p (m_on_exit[bb->index].m_names, SSA_NAME_VERSION (name))) + + bitmap b = m_on_exit[bb->index].m_names; + if (!b) return false; - return true; + + if (name) + return bitmap_bit_p (m_on_exit[bb->index].m_names, SSA_NAME_VERSION (name)); + return !bitmap_empty_p (b); } // Return TRUE if NAME has a range inference in block BB, and adjust range R @@ -288,7 +310,7 @@ infer_range_manager::has_range_p (tree name, basic_block bb) bool infer_range_manager::maybe_adjust_range (vrange &r, tree name, basic_block bb) { - if (!has_range_p (name, bb)) + if (!has_range_p (bb, name)) return false; exit_range *ptr = m_on_exit[bb->index].find_ptr (name); gcc_checking_assert (ptr); @@ -299,11 +321,23 @@ infer_range_manager::maybe_adjust_range (vrange &r, tree name, basic_block bb) return r.intersect (tmp); } -// Add range R as an inferred range for NAME in block BB. +// Add all inferred ranges in INFER at stmt S. + +void +infer_range_manager::add_ranges (gimple *s, gimple_infer_range &infer) +{ + for (unsigned x = 0; x < infer.num (); x++) + add_range (infer.name (x), s, infer.range (x)); +} + +// Add range R as an inferred range for NAME on stmt S. void -infer_range_manager::add_range (tree name, basic_block bb, const vrange &r) +infer_range_manager::add_range (tree name, gimple *s, const vrange &r) { + basic_block bb = gimple_bb (s); + if (!bb) + return; if (bb->index >= (int)m_on_exit.length ()) m_on_exit.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1); @@ -334,6 +368,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const vrange &r) ptr->range->set_vrange (cur); else ptr->range = m_range_allocator->clone (cur); + ptr->stmt = s; return; } @@ -342,16 +377,17 @@ infer_range_manager::add_range (tree name, basic_block bb, const vrange &r) ptr = (exit_range *)obstack_alloc (&m_list_obstack, sizeof (exit_range)); ptr->range = m_range_allocator->clone (r); ptr->name = name; + ptr->stmt = s; ptr->next = m_on_exit[bb->index].head; m_on_exit[bb->index].head = ptr; } -// Add a non-zero inferred range for NAME in block BB. +// Add a non-zero inferred range for NAME at stmt S. void -infer_range_manager::add_nonzero (tree name, basic_block bb) +infer_range_manager::add_nonzero (tree name, gimple *s) { - add_range (name, bb, get_nonzero (name)); + add_range (name, s, get_nonzero (name)); } // Follow immediate use chains and find all inferred ranges for NAME. @@ -378,7 +414,7 @@ infer_range_manager::register_all_uses (tree name) for (unsigned x = 0; x < infer.num (); x++) { if (name == infer.name (x)) - add_range (name, gimple_bb (s), infer.range (x)); + add_range (name, s, infer.range (x)); } } } diff --git a/gcc/gimple-range-infer.h b/gcc/gimple-range-infer.h index 384d8b2765e..fd5b2ad8dde 100644 --- a/gcc/gimple-range-infer.h +++ b/gcc/gimple-range-infer.h @@ -32,20 +32,35 @@ class gimple_infer_range { public: gimple_infer_range (gimple *s); + gimple_infer_range (tree name, vrange &r); inline unsigned num () const { return num_args; } inline tree name (unsigned index) const { gcc_checking_assert (index < num_args); return m_names[index]; } inline const vrange& range (unsigned index) const { gcc_checking_assert (index < num_args); return m_ranges[index]; } +private: void add_range (tree name, vrange &range); void add_nonzero (tree name); -private: void check_assume_func (gcall *call); unsigned num_args; static const int size_limit = 10; tree m_names[size_limit]; Value_Range m_ranges[size_limit]; inline void bump_index () { if (num_args < size_limit - 1) num_args++; } + friend class non_null_wrapper; +}; + +// This is the basic infer oracle API. Default functionaility does nothing. + +class infer_range_oracle +{ +public: + infer_range_oracle () { } + virtual ~infer_range_oracle () { } + virtual void add_ranges (gimple *, gimple_infer_range &) { } + virtual bool has_range_p (basic_block, tree = NULL_TREE) { return false; } + virtual bool maybe_adjust_range (vrange &, tree, basic_block) + { return false; } }; // This class manages a list of inferred ranges for each basic block. @@ -54,17 +69,17 @@ private: // followed the first time a name is referenced and block populated if // there are any inferred ranges. -class infer_range_manager +class infer_range_manager : public infer_range_oracle { public: infer_range_manager (bool do_search); - ~infer_range_manager (); - void add_range (tree name, basic_block bb, const vrange &r); - void add_nonzero (tree name, basic_block bb); - bool has_range_p (tree name, basic_block bb); - bool has_range_p (basic_block bb); - bool maybe_adjust_range (vrange &r, tree name, basic_block bb); + virtual ~infer_range_manager (); + virtual void add_ranges (gimple *s, gimple_infer_range &ir); + virtual bool has_range_p (basic_block bb, tree name = NULL_TREE); + virtual bool maybe_adjust_range (vrange &r, tree name, basic_block bb); private: + void add_range (tree name, gimple *s, const vrange &r); + void add_nonzero (tree name, gimple *s); class exit_range_head { public: diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index e35bec0e50d..b35ab43524b 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -303,7 +303,7 @@ path_range_query::range_defined_in_block (vrange &r, tree name, basic_block bb) } if (bb && POINTER_TYPE_P (TREE_TYPE (name))) - m_ranger.m_cache.m_exit.maybe_adjust_range (r, name, bb); + m_ranger.infer_oracle ().maybe_adjust_range (r, name, bb); if (DEBUG_SOLVER && (bb || !r.varying_p ())) { @@ -463,7 +463,7 @@ path_range_query::adjust_for_non_null_uses (basic_block bb) else r.set_varying (TREE_TYPE (name)); - if (m_ranger.m_cache.m_exit.maybe_adjust_range (r, name, bb)) + if (m_ranger.infer_oracle ().maybe_adjust_range (r, name, bb)) m_cache.set_range (name, r); } } diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 4326976fc2a..efc84dc3b44 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -253,7 +253,7 @@ gimple_ranger::range_on_edge (vrange &r, edge e, tree name) range_on_exit (r, e->src, name); // If this is not an abnormal edge, check for a non-null exit . if ((e->flags & (EDGE_EH | EDGE_ABNORMAL)) == 0) - m_cache.m_exit.maybe_adjust_range (r, name, e->src); + infer_oracle ().maybe_adjust_range (r, name, e->src); gcc_checking_assert (r.undefined_p () || range_compatible_p (r.type(), TREE_TYPE (name))); @@ -516,8 +516,7 @@ void gimple_ranger::register_transitive_inferred_ranges (basic_block bb) { // Return if there are no inferred ranges in BB. - infer_range_manager &infer = m_cache.m_exit; - if (!infer.has_range_p (bb)) + if (!infer_oracle ().has_range_p (bb)) return; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -530,7 +529,7 @@ gimple_ranger::register_transitive_inferred_ranges (basic_block bb) gimple *s = gsi_stmt (si); tree lhs = gimple_get_lhs (s); // If the LHS already has an inferred effect, leave it be. - if (!gimple_range_ssa_p (lhs) || infer.has_range_p (lhs, bb)) + if (!gimple_range_ssa_p (lhs) || infer_oracle ().has_range_p (bb, lhs)) continue; // Pick up global value. Value_Range g (TREE_TYPE (lhs)); @@ -543,13 +542,14 @@ gimple_ranger::register_transitive_inferred_ranges (basic_block bb) r.set_undefined (); tree name1 = gori ().depend1 (lhs); tree name2 = gori ().depend2 (lhs); - if ((name1 && infer.has_range_p (name1, bb)) - || (name2 && infer.has_range_p (name2, bb))) + if ((name1 && infer_oracle ().has_range_p (bb, name1)) + || (name2 && infer_oracle ().has_range_p (bb, name2))) { // Check if folding S produces a different result. if (fold_range (r, s, this) && g != r) { - infer.add_range (lhs, bb, r); + gimple_infer_range ir (lhs, r); + infer_oracle ().add_ranges (s, ir); m_cache.register_inferred_value (r, lhs, bb); } } diff --git a/gcc/value-query.cc b/gcc/value-query.cc index adcc59cadbf..41b581b20be 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -181,6 +181,23 @@ range_query::dump (FILE *) // Default oracle for all range queries. This contains no storage and thus // can be used anywhere. relation_oracle default_relation_oracle; +infer_range_oracle default_infer_oracle; + +void +range_query::create_infer_oracle (bool do_search) +{ + gcc_checking_assert (m_infer == &default_infer_oracle); + m_infer = new infer_range_manager (do_search); + gcc_checking_assert (m_infer); +} + +void +range_query::destroy_infer_oracle () +{ + if (m_infer && m_infer != &default_infer_oracle) + delete m_infer; + m_infer = &default_infer_oracle; +} // Create dominance based range oracle for the current query if dom info is // available. @@ -215,12 +232,14 @@ void range_query::share_query (range_query &q) { m_relation = q.m_relation; + m_infer = q.m_infer; m_shared_copy_p = true; } range_query::range_query () { m_relation = &default_relation_oracle; + m_infer = &default_infer_oracle; m_shared_copy_p = false; } @@ -229,6 +248,7 @@ range_query::~range_query () // Do not destroy anything if this is a shared copy. if (m_shared_copy_p) return; + destroy_infer_oracle (); destroy_relation_oracle (); } diff --git a/gcc/value-query.h b/gcc/value-query.h index a5735902af0..2f65d95bc9b 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -79,6 +79,10 @@ public: void create_relation_oracle (); void destroy_relation_oracle (); + inline class infer_range_oracle &infer_oracle () const { return *m_infer; } + void create_infer_oracle (bool do_search = TRUE); + void destroy_infer_oracle (); + virtual void dump (FILE *); protected: @@ -88,6 +92,7 @@ protected: basic_block bbentry, basic_block bbexit); bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt); relation_oracle *m_relation; + infer_range_oracle *m_infer; // When multiple related range queries wish to share oracles. // This is an internal interface void share_query (range_query &q); -- 2.41.0