* [Ada] Use out-of-line string concatenation at library level
@ 2017-04-25 9:46 Arnaud Charlet
0 siblings, 0 replies; only message in thread
From: Arnaud Charlet @ 2017-04-25 9:46 UTC (permalink / raw)
To: gcc-patches; +Cc: Eric Botcazou
[-- Attachment #1: Type: text/plain, Size: 1461 bytes --]
String concatenation can be implemented either in-line or out-of-line by the
compiler, depending on the optimization level and other factors. But doing
in-line concatenation at library level is undesirable in general and the
compiler already avoids it for simple declarations:
S : String := S1 & S2; -- out-of-line at all optimization levels
but not for slightly more complex ones:
S : String := Ada.Characters.Handling.To_Upper (S1 & S2);
which are implemented in-line for -O1 and above.
This patch changes the second case to using out-of-line concatenation at all
optimization levels which, among other things, generates more compact code.
The following package must always use out-of-line concatenation:
with Ada.Characters.Handling;
package P is
Scope: constant String := Ada.Characters.Handling.To_Upper ("P");
function Full_String return String;
end P;
package body P is
Full_Scope : constant String
:= Ada.Characters.Handling.To_Upper (Scope & ".body");
function Full_String return String is (Full_Scope);
end P;
Tested on x86_64-pc-linux-gnu, committed on trunk
2017-04-25 Eric Botcazou <ebotcazou@adacore.com>
* exp_ch4.adb (Library_Level_Target): New function.
(Expand_Concatenate): When optimization is enabled, also expand
the operation out-of-line if the concatenation is present within
the expression of the declaration of a library-level object and
not only if it is the expression of the declaration.
[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 3742 bytes --]
Index: exp_ch4.adb
===================================================================
--- exp_ch4.adb (revision 247135)
+++ exp_ch4.adb (working copy)
@@ -2767,6 +2767,10 @@
-- Set True during generation of the assignments of operands into
-- result once an operand known to be non-null has been seen.
+ function Library_Level_Target return Boolean;
+ -- Return True if the concatenation is within the expression of the
+ -- declaration of a library-level object.
+
function Make_Artyp_Literal (Val : Nat) return Node_Id;
-- This function makes an N_Integer_Literal node that is returned in
-- analyzed form with the type set to Artyp. Importantly this literal
@@ -2782,6 +2786,30 @@
function To_Ityp (X : Node_Id) return Node_Id;
-- The inverse function (uses Val in the case of enumeration types)
+ --------------------------
+ -- Library_Level_Target --
+ --------------------------
+
+ function Library_Level_Target return Boolean is
+ P : Node_Id := Parent (Cnode);
+
+ begin
+ while Present (P) loop
+ if Nkind (P) = N_Object_Declaration then
+ return Is_Library_Level_Entity (Defining_Identifier (P));
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (P) then
+ return False;
+ end if;
+
+ P := Parent (P);
+ end loop;
+
+ return False;
+ end Library_Level_Target;
+
------------------------
-- Make_Artyp_Literal --
------------------------
@@ -2842,16 +2870,6 @@
-- Local Declarations
- Lib_Level_Target : constant Boolean :=
- Nkind (Parent (Cnode)) = N_Object_Declaration
- and then
- Is_Library_Level_Entity (Defining_Identifier (Parent (Cnode)));
-
- -- If the concatenation declares a library level entity, we call the
- -- built-in concatenation routines to prevent code bloat, regardless
- -- of optimization level. This is space-efficient, and prevent linking
- -- problems when units are compiled with different optimizations.
-
Opnd_Typ : Entity_Id;
Ent : Entity_Id;
Len : Uint;
@@ -3372,22 +3390,27 @@
-- There are nine or fewer retained (non-null) operands
- -- The optimization level is -O0
+ -- The optimization level is -O0 or the debug flag gnatd.C is set,
+ -- and the debug flag gnatd.c is not set.
-- The corresponding System.Concat_n.Str_Concat_n routine is
-- available in the run time.
- -- The debug flag gnatd.c is not set
-
-- If all these conditions are met then we generate a call to the
-- relevant concatenation routine. The purpose of this is to avoid
-- undesirable code bloat at -O0.
+ -- If the concatenation is within the declaration of a library-level
+ -- object, we call the built-in concatenation routines to prevent code
+ -- bloat, regardless of the optimization level. This is space efficient
+ -- and prevents linking problems when units are compiled with different
+ -- optimization levels.
+
if Atyp = Standard_String
and then NN in 2 .. 9
- and then (Lib_Level_Target
- or else ((Optimization_Level = 0 or else Debug_Flag_Dot_CC)
- and then not Debug_Flag_Dot_C))
+ and then (((Optimization_Level = 0 or else Debug_Flag_Dot_CC)
+ and then not Debug_Flag_Dot_C)
+ or else Library_Level_Target)
then
declare
RR : constant array (Nat range 2 .. 9) of RE_Id :=
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2017-04-25 9:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-25 9:46 [Ada] Use out-of-line string concatenation at library level Arnaud Charlet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).