The handling of string concatenation is quite inefficient in the front-end
because the compiler generates a lot of implicit concatenation operators for
array types and also enumeration types, and then walks the full list every
time it needs to resolve a concatenation operator, in most cases for strings.

This small patch adds a guard to Find_Concatenation_Types in order to filter
out operators unrelated to string concatenation and thus to avoid doing a
costly full type resolution for each of them.  This saves more than 5% of
the instruction count on x86-64 for a typical testcase.

No functional changes.

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-10-20  Eric Botcazou  <ebotca...@adacore.com>

        * sem_ch4.adb (Find_Concatenation_Types): Filter out operators if one
        of the operands is a string literal.

Index: sem_ch4.adb
===================================================================
--- sem_ch4.adb (revision 253916)
+++ sem_ch4.adb (working copy)
@@ -6431,10 +6431,24 @@
       Op_Id : Entity_Id;
       N     : Node_Id)
    is
-      Op_Type : constant Entity_Id := Etype (Op_Id);
+      Is_String : constant Boolean := Nkind (L) = N_String_Literal
+                                        or else
+                                      Nkind (R) = N_String_Literal;
+      Op_Type   : constant Entity_Id := Etype (Op_Id);
 
    begin
       if Is_Array_Type (Op_Type)
+
+        --  Small but very effective optimization: if at least one operand is a
+        --  string literal, then the type of the operator must be either array
+        --  of characters or array of strings.
+
+        and then (not Is_String
+                    or else
+                  Is_Character_Type (Component_Type (Op_Type))
+                    or else
+                  Is_String_Type (Component_Type (Op_Type)))
+
         and then not Is_Limited_Type (Op_Type)
 
         and then (Has_Compatible_Type (L, Op_Type)

Reply via email to