[COMMITTED] ada: Revert to constrained allocation for string concatenation
Marc Poulhiès
poulhies@adacore.com
Thu Jan 5 14:39:07 GMT 2023
From: Eric Botcazou <ebotcazou@adacore.com>
Using an unconstrained allocation is less efficient in the general case.
gcc/ada/
* exp_ch3.adb (Expand_N_Object_Declaration): New local variable used
throughout instead of testing Is_Special_Return_Object every time.
Do not rename an OK_To_Rename object for a special return object.
* exp_ch4.adb (Expand_Concatenate): Revert to constrained allocation
if the result is allocated on the secondary stack.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_ch3.adb | 29 +++++++++-------
gcc/ada/exp_ch4.adb | 82 +++++++++++++++++++--------------------------
2 files changed, 50 insertions(+), 61 deletions(-)
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 7dbf82671aa..a76acf34d66 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6230,6 +6230,11 @@ package body Exp_Ch3 is
Base_Typ : constant Entity_Id := Base_Type (Typ);
Next_N : constant Node_Id := Next (N);
+ Special_Ret_Obj : constant Boolean := Is_Special_Return_Object (Def_Id);
+ -- If this is a special return object, it will be allocated differently
+ -- and ultimately rewritten as a renaming, so initialization activities
+ -- need to be deferred until after that is done.
+
function Build_Equivalent_Aggregate return Boolean;
-- If the object has a constrained discriminated type and no initial
-- value, it may be possible to build an equivalent aggregate instead,
@@ -7343,7 +7348,7 @@ package body Exp_Ch3 is
end if;
end if;
- if not Is_Special_Return_Object (Def_Id) then
+ if not Special_Ret_Obj then
Default_Initialize_Object (Init_After);
end if;
@@ -7403,7 +7408,7 @@ package body Exp_Ch3 is
Expander_Mode_Restore;
end if;
- if not Is_Special_Return_Object (Def_Id) then
+ if not Special_Ret_Obj then
Convert_Aggr_In_Object_Decl (N);
end if;
@@ -7479,7 +7484,7 @@ package body Exp_Ch3 is
-- case, the expansion of the return statement will take care of
-- creating the object (via allocator) and initializing it.
- if Is_Special_Return_Object (Def_Id) then
+ if Special_Ret_Obj then
-- If the type needs finalization and is not inherently
-- limited, then the target is adjusted after the copy
@@ -7791,7 +7796,7 @@ package body Exp_Ch3 is
if Present (Tag_Assign) then
if Present (Following_Address_Clause (N)) then
Ensure_Freeze_Node (Def_Id);
- elsif not Is_Special_Return_Object (Def_Id) then
+ elsif not Special_Ret_Obj then
Insert_Action_After (Init_After, Tag_Assign);
end if;
@@ -7931,7 +7936,7 @@ package body Exp_Ch3 is
and then
((not Is_Library_Level_Entity (Def_Id)
and then Is_Captured_Function_Call (Expr_Q)
- and then (not Is_Special_Return_Object (Def_Id)
+ and then (not Special_Ret_Obj
or else Is_Related_To_Func_Return
(Entity (Prefix (Expr_Q))))
and then not Is_Class_Wide_Type (Typ))
@@ -7945,12 +7950,14 @@ package body Exp_Ch3 is
-- Obj : Typ renames Expr;
- or else OK_To_Rename_Ref (Expr_Q)
+ or else (OK_To_Rename_Ref (Expr_Q)
+ and then not Special_Ret_Obj)
-- Likewise if it is a slice of such a variable
or else (Nkind (Expr_Q) = N_Slice
- and then OK_To_Rename_Ref (Prefix (Expr_Q))));
+ and then OK_To_Rename_Ref (Prefix (Expr_Q))
+ and then not Special_Ret_Obj));
-- If the type needs finalization and is not inherently limited,
-- then the target is adjusted after the copy and attached to the
@@ -7971,9 +7978,7 @@ package body Exp_Ch3 is
Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
Typ => Base_Typ);
- if Present (Adj_Call)
- and then not Is_Special_Return_Object (Def_Id)
- then
+ if Present (Adj_Call) and then not Special_Ret_Obj then
Insert_Action_After (Init_After, Adj_Call);
end if;
end if;
@@ -8601,9 +8606,7 @@ package body Exp_Ch3 is
end;
end if;
- if Is_Special_Return_Object (Def_Id)
- and then Present (Tag_Assign)
- then
+ if Special_Ret_Obj and then Present (Tag_Assign) then
Insert_Action_After (Init_After, Tag_Assign);
end if;
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 148b160b792..d9103b3387b 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -2728,7 +2728,6 @@ package body Exp_Ch4 is
Len : Unat;
J : Nat;
Clen : Node_Id;
- Decl : Node_Id;
Set : Boolean;
-- Start of processing for Expand_Concatenate
@@ -3255,32 +3254,10 @@ package body Exp_Ch4 is
Set_Is_Internal (Ent);
Set_Debug_Info_Needed (Ent);
- -- If the bound is statically known to be out of range, we do not want
- -- to abort, we want a warning and a constraint error at run time. Note
- -- that we have arranged that the result will not be treated as a static
- -- constant, so we won't get an illegality during the insertion. We also
- -- enable all checks (in particular range checks) in case the bounds of
- -- Subtyp_Ind are out of range.
-
- Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Ent,
- Object_Definition => Subtyp_Ind);
- Insert_Action (Cnode, Decl);
-
- -- If the result of the concatenation appears as the initializing
- -- expression of an object declaration, we can just rename the
- -- result, rather than copying it.
-
- Set_OK_To_Rename (Ent);
-
-- If we are concatenating strings and the current scope already uses
-- the secondary stack, allocate the result also on the secondary stack
-- to avoid putting too much pressure on the primary stack.
- -- We use an unconstrained allocation, i.e. we also allocate the bounds,
- -- so that the result can be renamed in all contexts.
-
-- Don't do this if -gnatd.h is set, as this will break the wrapping of
-- Cnode in an Expression_With_Actions, see Expand_N_Op_Concat.
@@ -3291,33 +3268,32 @@ package body Exp_Ch4 is
then
-- Generate:
-- subtype Axx is String (<low-bound> .. <high-bound>)
- -- type Ayy is access String;
+ -- type Ayy is access Axx;
-- Rxx : Ayy := new <Axx> [storage_pool = ss_pool];
- -- Sxx : String renames Rxx.all;
+ -- Sxx : Axx renames Rxx.all;
declare
ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
- Alloc : Node_Id;
- Deref : Node_Id;
- Temp : Entity_Id;
+ Alloc : Node_Id;
+ Temp : Entity_Id;
begin
- Insert_Action (Decl,
+ Insert_Action (Cnode,
Make_Subtype_Declaration (Loc,
Defining_Identifier => ConstrT,
Subtype_Indication => Subtyp_Ind),
Suppress => All_Checks);
- Freeze_Itype (ConstrT, Decl);
+ Freeze_Itype (ConstrT, Cnode);
- Insert_Action (Decl,
+ Insert_Action (Cnode,
Make_Full_Type_Declaration (Loc,
Defining_Identifier => Acc_Typ,
Type_Definition =>
Make_Access_To_Object_Definition (Loc,
- Subtype_Indication => New_Occurrence_Of (Atyp, Loc))),
+ Subtype_Indication => New_Occurrence_Of (ConstrT, Loc))),
Suppress => All_Checks);
Mutate_Ekind (Acc_Typ, E_Access_Type);
@@ -3335,33 +3311,43 @@ package body Exp_Ch4 is
Set_No_Initialization (Alloc);
Temp := Make_Temporary (Loc, 'R', Alloc);
- Insert_Action (Decl,
+ Insert_Action (Cnode,
Make_Object_Declaration (Loc,
Defining_Identifier => Temp,
Object_Definition => New_Occurrence_Of (Acc_Typ, Loc),
Expression => Alloc),
Suppress => All_Checks);
- Deref :=
- Make_Explicit_Dereference (Loc,
- Prefix => New_Occurrence_Of (Temp, Loc));
- Set_Etype (Deref, Atyp);
-
- Rewrite (Decl,
+ Insert_Action (Cnode,
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => Ent,
- Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
- Name => Deref));
-
- -- We do not analyze this renaming declaration because this would
- -- change the subtype of Ent back to a constrained string.
-
- Set_Etype (Ent, Atyp);
- Set_Renamed_Object (Ent, Deref);
- Set_Analyzed (Decl);
+ Subtype_Mark => New_Occurrence_Of (ConstrT, Loc),
+ Name =>
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Temp, Loc))),
+ Suppress => All_Checks);
end;
+
+ else
+ -- If the bound is statically known to be out of range, we do not
+ -- want to abort, we want a warning and a runtime constraint error.
+ -- Note that we have arranged that the result will not be treated
+ -- as a static constant, so we won't get an illegality during this
+ -- insertion. We also enable checks (in particular range checks) in
+ -- case the bounds of Subtyp_Ind are out of range.
+
+ Insert_Action (Cnode,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Ent,
+ Object_Definition => Subtyp_Ind));
end if;
+ -- If the result of the concatenation appears as the initializing
+ -- expression of an object declaration, we can just rename the
+ -- result, rather than copying it.
+
+ Set_OK_To_Rename (Ent);
+
-- Catch the static out of range case now
if Raises_Constraint_Error (High_Bound)
--
2.34.1
More information about the Gcc-patches
mailing list