From patchwork Sun Jul 3 15:34:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1651666 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=R50N8LYm; dkim-atps=neutral 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+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) 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 (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LbY0T5zGtz9sFx for ; Mon, 4 Jul 2022 01:35:04 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5ECEE3843879 for ; Sun, 3 Jul 2022 15:34:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5ECEE3843879 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1656862498; bh=+5I3RNv5w6QONDAuc7X968vLVniqAsqex4o475BEz4k=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=R50N8LYmNgyFWV041IUbJEcXS///TBK8R4eYGuj7tPFP6TeWpxQtY+Yx+6SX1E8vu Q2nNlxYv6neGcOBA0lLvs8W2ezRXZJA+sz/YdS9PxzVReJZjT4jcA5Rit4KQ9BhMBF 9it85KzEZbdBOmG7O+ty5X8p0po9+WCzoG6/tVxs= 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 1ED5F386C5A2 for ; Sun, 3 Jul 2022 15:34:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1ED5F386C5A2 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-302-uxI190Z4N5CZN2DNoyo4cw-1; Sun, 03 Jul 2022 11:34:35 -0400 X-MC-Unique: uxI190Z4N5CZN2DNoyo4cw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4BCB21019C88 for ; Sun, 3 Jul 2022 15:34:35 +0000 (UTC) Received: from abulafia.quesejoda.com (unknown [10.39.192.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B39A718EB8; Sun, 3 Jul 2022 15:34:34 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.17.1/8.17.1) with ESMTPS id 263FYWLZ417348 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Sun, 3 Jul 2022 17:34:32 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.17.1/8.17.1/Submit) id 263FYWLT417347; Sun, 3 Jul 2022 17:34:32 +0200 To: GCC patches Subject: [COMMITTED] Move range allocator code to value-range-storage.* Date: Sun, 3 Jul 2022 17:34:25 +0200 Message-Id: <20220703153425.417313-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com 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, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.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 Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Now that vrange_storage is in its own file, I think it's prudent to move all the vrange allocator code there since it's all related. The users of value-range.h do not need to know the implementation details of the storage facilities. Tested and benchmarked on x86-64 Linux. gcc/ChangeLog: * gimple-range-cache.cc: Include value-range-storage.h. * gimple-range-cache.h (class block_range_cache): Add "class" to m_range_allocator. * gimple-range-edge.cc (gimple_outgoing_range::gimple_outgoing_range): Allocate allocator. (gimple_outgoing_range::~gimple_outgoing_range): Free allocator. (gimple_outgoing_range::calc_switch_ranges): Dereference allocator. * gimple-range-edge.h: Add "class" to m_range_allocator. * gimple-range-infer.cc (infer_range_manager::infer_range_manager): Allocate allocator. (infer_range_manager::~infer_range_manager): Free allocator. (infer_range_manager::get_nonzero): Dereference allocator. (infer_range_manager::add_range): Same. * gimple-range-infer.h (class vrange_allocator): Add "class" to m_range_allocator. * value-range-storage.h (class vrange_allocator): Move from value-range.h. (class obstack_vrange_allocator): Same. (class ggc_vrange_allocator): Same. (vrange_allocator::alloc_vrange): Same. (vrange_allocator::alloc_irange): Same. * value-range.h (class vrange_allocator): Move to value-range-storage.h. (class obstack_vrange_allocator): Same. (class ggc_vrange_allocator): Same. --- gcc/gimple-range-cache.cc | 1 + gcc/gimple-range-cache.h | 2 +- gcc/gimple-range-edge.cc | 7 ++- gcc/gimple-range-edge.h | 2 +- gcc/gimple-range-infer.cc | 9 ++- gcc/gimple-range-infer.h | 2 +- gcc/value-range-storage.h | 113 ++++++++++++++++++++++++++++++++++++-- gcc/value-range.h | 109 ------------------------------------ 8 files changed, 124 insertions(+), 121 deletions(-) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 5bb52d5f70f..9be8bc6123b 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "ssa.h" #include "gimple-pretty-print.h" #include "gimple-range.h" +#include "value-range-storage.h" #include "tree-cfg.h" #include "target.h" #include "attribs.h" diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h index a784eba8345..0341192c9cb 100644 --- a/gcc/gimple-range-cache.h +++ b/gcc/gimple-range-cache.h @@ -44,7 +44,7 @@ private: vec m_ssa_ranges; ssa_block_ranges &get_block_ranges (tree name); ssa_block_ranges *query_block_ranges (tree name); - vrange_allocator *m_range_allocator; + class vrange_allocator *m_range_allocator; bitmap_obstack m_bitmaps; }; diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc index 03a804ac2be..194e8f87a4b 100644 --- a/gcc/gimple-range-edge.cc +++ b/gcc/gimple-range-edge.cc @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "tree-cfg.h" #include "gimple-range.h" +#include "value-range-storage.h" // If there is a range control statment at the end of block BB, return it. // Otherwise return NULL. @@ -68,6 +69,7 @@ gimple_outgoing_range::gimple_outgoing_range (int max_sw_edges) { m_edge_table = NULL; m_max_edges = max_sw_edges; + m_range_allocator = new obstack_vrange_allocator; } @@ -75,6 +77,7 @@ gimple_outgoing_range::~gimple_outgoing_range () { if (m_edge_table) delete m_edge_table; + delete m_range_allocator; } @@ -162,13 +165,13 @@ gimple_outgoing_range::calc_switch_ranges (gswitch *sw) // If there was an existing range and it doesn't fit, we lose the memory. // It'll get reclaimed when the obstack is freed. This seems less // intrusive than allocating max ranges for each case. - slot = m_range_allocator.clone (case_range); + slot = m_range_allocator->clone (case_range); } irange *&slot = m_edge_table->get_or_insert (default_edge, &existed); // This should be the first call into this switch. gcc_checking_assert (!existed); - irange *dr = m_range_allocator.clone (default_range); + irange *dr = m_range_allocator->clone (default_range); slot = dr; } diff --git a/gcc/gimple-range-edge.h b/gcc/gimple-range-edge.h index c81b943dae6..1a4dee9f41b 100644 --- a/gcc/gimple-range-edge.h +++ b/gcc/gimple-range-edge.h @@ -47,7 +47,7 @@ private: int m_max_edges; hash_map *m_edge_table; - obstack_vrange_allocator m_range_allocator; + class obstack_vrange_allocator *m_range_allocator; }; // If there is a range control statement at the end of block BB, return it. diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc index eee149104b4..2d12f86ce89 100644 --- a/gcc/gimple-range-infer.cc +++ b/gcc/gimple-range-infer.cc @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "ssa.h" #include "gimple-pretty-print.h" #include "gimple-range.h" +#include "value-range-storage.h" #include "tree-cfg.h" #include "target.h" #include "attribs.h" @@ -166,6 +167,7 @@ infer_range_manager::infer_range_manager (bool do_search) // Non-zero elements are very common, so cache them for each ssa-name. m_nonzero.create (0); m_nonzero.safe_grow_cleared (num_ssa_names + 1); + m_range_allocator = new obstack_vrange_allocator; } // Destruct a range infer manager. @@ -176,6 +178,7 @@ infer_range_manager::~infer_range_manager () obstack_free (&m_list_obstack, NULL); m_on_exit.release (); bitmap_obstack_release (&m_bitmaps); + delete m_range_allocator; } // Return a non-zero range value of the appropriate type for NAME from @@ -189,7 +192,7 @@ infer_range_manager::get_nonzero (tree name) m_nonzero.safe_grow_cleared (num_ssa_names + 20); if (!m_nonzero[v]) { - m_nonzero[v] = m_range_allocator.alloc_vrange (TREE_TYPE (name)); + m_nonzero[v] = m_range_allocator->alloc_vrange (TREE_TYPE (name)); m_nonzero[v]->set_nonzero (TREE_TYPE (name)); } return *(m_nonzero[v]); @@ -261,7 +264,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const vrange &r) else { vrange &v = cur; - ptr->range = m_range_allocator.clone (v); + ptr->range = m_range_allocator->clone (v); } return; } @@ -269,7 +272,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const vrange &r) // Otherwise create a record. bitmap_set_bit (m_on_exit[bb->index].m_names, SSA_NAME_VERSION (name)); ptr = (exit_range *)obstack_alloc (&m_list_obstack, sizeof (exit_range)); - ptr->range = m_range_allocator.clone (r); + ptr->range = m_range_allocator->clone (r); ptr->name = name; ptr->next = m_on_exit[bb->index].head; m_on_exit[bb->index].head = ptr; diff --git a/gcc/gimple-range-infer.h b/gcc/gimple-range-infer.h index bf27d0d3423..468b7d11286 100644 --- a/gcc/gimple-range-infer.h +++ b/gcc/gimple-range-infer.h @@ -78,7 +78,7 @@ private: bitmap m_seen; bitmap_obstack m_bitmaps; struct obstack m_list_obstack; - obstack_vrange_allocator m_range_allocator; + class obstack_vrange_allocator *m_range_allocator; }; #endif // GCC_GIMPLE_RANGE_SIDE_H diff --git a/gcc/value-range-storage.h b/gcc/value-range-storage.h index 58c5e114320..7e005e4db56 100644 --- a/gcc/value-range-storage.h +++ b/gcc/value-range-storage.h @@ -21,6 +21,27 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_VALUE_RANGE_STORAGE_H #define GCC_VALUE_RANGE_STORAGE_H +// This class is used to allocate the minimum amount of storage needed +// for a given range. Storage is automatically freed at destruction +// of the class. + +class vrange_allocator +{ +public: + vrange_allocator () { } + virtual ~vrange_allocator () { } + // Allocate a range of TYPE. + vrange *alloc_vrange (tree type); + // Allocate a memory block of BYTES. + virtual void *alloc (unsigned bytes) = 0; + virtual void free (void *p) = 0; + // Return a clone of SRC. + template T *clone (const T &src); +private: + irange *alloc_irange (unsigned pairs); + void operator= (const vrange_allocator &) = delete; +}; + // This class is used to allocate chunks of memory that can store // ranges as memory efficiently as possible. It is meant to be used // when long term storage of a range is needed. The class can be used @@ -40,10 +61,6 @@ private: vrange_allocator *m_alloc; }; - -// INTERNAL USE ONLY. The remaining interfaces are only exposed for -// the GTY machinery to play nice with tree_ssa_name. - // A chunk of memory pointing to an irange storage. class GTY ((variable_size)) irange_storage_slot @@ -82,4 +99,92 @@ private: trailing_wide_ints m_ints; }; +class obstack_vrange_allocator : public vrange_allocator +{ +public: + obstack_vrange_allocator () + { + obstack_init (&m_obstack); + } + virtual ~obstack_vrange_allocator () final override + { + obstack_free (&m_obstack, NULL); + } + virtual void *alloc (unsigned bytes) final override + { + return obstack_alloc (&m_obstack, bytes); + } + virtual void free (void *) final override { } +private: + obstack m_obstack; +}; + +class ggc_vrange_allocator : public vrange_allocator +{ +public: + ggc_vrange_allocator () { } + virtual ~ggc_vrange_allocator () final override { } + virtual void *alloc (unsigned bytes) final override + { + return ggc_internal_alloc (bytes); + } + virtual void free (void *p) final override + { + return ggc_free (p); + } +}; + +// Return a new range to hold ranges of TYPE. The newly allocated +// range is initialized to VR_UNDEFINED. + +inline vrange * +vrange_allocator::alloc_vrange (tree type) +{ + if (irange::supports_p (type)) + return alloc_irange (2); + + gcc_unreachable (); +} + +// Return a new range with NUM_PAIRS. + +inline irange * +vrange_allocator::alloc_irange (unsigned num_pairs) +{ + // Never allocate 0 pairs. + // Don't allocate 1 either, or we get legacy value_range's. + if (num_pairs < 2) + num_pairs = 2; + + size_t nbytes = sizeof (tree) * 2 * num_pairs; + + // Allocate the irange and required memory for the vector. + void *r = alloc (sizeof (irange)); + tree *mem = static_cast (alloc (nbytes)); + return new (r) irange (mem, num_pairs); +} + +// Return a clone of an irange. + +template <> +inline irange * +vrange_allocator::clone (const irange &src) +{ + irange *r = alloc_irange (src.num_pairs ()); + *r = src; + return r; +} + +// Return a clone of a vrange. + +template <> +inline vrange * +vrange_allocator::clone (const vrange &src) +{ + if (is_a (src)) + return clone (as_a (src)); + + gcc_unreachable (); +} + #endif // GCC_VALUE_RANGE_STORAGE_H diff --git a/gcc/value-range.h b/gcc/value-range.h index 627d221fe0f..8ee7793baeb 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -896,113 +896,4 @@ vrp_val_min (const_tree type) return NULL_TREE; } -// This is the range storage class. It is used to allocate the -// minimum amount of storage needed for a given range. Storage is -// automatically freed at destruction of the class. - -class vrange_allocator -{ -public: - vrange_allocator () { } - virtual ~vrange_allocator () { } - // Allocate a range of TYPE. - vrange *alloc_vrange (tree type); - // Allocate a memory block of BYTES. - virtual void *alloc (unsigned bytes) = 0; - virtual void free (void *p) = 0; - // Return a clone of SRC. - template T *clone (const T &src); -private: - irange *alloc_irange (unsigned pairs); - void operator= (const vrange_allocator &) = delete; -}; - -class obstack_vrange_allocator : public vrange_allocator -{ -public: - obstack_vrange_allocator () - { - obstack_init (&m_obstack); - } - virtual ~obstack_vrange_allocator () final override - { - obstack_free (&m_obstack, NULL); - } - virtual void *alloc (unsigned bytes) final override - { - return obstack_alloc (&m_obstack, bytes); - } - virtual void free (void *) final override { } -private: - obstack m_obstack; -}; - -class ggc_vrange_allocator : public vrange_allocator -{ -public: - ggc_vrange_allocator () { } - virtual ~ggc_vrange_allocator () final override { } - virtual void *alloc (unsigned bytes) final override - { - return ggc_internal_alloc (bytes); - } - virtual void free (void *p) final override - { - return ggc_free (p); - } -}; - -// Return a new range to hold ranges of TYPE. The newly allocated -// range is initialized to VR_UNDEFINED. - -inline vrange * -vrange_allocator::alloc_vrange (tree type) -{ - if (irange::supports_p (type)) - return alloc_irange (2); - - gcc_unreachable (); -} - -// Return a new range with NUM_PAIRS. - -inline irange * -vrange_allocator::alloc_irange (unsigned num_pairs) -{ - // Never allocate 0 pairs. - // Don't allocate 1 either, or we get legacy value_range's. - if (num_pairs < 2) - num_pairs = 2; - - size_t nbytes = sizeof (tree) * 2 * num_pairs; - - // Allocate the irange and required memory for the vector. - void *r = alloc (sizeof (irange)); - tree *mem = static_cast (alloc (nbytes)); - return new (r) irange (mem, num_pairs); -} - -// Return a clone of an irange. - -template <> -inline irange * -vrange_allocator::clone (const irange &src) -{ - irange *r = alloc_irange (src.num_pairs ()); - *r = src; - return r; -} - -// Return a clone of a vrange. - -template <> -inline vrange * -vrange_allocator::clone (const vrange &src) -{ - if (is_a (src)) - return clone (as_a (src)); - - gcc_unreachable (); -} - #endif // GCC_VALUE_RANGE_H