aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2011-08-02 15:04:46 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2011-08-02 17:04:46 +0200
commitd2b10647195d645708ad8cfc09fa0adf4a394224 (patch)
treef56b7bc0e4d5ca310780b045799c0f003bb066b2
parentc7b9d548d3533d6b48dcdfb882e5ce424f3d53c4 (diff)
downloadgcc-d2b10647195d645708ad8cfc09fa0adf4a394224.zip
gcc-d2b10647195d645708ad8cfc09fa0adf4a394224.tar.gz
gcc-d2b10647195d645708ad8cfc09fa0adf4a394224.tar.bz2
sem_ch6 (Analyze_Expression_Function): treat the function as Inline_Always...
2011-08-02 Ed Schonberg <schonberg@adacore.com> * 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
-rw-r--r--gcc/ada/ChangeLog11
-rw-r--r--gcc/ada/inline.adb6
-rw-r--r--gcc/ada/sem_ch6.adb39
-rw-r--r--gcc/ada/sem_util.adb20
-rw-r--r--gcc/ada/sem_util.ads6
5 files changed, 76 insertions, 6 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 02e05f9..e8407ba 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,14 @@
+2011-08-02 Ed Schonberg <schonberg@adacore.com>
+
+ * 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 <dismukes@adacore.com>
* sem_ch6.adb (Check_Conformance): Revise the check for nonconforming
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index c493797..68e53a5 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 ca7c005..1ca71fc 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 dbe5887..ef65040 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 aeb3557..163e647 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