[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
This commit is contained in:
parent
92b635e518
commit
6c87c83bb2
|
@ -1,3 +1,16 @@
|
|||
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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -0,0 +1,3 @@
|
|||
with Generic_Inst12_Pkg1;
|
||||
|
||||
package Generic_Inst12_Pkg2 is new Generic_Inst12_Pkg1 (Integer);
|
Loading…
Reference in New Issue