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)