aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-08-19 08:36:53 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-08-19 08:36:53 +0000
commit6c87c83bb2a8a65f6f73d23ebb863a5c67e4c6c2 (patch)
treeb582d19735f1d5a68c96a8932cda41a4b7c7ccff
parent92b635e518dfb3bc6829601c38a2c55ea8791887 (diff)
downloadgcc-6c87c83bb2a8a65f6f73d23ebb863a5c67e4c6c2.zip
gcc-6c87c83bb2a8a65f6f73d23ebb863a5c67e4c6c2.tar.gz
gcc-6c87c83bb2a8a65f6f73d23ebb863a5c67e4c6c2.tar.bz2
[Ada] Lift restriction on instantiations that are compilation units
This change lifts the restriction that was still present in the new on-demand instantiation scheme for the body of generics instantiated in non-main units. The instantiations that are compilation units were still dealt with in the old-fashioned way, that is to say the decision of instantiating the body was still made up front during the analysis of the instance declaration, instead of being deferred until after a call to an inlined subprogram is encountered. This should save a few more cycles when full inlining across units is enabled, but there should otherwise be no functional changes. 2019-08-19 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * inline.adb (Add_Inlined_Body): Do not special-case instances that are compilation units. (Add_Pending_Instantiation): Likewise. (Instantiate_Body): Skip instantiations that are compilation units and have already been performed. * sem_ch12.adb (Needs_Body_Instantiated): Do not special-case instances that are compilation units. (Load_Parent_Of_Generic): Be prepared for parent that is a compilation unit but whose instantiation node has not been replaced. gcc/testsuite/ * gnat.dg/generic_inst12.adb, gnat.dg/generic_inst12_pkg1.adb, gnat.dg/generic_inst12_pkg1.ads, gnat.dg/generic_inst12_pkg2.ads: New testcase. From-SVN: r274657
-rw-r--r--gcc/ada/ChangeLog13
-rw-r--r--gcc/ada/inline.adb24
-rw-r--r--gcc/ada/sem_ch12.adb35
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12.adb12
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb13
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads11
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads3
8 files changed, 93 insertions, 24 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c801498..2ac5309 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,18 @@
2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+ * inline.adb (Add_Inlined_Body): Do not special-case instances
+ that are compilation units.
+ (Add_Pending_Instantiation): Likewise.
+ (Instantiate_Body): Skip instantiations that are compilation
+ units and have already been performed.
+ * sem_ch12.adb (Needs_Body_Instantiated): Do not special-case
+ instances that are compilation units.
+ (Load_Parent_Of_Generic): Be prepared for parent that is a
+ compilation unit but whose instantiation node has not been
+ replaced.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
* inline.adb (Initialize, Lock): Deal with
Called_Pending_Instantiations.
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index 22a50e2..46daa48 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -611,12 +611,11 @@ package body Inline is
Inst_Decl := Unit_Declaration_Node (Inst);
-- Do not inline the instance if the body already exists,
- -- or if the instance is a compilation unit, or else if
- -- the instance node is simply missing.
+ -- or the instance node is simply missing.
if Present (Corresponding_Body (Inst_Decl))
- or else Nkind (Parent (Inst_Decl)) = N_Compilation_Unit
- or else No (Next (Inst_Decl))
+ or else (Nkind (Parent (Inst_Decl)) /= N_Compilation_Unit
+ and then No (Next (Inst_Decl)))
then
Set_Is_Called (Inst);
else
@@ -797,13 +796,11 @@ package body Inline is
To_Pending_Instantiations.Set (Act_Decl, Index);
- -- If an instantiation is either a compilation unit or is in the main
- -- unit or subunit or is a nested subprogram, then its body is needed
- -- as per the analysis already done in Analyze_Package_Instantiation
- -- and Analyze_Subprogram_Instantiation.
+ -- If an instantiation is in the main unit or subunit, or is a nested
+ -- subprogram, then its body is needed as per the analysis done in
+ -- Analyze_Package_Instantiation & Analyze_Subprogram_Instantiation.
- if Nkind (Parent (Inst)) = N_Compilation_Unit
- or else In_Main_Unit_Or_Subunit (Act_Decl_Id)
+ if In_Main_Unit_Or_Subunit (Act_Decl_Id)
or else (Is_Subprogram (Act_Decl_Id)
and then Is_Nested (Act_Decl_Id))
then
@@ -4460,6 +4457,13 @@ package body Inline is
if No (Info.Inst_Node) then
null;
+ -- If the instantiation node is a package body, this means that the
+ -- instance is a compilation unit and the instantiation has already
+ -- been performed by Build_Instance_Compilation_Unit_Nodes.
+
+ elsif Nkind (Info.Inst_Node) = N_Package_Body then
+ null;
+
elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
Instantiate_Package_Body (Info);
Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index e94fc21..17de328 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -3921,19 +3921,15 @@ package body Sem_Ch12 is
return False;
end if;
- -- Here we have a special handling for back-end inlining: if the
- -- instantiation is not a compilation unit, then we want to have
- -- its body instantiated. The reason is that Might_Inline_Subp
- -- does not catch all the cases (since it does not recurse into
- -- nested packages) so this avoids the need to patch things up
- -- at a later stage. Moreover the instantiations that are not
- -- compilation units are only performed on demand when back-end
+ -- Here we have a special handling for back-end inlining: if inline
+ -- processing is required, then we unconditionally want to have the
+ -- body instantiated. The reason is that Might_Inline_Subp does not
+ -- catch all the cases (as it does not recurse into nested packages)
+ -- so this avoids the need to patch things up afterwards. Moreover,
+ -- these instantiations are only performed on demand when back-end
-- inlining is enabled, so this causes very little extra work.
- if Nkind (Parent (N)) /= N_Compilation_Unit
- and then Inline_Processing_Required
- and then Back_End_Inlining
- then
+ if Inline_Processing_Required and then Back_End_Inlining then
return True;
end if;
@@ -13699,15 +13695,26 @@ package body Sem_Ch12 is
and then
Nkind (Original_Node (True_Parent)) = N_Package_Instantiation
then
- -- Parent is a compilation unit that is an instantiation.
- -- Instantiation node has been replaced with package decl.
+ -- Parent is a compilation unit that is an instantiation, and
+ -- instantiation node has been replaced with package decl.
Inst_Node := Original_Node (True_Parent);
exit;
elsif Nkind (True_Parent) = N_Package_Declaration
- and then Present (Generic_Parent (Specification (True_Parent)))
+ and then Nkind (Parent (True_Parent)) = N_Compilation_Unit
+ and then
+ Nkind (Unit (Parent (True_Parent))) = N_Package_Instantiation
+ then
+ -- Parent is a compilation unit that is an instantiation, but
+ -- instantiation node has not been replaced with package decl.
+
+ Inst_Node := Unit (Parent (True_Parent));
+ exit;
+
+ elsif Nkind (True_Parent) = N_Package_Declaration
and then Nkind (Parent (True_Parent)) /= N_Compilation_Unit
+ and then Present (Generic_Parent (Specification (True_Parent)))
then
-- Parent is an instantiation within another specification.
-- Declaration for instance has been inserted before original
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f3cff77..0f246bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst12.adb, gnat.dg/generic_inst12_pkg1.adb,
+ gnat.dg/generic_inst12_pkg1.ads,
+ gnat.dg/generic_inst12_pkg2.ads: New testcase.
+
2019-08-19 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/warn28.adb, gnat.dg/warn28.ads: New testcase.
diff --git a/gcc/testsuite/gnat.dg/generic_inst12.adb b/gcc/testsuite/gnat.dg/generic_inst12.adb
new file mode 100644
index 0000000..4f99749
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+-- { dg-options "-O -gnatn" }
+with Generic_Inst12_Pkg2;
+
+procedure Generic_Inst12 is
+
+ procedure My_Inner_G is new Generic_Inst12_Pkg2.Inner_G;
+
+begin
+ My_Inner_G (1);
+ Generic_Inst12_Pkg2.Proc (1);
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb
new file mode 100644
index 0000000..e4eced5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb
@@ -0,0 +1,13 @@
+package body Generic_Inst12_Pkg1 is
+
+ procedure Inner_G (Val : T) is
+ begin
+ null;
+ end;
+
+ procedure Proc (Val : T) is
+ begin
+ null;
+ end;
+
+end Generic_Inst12_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads
new file mode 100644
index 0000000..27de7cb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads
@@ -0,0 +1,11 @@
+generic
+ type T is private;
+package Generic_Inst12_Pkg1 is
+
+ generic
+ procedure Inner_G (Val : T);
+
+ procedure Proc (Val : T);
+ pragma Inline (Proc);
+
+end Generic_Inst12_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads b/gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads
new file mode 100644
index 0000000..60519ad
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads
@@ -0,0 +1,3 @@
+with Generic_Inst12_Pkg1;
+
+package Generic_Inst12_Pkg2 is new Generic_Inst12_Pkg1 (Integer);