From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 CEA273857C44 for ; Thu, 10 Mar 2022 04:09:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CEA273857C44 Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-642-tMnOdGl-O8mO34orpR-a_w-1; Wed, 09 Mar 2022 23:09:29 -0500 X-MC-Unique: tMnOdGl-O8mO34orpR-a_w-1 Received: by mail-qt1-f197.google.com with SMTP id m12-20020ac807cc000000b002e05dbf21acso3087194qth.22 for ; Wed, 09 Mar 2022 20:09:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:references:from:cc:in-reply-to :content-transfer-encoding; bh=FWETsavJ1PmivMSekHp8SvnbShhDx/0Kx4lzRaqlECA=; b=oji8iAQ3zGQZ1P9Df+F9cCqH73BUO53HwTKnOVe46L+/LyoV6zz1b2Q9v0v0Gu//5L H43kXvn9Zplvul6WwaUaofLDl+dV7F1FjLY8oX+ykoL4HlhZGMxzUQsUCyXa5mmtziFJ I/dwJsZJUX1oUKZDtKA98iEVDvUODaAbEGPauntf1leHqR4vZ3FumrooW581NeinGEqH u4dDdcAtEkCjsHgen7xqkIexZLDopFT2mmMc7xFDuU6baXUPppOkgiMRJ3rb2gfS/7s6 xzwYodfLSDxy09ecsi4ze94kFYJ576Umir0b59VFnNiBVXLfw3NOlbjEEBTTvxAs5pPk KqVg== X-Gm-Message-State: AOAM530wTlJh8DohWgaLmWG/cdyzdGKfqLxda2evDJww/drgkEEglQaB Nf6YNmMqykRAGBQlNZRxjT57gHHC0aRwH5yzuo1LOfeoip4oVy05JzFuqM8M0KzSnlCALNC9ssv EEEE1s7LWmtqJ7PBVFQ== X-Received: by 2002:a05:6214:f22:b0:435:ba56:7ee1 with SMTP id iw2-20020a0562140f2200b00435ba567ee1mr2273971qvb.89.1646885368451; Wed, 09 Mar 2022 20:09:28 -0800 (PST) X-Google-Smtp-Source: ABdhPJyD6Yj494Rj+Ol7+w6HXo1bBhmL5GLN4CSW7HlimjrYRVO98mjUZdzZwoeC69vqTGGME9mtFg== X-Received: by 2002:a05:6214:f22:b0:435:ba56:7ee1 with SMTP id iw2-20020a0562140f2200b00435ba567ee1mr2273957qvb.89.1646885368083; Wed, 09 Mar 2022 20:09:28 -0800 (PST) Received: from [192.168.1.149] (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 l8-20020a05622a174800b002e1a30533e2sm2140895qtk.8.2022.03.09.20.09.26 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 09 Mar 2022 20:09:26 -0800 (PST) Message-ID: <1de0b889-66e7-8202-5c5e-526b728a36e8@redhat.com> Date: Wed, 9 Mar 2022 23:09:25 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: Re: [PATCH] c++: fold calls to std::move/forward [PR96780] To: Patrick Palka , gcc-patches@gcc.gnu.org References: <20220301220821.1732163-1-ppalka@redhat.com> From: Jason Merrill Cc: Jonathan Wakely In-Reply-To: <20220301220821.1732163-1-ppalka@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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-List-Received-Date: Thu, 10 Mar 2022 04:09:33 -0000 On 3/1/22 18:08, Patrick Palka wrote: > A well-formed call to std::move/forward is equivalent to a cast, but the > former being a function call means it comes with bloated debug info, which > persists even after the call has been inlined away, for an operation that > is never interesting to debug. > > This patch addresses this problem in a relatively ad-hoc way by folding > calls to std::move/forward into casts as part of the frontend's general > expression folding routine. After this patch with -O2 and a non-checking > compiler, debug info size for some testcases decreases by about ~10% and > overall compile time and memory usage decreases by ~2%. Impressive. Which testcases? Do you also want to handle addressof and as_const in this patch, as Jonathan suggested? I think we can do this now, and think about generalizing more in stage 1. > Bootstrapped and regtested on x86_64-pc-linux-gnu, is this something we > want to consider for GCC 12? > > PR c++/96780 > > gcc/cp/ChangeLog: > > * cp-gimplify.cc (cp_fold) : When optimizing, > fold calls to std::move/forward into simple casts. > * cp-tree.h (is_std_move_p, is_std_forward_p): Declare. > * typeck.cc (is_std_move_p, is_std_forward_p): Export. > > gcc/testsuite/ChangeLog: > > * g++.dg/opt/pr96780.C: New test. > --- > gcc/cp/cp-gimplify.cc | 18 ++++++++++++++++++ > gcc/cp/cp-tree.h | 2 ++ > gcc/cp/typeck.cc | 6 ++---- > gcc/testsuite/g++.dg/opt/pr96780.C | 24 ++++++++++++++++++++++++ > 4 files changed, 46 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/opt/pr96780.C > > diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc > index d7323fb5c09..0b009b631c7 100644 > --- a/gcc/cp/cp-gimplify.cc > +++ b/gcc/cp/cp-gimplify.cc > @@ -2756,6 +2756,24 @@ cp_fold (tree x) > > case CALL_EXPR: > { > + if (optimize I think this should check flag_no_inline rather than optimize. > + && (is_std_move_p (x) || is_std_forward_p (x))) > + { > + /* When optimizing, "inline" calls to std::move/forward by > + simply folding them into the corresponding cast. This is > + cheaper than relying on the inliner to do so, and also > + means we avoid generating useless debug info for them at all. > + > + At this point the argument has already been coerced into a > + reference, so it suffices to use a NOP_EXPR to express the > + reference-to-reference cast. */ > + r = CALL_EXPR_ARG (x, 0); > + if (!same_type_p (TREE_TYPE (x), TREE_TYPE (r))) > + r = build_nop (TREE_TYPE (x), r); > + x = cp_fold (r); > + break; > + } > + > int sv = optimize, nw = sv; > tree callee = get_callee_fndecl (x); > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 37d462fca6e..ab828730b03 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -8089,6 +8089,8 @@ extern tree finish_right_unary_fold_expr (tree, int); > extern tree finish_binary_fold_expr (tree, tree, int); > extern tree treat_lvalue_as_rvalue_p (tree, bool); > extern bool decl_in_std_namespace_p (tree); > +extern bool is_std_move_p (tree); > +extern bool is_std_forward_p (tree); > > /* in typeck2.cc */ > extern void require_complete_eh_spec_types (tree, tree); > diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc > index bddc83759ad..a3644f8e7f7 100644 > --- a/gcc/cp/typeck.cc > +++ b/gcc/cp/typeck.cc > @@ -62,8 +62,6 @@ static bool maybe_warn_about_returning_address_of_local (tree, location_t = UNKN > static void error_args_num (location_t, tree, bool); > static int convert_arguments (tree, vec **, tree, int, > tsubst_flags_t); > -static bool is_std_move_p (tree); > -static bool is_std_forward_p (tree); > > /* Do `exp = require_complete_type (exp);' to make sure exp > does not have an incomplete type. (That includes void types.) > @@ -10207,7 +10205,7 @@ decl_in_std_namespace_p (tree decl) > > /* Returns true if FN, a CALL_EXPR, is a call to std::forward. */ > > -static bool > +bool > is_std_forward_p (tree fn) > { > /* std::forward only takes one argument. */ > @@ -10224,7 +10222,7 @@ is_std_forward_p (tree fn) > > /* Returns true if FN, a CALL_EXPR, is a call to std::move. */ > > -static bool > +bool > is_std_move_p (tree fn) > { > /* std::move only takes one argument. */ > diff --git a/gcc/testsuite/g++.dg/opt/pr96780.C b/gcc/testsuite/g++.dg/opt/pr96780.C > new file mode 100644 > index 00000000000..ca24b2802bb > --- /dev/null > +++ b/gcc/testsuite/g++.dg/opt/pr96780.C > @@ -0,0 +1,24 @@ > +// PR c++/96780 > +// Verify calls to std::move/forward are folded away by the frontend. > +// { dg-do compile { target c++11 } } > +// { dg-additional-options "-O -fdump-tree-gimple" } > + > +#include > + > +struct A; > + > +extern A& a; > +extern const A& ca; > + > +void f() { > + auto&& x1 = std::move(a); > + auto&& x2 = std::forward(a); > + auto&& x3 = std::forward(a); > + > + auto&& x4 = std::move(ca); > + auto&& x5 = std::forward(ca); > + auto&& x6 = std::forward(ca); > +} > + > +// { dg-final { scan-tree-dump-not "= std::move" "gimple" } } > +// { dg-final { scan-tree-dump-not "= std::forward" "gimple" } }