From patchwork Thu Dec 8 22:01:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 1713927 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.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=efFNjINx; 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 ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NSp5c2Hvkz23pG for ; Fri, 9 Dec 2022 09:01:39 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6901B388C5D8 for ; Thu, 8 Dec 2022 22:01:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6901B388C5D8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670536897; bh=gdTalr0EaPF7o03jeRY+JVKOenScK2Idrm6j1SNd9Oc=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=efFNjINxviVSQTBB47J/LaeHkatm4LPqAsdjZ8LgZrHr/SGkpwSbrtqiFgCpXgJWl hL+Dy5+Q7jusF4i1rQ/rVp6ECkV/5xBZxg3nP4mbvM/2jvj7Ua3KlwMf2jcfcRvbbI HN3ZuKCH2fuWZ167GhpHAubBBiSVPXw/n39/knWE= 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 0551C385B1AE for ; Thu, 8 Dec 2022 22:01:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0551C385B1AE Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-97-2J-bbmejOgCinqa5FbUvGw-1; Thu, 08 Dec 2022 17:01:16 -0500 X-MC-Unique: 2J-bbmejOgCinqa5FbUvGw-1 Received: by mail-qt1-f199.google.com with SMTP id fg11-20020a05622a580b00b003a7eaa5cb47so2642911qtb.15 for ; Thu, 08 Dec 2022 14:01:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gdTalr0EaPF7o03jeRY+JVKOenScK2Idrm6j1SNd9Oc=; b=HOmtyV7gnSKWKvuxAxl9mQcQYVjsAuAnm08qFGdCi0AdKA2uhYGfnvDE9EL5riVEWd R2mXDkjlA8LVHtbhBowW2/PvFoCvXHxjulQh/G4CgMdwmuJvDRqcgizkg8hFVlhgXDb+ yp6A0JwYDATOfEyrnZE7Em2FHEfK+4/fDYWyQSkvppHcZyz+cptYBVfxFqPsCQGQ+5EO cgvMMYi7rEpXpa06zPLTMyf1WmHg0OZlorHKBUx3gLPiSWuyxnHf9fyVfhWAAJstWqyx +DqF32x1Nd0Ux9TA3AeN6OfqTM9MfwxeAunMZRyl32MccpwFoKwhpYQ0M4W8U9qB4WGO hJag== X-Gm-Message-State: ANoB5pl8QHcdmoC8nn9SS1szXDX0nnxXKJLReiLrAArqhNPGPkD775z4 qSK2zsBbmQzxwygeljpAJF/qg77p6khMGR2Ptf52BYfeE63a6jC9mcEYchYmBuT9DnMUf7Wc8q/ iCg4tU8T2QOJt2uL7YzWnQfjhNhA1JIq1z4bAnKCwGs+oD4UE4sUsdXfm4P0bN19R6w== X-Received: by 2002:ac8:544b:0:b0:3a5:3136:6be8 with SMTP id d11-20020ac8544b000000b003a531366be8mr4217947qtq.45.1670536875722; Thu, 08 Dec 2022 14:01:15 -0800 (PST) X-Google-Smtp-Source: AA0mqf6npbtNfccuSB8dW8nBbMwkxtJzrFjAWbekzRXk6mU/9nvrrAwy0LPlrP7sQMQu+8uaNRD7Nw== X-Received: by 2002:ac8:544b:0:b0:3a5:3136:6be8 with SMTP id d11-20020ac8544b000000b003a531366be8mr4217893qtq.45.1670536874924; Thu, 08 Dec 2022 14:01:14 -0800 (PST) Received: from jason.com (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id y6-20020a05620a44c600b006fa7b5ea2d1sm20508053qkp.125.2022.12.08.14.01.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Dec 2022 14:01:14 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH RFA] gimplify: avoid unnecessary copy of init array [PR105838] Date: Thu, 8 Dec 2022 17:01:12 -0500 Message-Id: <20221208220112.1700553-1-jason@redhat.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.5 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, RCVD_IN_MSPIKE_H2, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" After the previous patches, I noticed that we were putting the array of strings into .rodata, but then memcpying it into an automatic array, which is pointless; we should be able to use it directly. C++ doesn't allow us to do this for the backing array of an initializer_list, but should be able to do it for the implementation detail array we use to construct the backing array. This doesn't happen automatically because TREE_ADDRESSABLE is set, and gimplify_init_constructor uses that to decide whether to promote a variable to static. Ideally this could use escape analysis to recognize that the address, though taken, never leaves the function; that should allow promotion when we're only using the address for indexing within the function, as in initlist-opt2.C. But in initlist-opt1.C, we're passing the array address to another function, so it definitely escapes; it's only safe in this case because it's calling a standard library function that we know only uses it for indexing. So, a flag seems needed. I first thought to put the flag on the TARGET_EXPR, but the VAR_DECL seems more appropriate. Bikeshedding, or other approaches, welcome. PR c++/105838 gcc/ChangeLog: * tree.h (DECL_NOT_OBSERVABLE): New. * tree-core.h (struct tree_decl_common): Mention it. * gimplify.cc (gimplify_init_constructor): Check it. gcc/cp/ChangeLog: * call.cc (maybe_init_list_as_array): Set DECL_NOT_OBSERVABLE. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt1.C: Check for static array. * g++.dg/tree-ssa/initlist-opt2.C: Likewise. --- gcc/tree-core.h | 3 ++- gcc/tree.h | 5 +++++ gcc/cp/call.cc | 4 +++- gcc/gimplify.cc | 3 ++- gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C | 1 + gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C | 1 + 6 files changed, 14 insertions(+), 3 deletions(-) base-commit: bd0485f20f4794f9787237706a6308473a8e9415 diff --git a/gcc/tree-core.h b/gcc/tree-core.h index e146b133dbd..c0d63632c1e 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1808,7 +1808,8 @@ struct GTY(()) tree_decl_common { In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_HAS_VALUE_EXPR_P. */ unsigned decl_flag_2 : 1; - /* In FIELD_DECL, this is DECL_PADDING_P. */ + /* In FIELD_DECL, this is DECL_PADDING_P. + In VAR_DECL, this is DECL_NOT_OBSERVABLE. */ unsigned decl_flag_3 : 1; /* Logically, these two would go in a theoretical base shared by var and parm decl. */ diff --git a/gcc/tree.h b/gcc/tree.h index 23223ca0c87..7ba88fd16db 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3221,6 +3221,11 @@ extern void decl_fini_priority_insert (tree, priority_type); #define DECL_NONALIASED(NODE) \ (VAR_DECL_CHECK (NODE)->base.nothrow_flag) +/* In a VAR_DECL, nonzero if this variable is not observable by user code (and + so e.g. it can be promoted to static even if it's addressable). */ +#define DECL_NOT_OBSERVABLE(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_common.decl_flag_3) + /* This field is used to reference anything in decl.result and is meant only for use by the garbage collector. */ #define DECL_RESULT_FLD(NODE) \ diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 14aa96dd328..a9052c64265 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -4247,7 +4247,9 @@ maybe_init_list_as_array (tree elttype, tree init) init_elttype = cp_build_qualified_type (init_elttype, TYPE_QUAL_CONST); tree arr = build_array_of_n_type (init_elttype, CONSTRUCTOR_NELTS (init)); - return finish_compound_literal (arr, init, tf_none); + arr = finish_compound_literal (arr, init, tf_none); + DECL_NOT_OBSERVABLE (TARGET_EXPR_SLOT (arr)) = true; + return arr; } /* If we were going to call e.g. vector(initializer_list) starting diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 250782b1140..87c913c48c5 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -5234,7 +5234,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && TREE_READONLY (object) && VAR_P (object) && !DECL_REGISTER (object) - && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)) + && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object) + || DECL_NOT_OBSERVABLE (object)) /* For ctors that have many repeated nonzero elements represented through RANGE_EXPRs, prefer initializing those through runtime loops over copies of large amounts diff --git a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C index 053317b59d8..b1d2d25faf4 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C +++ b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C @@ -4,6 +4,7 @@ // Test that we do range-initialization from const char *. // { dg-final { scan-tree-dump {_M_range_initialize} "gimple" } } +// { dg-final { scan-tree-dump {static const char.*72} "gimple" } } #include #include diff --git a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C index fc928bb5405..6730b758ac7 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C +++ b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C @@ -4,6 +4,7 @@ // Check that we call the basic_string constructor once (and define it once). // { dg-final { scan-tree-dump-times {>::basic_string} 2 "gimple" } } +// { dg-final { scan-tree-dump {static const char.*72} "gimple" } } #include