From patchwork Mon Sep 12 08:19:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marc_Poulhi=C3=A8s?= X-Patchwork-Id: 1152 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5044:0:0:0:0:0 with SMTP id h4csp1781780wrt; Mon, 12 Sep 2022 01:32:29 -0700 (PDT) X-Google-Smtp-Source: AA6agR44f1HVCRyStu0cd2UZfRFLnzIcMovQOdMZCsv2XYoeQTKyV/FLxfSMP6bEkLGF5rUsulBV X-Received: by 2002:aa7:ccd3:0:b0:44e:6c07:6b8 with SMTP id y19-20020aa7ccd3000000b0044e6c0706b8mr21511678edt.426.1662971548754; Mon, 12 Sep 2022 01:32:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1662971548; cv=none; d=google.com; s=arc-20160816; b=M499h/oXiRn7yZydSpZfQy/w3BuY/6QBQHUGaCaYWakkIri1CbNVlf4mNdK+gEEThS YP1+wFrdiraf7lFQdW4iCWQKss9MLJunQjSy5NrauTLD5SNtyR4prnS8KB2/04rFK3MB /8DHBtsX1g6VYIEZTLNNyndwViALewCHEc+fAq51cyW/NMIVAXqaH5j0uGhUBvP82qzH 9iY8GN3UZC+Tjy54ad6hEH85tEfAibtJsw0nDiHO/fFCXYs13i5dfKHEym457iyyT/wr 3qKsgEi9UVSZR2w0JbWmhIpsD41mI+1jzZp3nG8eddxMHPHh7/ihTH0E5v6g9jgWOFhH 9/dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-disposition:mime-version:message-id:subject:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=CPS5edPwsswVX5AyvuqCwLS806k24FnYwg3vcThAvYE=; b=w74UyRMb3Ic8mT37XLv+KzOchAsIUsQU3gbY5j0sMW2/RaEr/IcLQnP4F/bVY24GlN wEy4HM603ihSeOmKzu5S8JrTKw/vuGsuYv2o9VkAR4oQLJp6lAVynaYII6Mckta7enpy AK9XVbWorC0B2x+gOl2cxd7/XAH2sRDLpVtlI3zdY8kCIMbMds60BHCOI8AZ+GSUFag+ XKZzOgqZKJh77tN6NsIh/kJagr/Sr1PczIrgAqBLdOhoVJgICTG7kjtDopp08x/6o3nY IpPeVcyNmpqDOluJ8I4N33X3JfG5E1aRh2kaYe5SduGNYrsG0DPvozrPdXbHhgEl0Pqi zoqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kqDH23cT; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id d10-20020aa7c1ca000000b0044e78dbb615si5981814edp.379.2022.09.12.01.32.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 01:32:28 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kqDH23cT; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 32C6D39730FB for ; Mon, 12 Sep 2022 08:25:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 32C6D39730FB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1662971115; bh=CPS5edPwsswVX5AyvuqCwLS806k24FnYwg3vcThAvYE=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=kqDH23cTAL8G9DgOkmRAcviGrJ/p5VtMCoiiXApTGXcAMT3jOGmlY1kxvNlbCdUbA QuYZ+zvT8FWpMXGOM0kcJvp6PZadvWUmnz5cXPIi+4+HUZaDTViKVwewATFeF62DN9 TyTjE6/DZ5VbXJiv1i3qUDhg+AUzC31XJ4l0Jbnk= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by sourceware.org (Postfix) with ESMTPS id 956793851145 for ; Mon, 12 Sep 2022 08:19:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 956793851145 Received: by mail-wr1-x42f.google.com with SMTP id o25so14061715wrf.9 for ; Mon, 12 Sep 2022 01:19:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date; bh=CPS5edPwsswVX5AyvuqCwLS806k24FnYwg3vcThAvYE=; b=f2PUcaqlh34fFbjnvnhX7/QkGlyNxHBTmZZmdBFZc8zaQr7FxRGgWa5tjb0GlkJm4O 02bHVB1eWrb28RB094QEZ5vDrOjaiuMuP9VPwvDo9HExtdsyOzJ02LeQY4K7yvJdNZ15 OiBpf47U4qUchxODcc8WdcdsY+L3heLkOnWL3Tlb+OWa4nBzsxoUaYm+B+iqUUPU53jc Vh5plA/i9XnHHgKX6nQax0UgA/AidsWrLzAWzK3nd+hVS0pN9glHKo6HHHsQaPWQtbN/ D3It5uFQBUTqoeUfJYiwPqpTIiwSo/40yva/D7YifjsKkBllwUAuYPeiSIKMzdtoy4Nn A0ew== X-Gm-Message-State: ACgBeo2hCjHWytD+CEBqBfDamLRFdS0l6tt08s9cJobvQUu9+z4bSa7X 1APtJbjX5CZ0S7FQdPjhjaSJZydrSrDUDw== X-Received: by 2002:a5d:6543:0:b0:22a:3877:7bc9 with SMTP id z3-20020a5d6543000000b0022a38777bc9mr8858329wrv.142.1662970780442; Mon, 12 Sep 2022 01:19:40 -0700 (PDT) Received: from poulhies-Precision-5550 (lmontsouris-659-1-24-67.w81-250.abo.wanadoo.fr. [81.250.175.67]) by smtp.gmail.com with ESMTPSA id b14-20020a5d634e000000b00228da396f9dsm6503427wrw.84.2022.09.12.01.19.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 01:19:39 -0700 (PDT) Date: Mon, 12 Sep 2022 10:19:39 +0200 To: gcc-patches@gcc.gnu.org Subject: [Ada] Temporary tweak new expansion of contracts Message-ID: <20220912081939.GA1513086@poulhies-Precision-5550> MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.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, 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: =?utf-8?q?Marc_Poulhi=C3=A8s_via_Gcc-patches?= From: =?utf-8?q?Marc_Poulhi=C3=A8s?= Reply-To: Marc =?iso-8859-1?q?Poulhi=E8s?= Cc: Eric Botcazou Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1743752054804976970?= X-GMAIL-MSGID: =?utf-8?q?1743752054804976970?= In the case of a function, the new expansion of contracts makes use of an extended return statement to store the result of the function in the return object while the post-conditions are evaluated. Unfortunately GNAT does not elide the copy of the return object for extended return statements for the time being, so this scheme incurs an extra copy of the return value on the primary or secondary stack, as well as an additional pair of calls to Adjust/Finalize when the return type needs finalization. This temporarily changes the expansion to use a block statement containing a renaming, which does not incur the extra copy provided that it is manually adjusted to be recognized by the existing "tail call" optimization present in the Expand_Simple_Function_Return routine. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * contracts.adb (uild_Subprogram_Contract_Wrapper): Remove useless local variable. In the case of a function, replace the extended return statement by a block statement declaring a renaming of the call to the local subprogram after removing side effects manually. (Expand_Subprogram_Contract): Adjust description accordingly. * exp_ch6.adb (Expand_Ctrl_Function_Call): Rewrite obsolete comment and do not apply the transformation twice. * sem_attr.adb (Analyze_Attribute_Old_Result): Now expect a block statement instead of an extended return statement. diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -1577,7 +1577,6 @@ package body Contracts is Decls : List_Id; Result : Entity_Id) is - Actuals : constant List_Id := Empty_List; Body_Decl : constant Entity_Id := Unit_Declaration_Node (Body_Id); Loc : constant Source_Ptr := Sloc (Body_Decl); Spec_Id : constant Entity_Id := Corresponding_Spec (Body_Decl); @@ -1606,11 +1605,11 @@ package body Contracts is Ret_Type := Etype (Subp_Id); -- Generate the contracts wrapper by moving the original declarations - -- and statements within a local subprogram and calling it within - -- an extended return to preserve the result for the purpose of - -- evaluating postconditions, contracts, type invariants, etc. + -- and statements within a local subprogram, calling it and possibly + -- preserving the result for the purpose of evaluating postconditions, + -- contracts, type invariants, etc. - -- Generate: + -- In the case of a function, generate: -- -- function Original_Func (X : in out Integer) return Typ is -- @@ -1623,13 +1622,25 @@ package body Contracts is -- end; -- -- begin - -- return - -- Result_Obj : constant Typ := _Wrapped_Statements - -- do + -- declare + -- type Axx is access all Typ; + -- Rxx : constant Axx := _Wrapped_Statements'reference; + -- Result_Obj : Typ renames Rxx.all; + -- + -- begin -- - -- end return; + -- return Rxx.all; + -- end; -- end; -- + -- This sequence is recognized by Expand_Simple_Function_Return as a + -- tail call, in other words equivalent to "return _Wrapped_Statements;" + -- and thus the copy to the anonymous return object is elided, including + -- a pair of calls to Adjust/Finalize for types requiring finalization. + + -- Note that an extended return statement does not yield the same result + -- because the copy of the return object is not elided by GNAT for now. + -- Or, in the case of a procedure: -- -- procedure Original_Proc (X : in out Integer) is @@ -1680,8 +1691,7 @@ package body Contracts is Set_Declarations (Body_Decl, Decls); Set_Handled_Statement_Sequence (Body_Decl, Make_Handled_Sequence_Of_Statements (Loc, - End_Label => Make_Identifier (Loc, Chars (Wrapper_Id)), - Statements => New_List)); + End_Label => Make_Identifier (Loc, Chars (Wrapper_Id)))); -- Move certain flags which are relevant to the body @@ -1697,7 +1707,7 @@ package body Contracts is Set_Has_Pragma_Inline_Always (Wrapper_Id, Has_Pragma_Inline_Always (Subp_Id)); - -- Generate call to the wrapper + -- Prepend a call to the wrapper when the subprogram is a procedure if No (Ret_Type) or else Ret_Type = Standard_Void_Type then Prepend_To (Stmts, @@ -1706,25 +1716,64 @@ package body Contracts is Set_Statements (Handled_Statement_Sequence (Body_Decl), Stmts); - -- Generate the post-execution statements and the extended return - -- when the subprogram being wrapped is a function. + -- Declare a renaming of the result of the call to the wrapper and + -- append a return of the result of the call when the subprogram is + -- a function, after manually removing the side effects. Note that + -- we cannot call Remove_Side_Effects here because nothing has been + -- analyzed yet and we cannot return the renaming itself because + -- Expand_Simple_Function_Return expects an explicit dereference. else - Set_Statements (Handled_Statement_Sequence (Body_Decl), New_List ( - Make_Extended_Return_Statement (Loc, - Return_Object_Declarations => New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Result, - Object_Definition => - New_Occurrence_Of (Ret_Type, Loc), - Expression => - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (Wrapper_Id, Loc), - Parameter_Associations => Actuals))), - Handled_Statement_Sequence => - Make_Handled_Sequence_Of_Statements (Loc, - Statements => Stmts)))); + declare + A_Id : constant Node_Id := Make_Temporary (Loc, 'A'); + R_Id : constant Node_Id := Make_Temporary (Loc, 'R'); + + begin + Set_Statements (Handled_Statement_Sequence (Body_Decl), New_List ( + Make_Block_Statement (Loc, + + Declarations => New_List ( + Make_Full_Type_Declaration (Loc, + Defining_Identifier => A_Id, + Type_Definition => + Make_Access_To_Object_Definition (Loc, + All_Present => True, + Null_Exclusion_Present => True, + Subtype_Indication => + New_Occurrence_Of (Ret_Type, Loc))), + + Make_Object_Declaration (Loc, + Defining_Identifier => R_Id, + Object_Definition => New_Occurrence_Of (A_Id, Loc), + Constant_Present => True, + Expression => + Make_Reference (Loc, + Make_Function_Call (Loc, + Name => New_Occurrence_Of (Wrapper_Id, Loc)))), + + Make_Object_Renaming_Declaration (Loc, + Defining_Identifier => Result, + Subtype_Mark => New_Occurrence_Of (Ret_Type, Loc), + Name => + Make_Explicit_Dereference (Loc, + New_Occurrence_Of (R_Id, Loc)))), + + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => Stmts)))); + + Append_To (Stmts, + Make_Simple_Return_Statement (Loc, + Expression => + Make_Explicit_Dereference (Loc, + New_Occurrence_Of (R_Id, Loc)))); + + -- It is required for Is_Related_To_Func_Return to return True + -- that the temporary Rxx be related to the expression of the + -- simple return statement built just above. + + Set_Related_Expression (R_Id, Expression (Last (Stmts))); + end; end if; end Build_Subprogram_Contract_Wrapper; @@ -3387,16 +3436,16 @@ package body Contracts is -- -- - -- function _wrapped_statements (...) return ... is + -- function _Wrapped_Statements (...) return ... is -- -- begin -- - -- end _wrapped_statements; + -- end _Wrapped_Statements; -- begin - -- return - -- Result : ... := _wrapped_statements - -- do + -- declare + -- Result : ... renames _Wrapped_Statements; + -- begin -- -- -- @@ -3405,7 +3454,7 @@ package body Contracts is -- --