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 <[email protected]>
* 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)