From 3ac5f7de34bdd82f3e4a8b3977749e9e1ce0a269 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Mon, 16 Jul 2018 14:10:32 +0000 Subject: [PATCH] [Ada] Code cleanup on functions inlining This patch is preventive: it improves checks on inline functions that return unconstrained type. It does not change the functionality of the compiler. 2018-07-16 Javier Miranda gcc/ada/ * inline.adb (Build_Body_To_Inline): Minor code reorganization that ensures that calls to function Has_Single_Return() pass a decorated tree. (Has_Single_Return.Check_Return): Peform checks on entities (instead on relying on their characters). From-SVN: r262708 --- gcc/ada/ChangeLog | 8 +++++ gcc/ada/inline.adb | 81 +++++++++++++++++++++++++--------------------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index bff06e6be43..163118f5027 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2018-07-16 Javier Miranda + + * inline.adb (Build_Body_To_Inline): Minor code reorganization that + ensures that calls to function Has_Single_Return() pass a decorated + tree. + (Has_Single_Return.Check_Return): Peform checks on entities (instead on + relying on their characters). + 2018-07-16 Javier Miranda * exp_ch5.adb (Expand_Iterator_Loop_Over_Array): Code cleanup. Required diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb index bc01ffc58ce..df7fdb9e893 100644 --- a/gcc/ada/inline.adb +++ b/gcc/ada/inline.adb @@ -1085,33 +1085,9 @@ package body Inline is Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id); return; - -- Functions that return unconstrained composite types require - -- secondary stack handling, and cannot currently be inlined, unless - -- all return statements return a local variable that is the first - -- local declaration in the body. - - elsif Ekind (Spec_Id) = E_Function - and then not Is_Scalar_Type (Etype (Spec_Id)) - and then not Is_Access_Type (Etype (Spec_Id)) - and then not Is_Constrained (Etype (Spec_Id)) - then - if not Has_Single_Return (N) - - -- Skip inlining if the function returns an unconstrained type - -- using an extended return statement, since this part of the - -- new inlining model is not yet supported by the current - -- implementation. ??? - - or else (Returns_Unconstrained_Type (Spec_Id) - and then Has_Extended_Return) - then - Cannot_Inline - ("cannot inline & (unconstrained return type)?", N, Spec_Id); - return; - end if; - - -- Ditto for functions that return controlled types, where controlled - -- actions interfere in complex ways with inlining. + -- Functions that return controlled types cannot currently be inlined + -- because they require secondary stack handling; controlled actions + -- may also interfere in complex ways with inlining. elsif Ekind (Spec_Id) = E_Function and then Needs_Finalization (Etype (Spec_Id)) @@ -1234,10 +1210,37 @@ package body Inline is Restore_Env; end if; + -- Functions that return unconstrained composite types require + -- secondary stack handling, and cannot currently be inlined, unless + -- all return statements return a local variable that is the first + -- local declaration in the body. We had to delay this check until + -- the body of the function is analyzed since Has_Single_Return() + -- requires a minimum decoration. + + if Ekind (Spec_Id) = E_Function + and then not Is_Scalar_Type (Etype (Spec_Id)) + and then not Is_Access_Type (Etype (Spec_Id)) + and then not Is_Constrained (Etype (Spec_Id)) + then + if not Has_Single_Return (Body_To_Analyze) + + -- Skip inlining if the function returns an unconstrained type + -- using an extended return statement, since this part of the + -- new inlining model is not yet supported by the current + -- implementation. ??? + + or else (Returns_Unconstrained_Type (Spec_Id) + and then Has_Extended_Return) + then + Cannot_Inline + ("cannot inline & (unconstrained return type)?", N, Spec_Id); + return; + end if; + -- If secondary stack is used, there is no point in inlining. We have -- already issued the warning in this case, so nothing to do. - if Uses_Secondary_Stack (Body_To_Analyze) then + elsif Uses_Secondary_Stack (Body_To_Analyze) then return; end if; @@ -3904,17 +3907,23 @@ package body Inline is if Present (Expression (N)) and then Is_Entity_Name (Expression (N)) then + pragma Assert (Present (Entity (Expression (N)))); + if No (Return_Statement) then Return_Statement := N; return OK; - elsif Chars (Expression (N)) = - Chars (Expression (Return_Statement)) - then - return OK; - else - return Abandon; + pragma Assert + (Present (Entity (Expression (Return_Statement)))); + + if Entity (Expression (N)) = + Entity (Expression (Return_Statement)) + then + return OK; + else + return Abandon; + end if; end if; -- A return statement within an extended return is a noop @@ -3963,8 +3972,8 @@ package body Inline is else return Present (Declarations (N)) and then Present (First (Declarations (N))) - and then Chars (Expression (Return_Statement)) = - Chars (Defining_Identifier (First (Declarations (N)))); + and then Entity (Expression (Return_Statement)) = + Defining_Identifier (First (Declarations (N))); end if; end Has_Single_Return; -- 2.30.2