From d2b10647195d645708ad8cfc09fa0adf4a394224 Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Tue, 2 Aug 2011 15:04:46 +0000 Subject: [PATCH] sem_ch6 (Analyze_Expression_Function): treat the function as Inline_Always... 2011-08-02 Ed Schonberg * sem_ch6 (Analyze_Expression_Function): treat the function as Inline_Always, and introduce a subprogram declaration for it when it is not a completion. * inline.adb (Add_Inlined_Body): recognize bodies that come from expression functions, so that the back-end can determine whether they can in fact be inlined. * sem_util.adb (Is_Expression_Function): predicate to determine whether a function body comes from an expression function. From-SVN: r177173 --- gcc/ada/ChangeLog | 11 +++++++++++ gcc/ada/inline.adb | 6 ++++-- gcc/ada/sem_ch6.adb | 39 ++++++++++++++++++++++++++++++++++++--- gcc/ada/sem_util.adb | 20 ++++++++++++++++++++ gcc/ada/sem_util.ads | 6 +++++- 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 02e05f9b8c4..e8407baba03 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,14 @@ +2011-08-02 Ed Schonberg + + * sem_ch6 (Analyze_Expression_Function): treat the function as + Inline_Always, and introduce a subprogram declaration for it when it is + not a completion. + * inline.adb (Add_Inlined_Body): recognize bodies that come from + expression functions, so that the back-end can determine whether they + can in fact be inlined. + * sem_util.adb (Is_Expression_Function): predicate to determine whether + a function body comes from an expression function. + 2011-08-02 Gary Dismukes * sem_ch6.adb (Check_Conformance): Revise the check for nonconforming diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb index c4937976be2..68e53a5de6d 100644 --- a/gcc/ada/inline.adb +++ b/gcc/ada/inline.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -342,7 +342,9 @@ package body Inline is null; elsif not Is_Inlined (Pack) - and then not Has_Completion (E) + and then + (not Has_Completion (E) + or else Is_Expression_Function (E)) then Set_Is_Inlined (Pack); Inlined_Bodies.Increment_Last; diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index ca7c00519c4..1ca71fc288e 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -271,6 +271,7 @@ package body Sem_Ch6 is LocX : constant Source_Ptr := Sloc (Expression (N)); Def_Id : constant Entity_Id := Defining_Entity (Specification (N)); New_Body : Node_Id; + New_Decl : Node_Id; Prev : constant Entity_Id := Current_Entity_In_Scope (Def_Id); -- If the expression is a completion, Prev is the entity whose @@ -278,8 +279,13 @@ package body Sem_Ch6 is begin -- This is one of the occasions on which we transform the tree during - -- semantic analysis. Transform the expression function into an - -- equivalent subprogram body, and then analyze that. + -- semantic analysis. If this is a completion, transform the expression + -- function into an equivalent subprogram body, and analyze it. + + -- Expression functions are inlined unconditionally. The back-end will + -- determine whether this is possible. + + Inline_Processing_Required := True; New_Body := Make_Subprogram_Body (Loc, @@ -304,10 +310,37 @@ package body Sem_Ch6 is Rewrite (N, Make_Null_Statement (Loc)); Analyze (N); Analyze (New_Body); + Set_Is_Inlined (Prev); - else + elsif Present (Prev) then Rewrite (N, New_Body); + Set_Is_Inlined (Prev); Analyze (N); + + -- If this is not a completion, create both a declaration and a body, + -- so that the expression can be inlined whenever possible. + + else + New_Decl := + Make_Subprogram_Declaration (Loc, + Specification => Specification (N)); + Rewrite (N, New_Decl); + Analyze (N); + Set_Is_Inlined (Defining_Entity (New_Decl)); + + -- Create new set of formals for specification in body. + + Set_Specification (New_Body, + Make_Function_Specification (Loc, + Defining_Unit_Name => + Make_Defining_Identifier (Loc, Chars (Defining_Entity (N))), + Parameter_Specifications => + Copy_Parameter_List (Defining_Entity (New_Decl)), + Result_Definition => + New_Copy_Tree (Result_Definition (Specification (New_Decl))))); + + Insert_After (N, New_Body); + Analyze (New_Body); end if; end Analyze_Expression_Function; diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index dbe5887690b..ef650401d7a 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -6541,6 +6541,26 @@ package body Sem_Util is end if; end Is_Descendent_Of; + ---------------------------- + -- Is_Expression_Function -- + ---------------------------- + + function Is_Expression_Function (Subp : Entity_Id) return Boolean is + Decl : constant Node_Id := Unit_Declaration_Node (Subp); + + begin + return Ekind (Subp) = E_Function + and then Nkind (Decl) = N_Subprogram_Declaration + and then + (Nkind (Original_Node (Decl)) = N_Expression_Function + or else + (Present (Corresponding_Body (Decl)) + and then + Nkind (Original_Node + (Unit_Declaration_Node (Corresponding_Body (Decl)))) + = N_Expression_Function)); + end Is_Expression_Function; + -------------- -- Is_False -- -------------- diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index aeb35571be1..163e6470431 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -741,6 +741,10 @@ package Sem_Util is -- First determine whether type T is an interface and then check whether -- it is of protected, synchronized or task kind. + function Is_Expression_Function (Subp : Entity_Id) return Boolean; + -- Predicate to determine whether a function entity comes from a rewritten + -- expression function, and should be inlined unconditionally. + function Is_False (U : Uint) return Boolean; pragma Inline (Is_False); -- The argument is a Uint value which is the Boolean'Pos value of a Boolean -- 2.30.2