From patchwork Wed Jul 3 10:47:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 1956153 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=adacore.com header.i=@adacore.com header.a=rsa-sha256 header.s=google header.b=ZVR3OiJZ; 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 4WDc2G2NR9z1xqh for ; Wed, 3 Jul 2024 20:48:20 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 213963860744 for ; Wed, 3 Jul 2024 10:48:19 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 045073860744 for ; Wed, 3 Jul 2024 10:47:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 045073860744 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 045073860744 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::629 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720003679; cv=none; b=BfJ/gOAW4ouTAB5L1RyNNdcC+eIt+lS459bOIfO1QgplZp7HHEadcly0VetoJCAzWVWRMUVemEV7ouq9+SWyBpoFB9SvhrJeI8WRnfcRUaNQKaevPNT0QO8Jmh9efjmlsHhyuJ2UMTMMfFRv1MPRaouCZZZBaiKgY/74t0K4T/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720003679; c=relaxed/simple; bh=+RyLaJ0+IsY0mjBhOTYYs780UMphO4kx7gOOzGywQY4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=GXyw08zCMwbyDvOE4SD7pLAP8XIj5OGPNc53IOZ09ARbdlKq3/zFYuFviMW7RqQ/iR91UeNzxgbK5nguzEnpXE2lr/r6DPJxLhAggOcBTqPF8c24DCPs/nu5L3luHrzvc0PakkOt4oRbpvszLUPzZfsALUZWjpf2MZdNGJmPoXk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1fb0d7e4ee9so7421345ad.3 for ; Wed, 03 Jul 2024 03:47:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1720003668; x=1720608468; darn=gcc.gnu.org; h=mime-version:user-agent:message-id:in-reply-to:date:references :organization:subject:cc:to:from:from:to:cc:subject:date:message-id :reply-to; bh=b4La6+SHCktBB0wwCTxcCi4upVWVhQj1xCHTvqh34xE=; b=ZVR3OiJZCHXR2cm8BxU1+pbkDx/AUJkdPFP7FvvoDfzp5CTm3NVOorTvsEGSBDv4qU hmkoGKH6ydPZe7jlnEQvzCnfnoRzg47UotT/10CyPBUvQ/f43dxqP6yNt7VgsreA2gIv GMHYoFTk2h8fX+mOQuL2RcvS2LGL5JyDgX8D1krHRWFJnpNA68yf8YaEAcJgVvEyS0Kz PYTP8V3IJuxBO0fv4j0P7Jiff4PSizk3gY+RjsyMcT3DFVcI+ppd7QJ+2aaV4pWSmbNz sswvEHfSoBEeUwDWGpCRtEB+s7+aXZ7SPvk0zcSqHCvrCUlOwUz6LE9lia/H6rT1/wSE 4WxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720003668; x=1720608468; h=mime-version:user-agent:message-id:in-reply-to:date:references :organization:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=b4La6+SHCktBB0wwCTxcCi4upVWVhQj1xCHTvqh34xE=; b=apRbYRpw1riLtPHevmeou7I6r90593HmmQWgHmr/QxIkpG9HK7EuOef/m6uglDayF2 cPaR2WmB8IutaROzCQLbGAFa4P0dM7WtxB7fVM/VISQxXUhLZpWJMQKPneVc4YRRojdT 64jzLPZutqJSD1LNhUumZlACYY5Zy3bPzF/X9wGTKViYza9ixZUXzJFWzMQh/HG2rJXu Sl0VIVh+uVX2afKZ55s0ejUZBQjHLD6Yt8eE3iBHiq+fTAEVzVIw4FK3VKxO+cIkjron xNAcyD6xZLW9FyMh3fgtM8LJSY88ZHXODy5Z2yq866AOHfHJW5Bz8LfoPG0Xgm+IYcBa wozw== X-Gm-Message-State: AOJu0YxQBVnoNx/W24q+B7c07G2iSdz4Ph8eIxuIOH+wtfVrBx9qtUcf 6vOmM0ojSwijU1SqUiuJwkPpZ7PmqDnzOToOrvTw/5VBynSZiGxOcv3omyn1ArrpYZm7aftu7zP CLcWC X-Google-Smtp-Source: AGHT+IEhbJa5HCjeCurA6U9Fg8vSNc1AOcB+fd9op7wCgfPTrmEM3chfPZWTE73+3BT5xSazY0NbUw== X-Received: by 2002:a17:902:d506:b0:1f7:1706:25ba with SMTP id d9443c01a7336-1fadbc84427mr97334545ad.15.1720003667685; Wed, 03 Jul 2024 03:47:47 -0700 (PDT) Received: from free.home ([2804:7f1:218a:d53f:1f12:68c4:3c4:d64a]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fb1e282aacsm7404945ad.127.2024.07.03.03.47.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jul 2024 03:47:47 -0700 (PDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 463AlXe7660338 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 3 Jul 2024 07:47:33 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: Eric Botcazou Subject: [PATCH v2] [FYI] Deduplicate explicitly-sized types (was: Re: [FYI] map packed field type to unpacked for debug info) Organization: Free thinker, does not speak for AdaCore References: Date: Wed, 03 Jul 2024 07:47:33 -0300 In-Reply-To: (Alexandre Oliva's message of "Thu, 13 Jun 2024 21:09:45 -0300") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, WEIRD_QUOTING 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 On Jun 13, 2024, Alexandre Oliva wrote: > I'll be back with an improved version. When make_type_from_size is called with a biased type, for an entity that isn't explicitly biased, we may refrain from reusing the given type because it doesn't seem to match, and then proceed to create an exact copy of that type. Compute earlier the biased status of the expected type, early enough for the suitability check of the given type. Modify for_biased instead of biased_p, so that biased_p remains with the given type's status for the comparison. Avoid creating unnecessary copies of types in make_type_from_size, by caching and reusing previously-created identical types, similarly to the caching of packable types. While at that, fix two vaguely related issues: - TYPE_DEBUG_TYPE's storage is shared with other sorts of references to types, so it shouldn't be accessed unless TYPE_CAN_HAVE_DEBUG_TYPE_P holds. - When we choose the narrower/packed variant of a type as the main debug info type, we fail to output its name if we fail to follow debug type for the TYPE_NAME decl type in modified_type_die. Regstrapped on x86_64-linux-gnu. Pre-approved by Eric. for gcc/ada/ChangeLog * gcc-interface/misc.cc (gnat_get_array_descr_info): Only follow TYPE_DEBUG_TYPE if TYPE_CAN_HAVE_DEBUG_TYPE_P. * gcc-interface/utils.cc (sized_type_hash): New struct. (sized_type_hasher): New struct. (sized_type_hash_table): New variable. (init_gnat_utils): Allocate it. (destroy_gnat_utils): Release it. (sized_type_hasher::equal): New. (hash_sized_type): New. (canonicalize_sized_type): New. (make_type_from_size): Use it to cache packed variants. Fix type reuse by combining biased_p and for_biased earlier. Hold the combination in for_biased, adjusting later uses. for gcc/ChangeLog * dwarf2out.cc (modified_type_die): Follow name's debug type. for gcc/testsuite/ChangeLog * gnat.dg/bias1.adb: Count occurrences of -7.*DW_AT_GNU_bias. --- gcc/ada/gcc-interface/misc.cc | 3 + gcc/ada/gcc-interface/utils.cc | 116 +++++++++++++++++++++++++++++++++++++-- gcc/dwarf2out.cc | 7 ++ gcc/testsuite/gnat.dg/bias1.adb | 3 + 4 files changed, 120 insertions(+), 9 deletions(-) diff --git a/gcc/ada/gcc-interface/misc.cc b/gcc/ada/gcc-interface/misc.cc index 4f6f6774fe702..f77629ce70bf6 100644 --- a/gcc/ada/gcc-interface/misc.cc +++ b/gcc/ada/gcc-interface/misc.cc @@ -967,7 +967,8 @@ gnat_get_array_descr_info (const_tree const_type, while (true) { - if (TYPE_DEBUG_TYPE (source_element_type)) + if (TYPE_CAN_HAVE_DEBUG_TYPE_P (source_element_type) + && TYPE_DEBUG_TYPE (source_element_type)) source_element_type = TYPE_DEBUG_TYPE (source_element_type); else if (TYPE_IS_PADDING_P (source_element_type)) source_element_type diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 0eb9af8d4a2d5..66e3192ea4fbd 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -364,6 +364,26 @@ struct pad_type_hasher : ggc_cache_ptr_hash static GTY ((cache)) hash_table *pad_type_hash_table; +struct GTY((for_user)) sized_type_hash +{ + hashval_t hash; + tree type; +}; + +struct sized_type_hasher : ggc_cache_ptr_hash +{ + static inline hashval_t hash (sized_type_hash *t) { return t->hash; } + static bool equal (sized_type_hash *a, sized_type_hash *b); + + static int + keep_cache_entry (sized_type_hash *&t) + { + return ggc_marked_p (t->type); + } +}; + +static GTY ((cache)) hash_table *sized_type_hash_table; + static tree merge_sizes (tree, tree, tree, bool, bool); static tree fold_bit_position (const_tree); static tree compute_related_constant (tree, tree); @@ -421,6 +441,9 @@ init_gnat_utils (void) /* Initialize the hash table of padded types. */ pad_type_hash_table = hash_table::create_ggc (512); + + /* Initialize the hash table of sized types. */ + sized_type_hash_table = hash_table::create_ggc (512); } /* Destroy data structures of the utils.cc module. */ @@ -443,6 +466,10 @@ destroy_gnat_utils (void) /* Destroy the hash table of padded types. */ pad_type_hash_table->empty (); pad_type_hash_table = NULL; + + /* Destroy the hash table of sized types. */ + sized_type_hash_table->empty (); + sized_type_hash_table = NULL; } /* GNAT_ENTITY is a GNAT tree node for an entity. Associate GNU_DECL, a GCC @@ -1350,6 +1377,79 @@ type_unsigned_for_rm (tree type) return false; } +/* Return true iff the sized types are equivalent. */ + +bool +sized_type_hasher::equal (sized_type_hash *t1, sized_type_hash *t2) +{ + tree type1, type2; + + if (t1->hash != t2->hash) + return false; + + type1 = t1->type; + type2 = t2->type; + + /* We consider sized types equivalent if they have the same name, + size, alignment, RM size, and biasing. The range is not expected + to vary across different-sized versions of the same base + type. */ + bool res + = (TYPE_NAME (type1) == TYPE_NAME (type2) + && TYPE_SIZE (type1) == TYPE_SIZE (type2) + && TYPE_ALIGN (type1) == TYPE_ALIGN (type2) + && TYPE_RM_SIZE (type1) == TYPE_RM_SIZE (type2) + && (TYPE_BIASED_REPRESENTATION_P (type1) + == TYPE_BIASED_REPRESENTATION_P (type2))); + + gcc_assert (!res + || (TYPE_RM_MIN_VALUE (type1) == TYPE_RM_MIN_VALUE (type2) + && TYPE_RM_MAX_VALUE (type1) == TYPE_RM_MAX_VALUE (type2))); + + return res; +} + +/* Compute the hash value for the sized TYPE. */ + +static hashval_t +hash_sized_type (tree type) +{ + hashval_t hashcode; + + hashcode = iterative_hash_expr (TYPE_NAME (type), 0); + hashcode = iterative_hash_expr (TYPE_SIZE (type), hashcode); + hashcode = iterative_hash_hashval_t (TYPE_ALIGN (type), hashcode); + hashcode = iterative_hash_expr (TYPE_RM_SIZE (type), hashcode); + hashcode + = iterative_hash_hashval_t (TYPE_BIASED_REPRESENTATION_P (type), hashcode); + + return hashcode; +} + +/* Look up the sized TYPE in the hash table and return its canonical version + if it exists; otherwise, insert it into the hash table. */ + +static tree +canonicalize_sized_type (tree type) +{ + const hashval_t hashcode = hash_sized_type (type); + struct sized_type_hash in, *h, **slot; + + in.hash = hashcode; + in.type = type; + slot = sized_type_hash_table->find_slot_with_hash (&in, hashcode, INSERT); + h = *slot; + if (!h) + { + h = ggc_alloc (); + h->hash = hashcode; + h->type = type; + *slot = h; + } + + return h->type; +} + /* Given a type TYPE, return a new type whose size is appropriate for SIZE. If TYPE is the best type, return it. Otherwise, make a new type. We only support new integral and pointer types. FOR_BIASED is true if @@ -1383,6 +1483,11 @@ make_type_from_size (tree type, tree size_tree, bool for_biased) biased_p = (TREE_CODE (type) == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type)); + /* FOR_BIASED initially refers to the entity's representation, + not to its type's. The type we're to return must take both + into account. */ + for_biased |= biased_p; + /* Integer types with precision 0 are forbidden. */ if (size == 0) size = 1; @@ -1394,12 +1499,10 @@ make_type_from_size (tree type, tree size_tree, bool for_biased) || size > (Enable_128bit_Types ? 128 : LONG_LONG_TYPE_SIZE)) break; - biased_p |= for_biased; - /* The type should be an unsigned type if the original type is unsigned or if the lower bound is constant and non-negative or if the type is biased, see E_Signed_Integer_Subtype case of gnat_to_gnu_entity. */ - if (type_unsigned_for_rm (type) || biased_p) + if (type_unsigned_for_rm (type) || for_biased) new_type = make_unsigned_type (size); else new_type = make_signed_type (size); @@ -1409,9 +1512,12 @@ make_type_from_size (tree type, tree size_tree, bool for_biased) /* Copy the name to show that it's essentially the same type and not a subrange type. */ TYPE_NAME (new_type) = TYPE_NAME (type); - TYPE_BIASED_REPRESENTATION_P (new_type) = biased_p; + TYPE_BIASED_REPRESENTATION_P (new_type) = for_biased; SET_TYPE_RM_SIZE (new_type, bitsize_int (size)); - return new_type; + + return (TYPE_NAME (new_type) + ? canonicalize_sized_type (new_type) + : new_type); case RECORD_TYPE: /* Do something if this is a fat pointer, in which case we diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index c1814fc242ce3..357efaa5990e2 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -14051,8 +14051,11 @@ modified_type_die (tree type, int cv_quals, bool reverse, && (qualified_type == TYPE_MAIN_VARIANT (type) || (cv_quals == TYPE_UNQUALIFIED))) || (TREE_CODE (name) == TYPE_DECL - && TREE_TYPE (name) == qualified_type - && DECL_NAME (name)))) + && DECL_NAME (name) + && (TREE_TYPE (name) == qualified_type + || (lang_hooks.types.get_debug_type + && (lang_hooks.types.get_debug_type (TREE_TYPE (name)) + == qualified_type)))))) { if (TREE_CODE (name) == TYPE_DECL) /* Could just call add_name_and_src_coords_attributes here, diff --git a/gcc/testsuite/gnat.dg/bias1.adb b/gcc/testsuite/gnat.dg/bias1.adb index 016a159b692da..d9a00a1aa4588 100644 --- a/gcc/testsuite/gnat.dg/bias1.adb +++ b/gcc/testsuite/gnat.dg/bias1.adb @@ -1,6 +1,7 @@ -- { dg-do compile } -- { dg-options "-cargs -g -dA -gnatws -fgnat-encodings=gdb -margs" } -- { dg-final { scan-assembler "DW_AT_GNU_bias" } } +-- { dg-final { scan-assembler-times "-7.*DW_AT_GNU_bias" 1 } } procedure Bias1 is type Small is range -7 .. -4; @@ -31,4 +32,4 @@ procedure Bias1 is begin null; -end Bias1; \ No newline at end of file +end Bias1;