From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7871) id 4AC503858C83; Tue, 3 Jan 2023 09:34:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4AC503858C83 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1672738449; bh=7qL255qSiRzgGHpclAdFD0PJdXSwYHfMNu0UUUn2cN0=; h=From:To:Subject:Date:From; b=SQR4G3hG8luMDcmbQhtgVRUFO+Nr1rKZzfUiHjC6gIQ/dVAxTaUoLDCLfFi+HrQdu mC+odQZp4sDqJb+COiTGwLohvWdUhjgBkis/ny5iqithFUXqXRpapRC4Og5PC/VA/q ObsI0c+K+xU/T6fTSRQKDYzGVJVcduAmkK5d8uBU= MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Marc Poulhi?s To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4965] ada: Adapt frontend optimization for aggregate assignment X-Act-Checkin: gcc X-Git-Author: =?utf-8?q?Marc_Poulhi=C3=A8s?= X-Git-Refname: refs/heads/master X-Git-Oldrev: 48d9f7cb215f1af996788aee07808339a786a18d X-Git-Newrev: 742084ada1e0974f5c7491fda65702e45bd07848 Message-Id: <20230103093409.4AC503858C83@sourceware.org> Date: Tue, 3 Jan 2023 09:34:09 +0000 (GMT) List-Id: https://gcc.gnu.org/g:742084ada1e0974f5c7491fda65702e45bd07848 commit r13-4965-g742084ada1e0974f5c7491fda65702e45bd07848 Author: Marc Poulhiès Date: Fri Nov 25 14:52:04 2022 +0100 ada: Adapt frontend optimization for aggregate assignment The frontend currently relies on gigi to use efficient assignment in particular cases like: Some_Var.all := (others => (others => 0)); gigi would use memset to clear memory pointed to by Some_Var. In the case of an access with a Designated_Storage_Model aspect with a Copy_To procedure, memset can't be used directly. Instead of simply disabling this frontend/gigi optimization and having the frontend emit several assignments, a temporary is used (through the new Build_Assignment_With_Temporary): gigi can still memset it, and this temporary is then copied into the original target (and the regular storage model mechanism handles it). gcc/ada/ * exp_aggr.adb (Build_Assignment_With_Temporary): New. (Expand_Array_Aggregate): Tune backend optimization and insert a temporary in the case of an access with Designated_Storage_Model aspect. (Convert_Array_Aggr_In_Allocator): Likewise. Diff: --- gcc/ada/exp_aggr.adb | 106 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 14 deletions(-) diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 4d8bb817b80..30f32a78453 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -62,6 +62,7 @@ with Sem_Eval; use Sem_Eval; with Sem_Mech; use Sem_Mech; with Sem_Res; use Sem_Res; with Sem_Util; use Sem_Util; +use Sem_Util.Storage_Model_Support; with Sinfo; use Sinfo; with Sinfo.Nodes; use Sinfo.Nodes; with Sinfo.Utils; use Sinfo.Utils; @@ -75,6 +76,15 @@ with Warnsw; use Warnsw; package body Exp_Aggr is + function Build_Assignment_With_Temporary + (Target : Node_Id; + Typ : Node_Id; + Source : Node_Id) return List_Id; + -- Returns a list of actions to assign Source to Target of type Typ using + -- an extra temporary: + -- Tmp := Source; + -- Target := Tmp; + type Case_Bounds is record Choice_Lo : Node_Id; Choice_Hi : Node_Id; @@ -2508,6 +2518,42 @@ package body Exp_Aggr is return New_Code; end Build_Array_Aggr_Code; + ------------------------------------- + -- Build_Assignment_With_Temporary -- + ------------------------------------- + + function Build_Assignment_With_Temporary + (Target : Node_Id; + Typ : Node_Id; + Source : Node_Id) return List_Id + is + Loc : constant Source_Ptr := Sloc (Source); + + Aggr_Code : List_Id; + Tmp : Entity_Id; + Tmp_Decl : Node_Id; + + begin + Tmp := Make_Temporary (Loc, 'A', Source); + Tmp_Decl := + Make_Object_Declaration (Loc, + Defining_Identifier => Tmp, + Object_Definition => New_Occurrence_Of (Typ, Loc)); + Set_No_Initialization (Tmp_Decl, True); + + Aggr_Code := New_List (Tmp_Decl); + Append_To (Aggr_Code, + Make_OK_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Tmp, Loc), + Expression => Source)); + + Append_To (Aggr_Code, + Make_OK_Assignment_Statement (Loc, + Name => Target, + Expression => New_Occurrence_Of (Tmp, Loc))); + return Aggr_Code; + end Build_Assignment_With_Temporary; + ---------------------------- -- Build_Record_Aggr_Code -- ---------------------------- @@ -4514,15 +4560,29 @@ package body Exp_Aggr is New_Aggr := New_Copy_Tree (Aggr); Set_Expansion_Delayed (New_Aggr, False); - Aggr_Code := - New_List ( - Make_OK_Assignment_Statement (Sloc (New_Aggr), - Name => Target, - Expression => New_Aggr)); + -- In the case of Target's type using the Designated_Storage_Model + -- aspect with a Copy_To procedure, insert a temporary and have the + -- back end handle the assignment to it. Copy the result to the + -- original target. + + if Has_Designated_Storage_Model_Aspect + (Etype (Prefix (Expression (Target)))) + and then Present (Storage_Model_Copy_To + (Storage_Model_Object + (Etype (Prefix (Expression (Target)))))) + then + Aggr_Code := Build_Assignment_With_Temporary (Target, + Typ, New_Aggr); + else + Aggr_Code := + New_List ( + Make_OK_Assignment_Statement (Sloc (New_Aggr), + Name => Target, + Expression => New_Aggr)); + end if; -- Or else, generate component assignments to it, as for an aggregate -- that appears on the right-hand side of an assignment statement. - else Aggr_Code := Build_Array_Aggr_Code (Aggr, @@ -7065,16 +7125,34 @@ package body Exp_Aggr is and then not Is_Possibly_Unaligned_Slice (Target) and then Aggr_Assignment_OK_For_Backend (N) then - if Maybe_In_Place_OK then - return; - end if; - Aggr_Code := - New_List ( - Make_Assignment_Statement (Loc, - Name => Target, - Expression => New_Copy_Tree (N))); + -- In the case of an assignment using an access with the + -- Designated_Storage_Model aspect with a Copy_To procedure, + -- insert a temporary and have the back end handle the assignment + -- to it. Copy the result to the original target. + + if Parent_Kind = N_Assignment_Statement + and then Nkind (Name (Parent_Node)) = N_Explicit_Dereference + and then Has_Designated_Storage_Model_Aspect + (Etype (Prefix (Name (Parent_Node)))) + and then Present (Storage_Model_Copy_To + (Storage_Model_Object + (Etype (Prefix (Name (Parent_Node)))))) + then + Aggr_Code := Build_Assignment_With_Temporary (Target, + Typ, New_Copy_Tree (N)); + else + if Maybe_In_Place_OK then + return; + end if; + Aggr_Code := + New_List ( + Make_Assignment_Statement (Loc, + Name => Target, + Expression => New_Copy_Tree (N))); + + end if; else Aggr_Code := Build_Array_Aggr_Code (N,