inline.adb (Back_End_Cannot_Inline): Lift restriction on calls to subprograms without a previous spec declared in...

* inline.adb (Back_End_Cannot_Inline): Lift restriction on calls to
	subprograms without a previous spec declared in the same unit.
	* gcc-interface/trans.c (Compilation_Unit_to_gnu): Process inlined
	subprograms at the end of the unit instead of at the beginning.
	* gcc-interface/utils.c (create_subprog_decl): Check that the entity
	isn't public for the special handling of non-inline functions nested
	inside inline external functions.

From-SVN: r171551
This commit is contained in:
Eric Botcazou 2011-03-26 09:34:40 +00:00
parent 530f4f437a
commit 5daed84a54
8 changed files with 63 additions and 69 deletions

View file

@ -1,6 +1,16 @@
2011-03-26 Eric Botcazou <ebotcazou@adacore.com>
* inline.adb (Back_End_Cannot_Inline): Lift restriction on calls to
subprograms without a previous spec declared in the same unit.
* gcc-interface/trans.c (Compilation_Unit_to_gnu): Process inlined
subprograms at the end of the unit instead of at the beginning.
* gcc-interface/utils.c (create_subprog_decl): Check that the entity
isn't public for the special handling of non-inline functions nested
inside inline external functions.
2011-03-25 Jeff Law <law@redhat.com> 2011-03-25 Jeff Law <law@redhat.com>
* ada/gcc-interface/utils.c (def_fn_type): Add missing va_end. * gcc-interface/utils.c (def_fn_type): Add missing va_end.
2011-03-24 Eric Botcazou <ebotcazou@adacore.com> 2011-03-24 Eric Botcazou <ebotcazou@adacore.com>

View file

@ -3793,6 +3793,20 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
finalize_from_with_types (); finalize_from_with_types ();
} }
if (type_annotate_only && gnat_node == Cunit (Main_Unit))
{
elaborate_all_entities (gnat_node);
if (Nkind (Unit (gnat_node)) == N_Subprogram_Declaration
|| Nkind (Unit (gnat_node)) == N_Generic_Package_Declaration
|| Nkind (Unit (gnat_node)) == N_Generic_Subprogram_Declaration)
return;
}
process_decls (Declarations (Aux_Decls_Node (gnat_node)), Empty, Empty,
true, true);
add_stmt (gnat_to_gnu (Unit (gnat_node)));
/* If we can inline, generate code for all the inlined subprograms. */ /* If we can inline, generate code for all the inlined subprograms. */
if (optimize) if (optimize)
{ {
@ -3822,20 +3836,6 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
} }
} }
if (type_annotate_only && gnat_node == Cunit (Main_Unit))
{
elaborate_all_entities (gnat_node);
if (Nkind (Unit (gnat_node)) == N_Subprogram_Declaration
|| Nkind (Unit (gnat_node)) == N_Generic_Package_Declaration
|| Nkind (Unit (gnat_node)) == N_Generic_Subprogram_Declaration)
return;
}
process_decls (Declarations (Aux_Decls_Node (gnat_node)), Empty, Empty,
true, true);
add_stmt (gnat_to_gnu (Unit (gnat_node)));
/* Process any pragmas and actions following the unit. */ /* Process any pragmas and actions following the unit. */
add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node))); add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node)));
add_stmt_list (Actions (Aux_Decls_Node (gnat_node))); add_stmt_list (Actions (Aux_Decls_Node (gnat_node)));

View file

@ -1790,6 +1790,7 @@ create_subprog_decl (tree subprog_name, tree asm_name,
We could inline the nested function as well but it's probably better We could inline the nested function as well but it's probably better
to err on the side of too little inlining. */ to err on the side of too little inlining. */
if (!inline_flag if (!inline_flag
&& !public_flag
&& current_function_decl && current_function_decl
&& DECL_DECLARED_INLINE_P (current_function_decl) && DECL_DECLARED_INLINE_P (current_function_decl)
&& DECL_EXTERNAL (current_function_decl)) && DECL_EXTERNAL (current_function_decl))

View file

@ -368,12 +368,6 @@ package body Inline is
-- inlined under ZCX because the numeric suffix generated by gigi -- inlined under ZCX because the numeric suffix generated by gigi
-- will be different in the body and the place of the inlined call. -- will be different in the body and the place of the inlined call.
-- --
-- If the body to be inlined contains calls to subprograms declared
-- in the same body that have no previous spec, the back-end cannot
-- inline either because the bodies to be inlined are processed before
-- the rest of the enclosing package body, and gigi will then find
-- references to entities that have not been elaborated yet.
--
-- This procedure must be carefully coordinated with the back end. -- This procedure must be carefully coordinated with the back end.
---------------------------- ----------------------------
@ -384,41 +378,6 @@ package body Inline is
Decl : constant Node_Id := Unit_Declaration_Node (Subp); Decl : constant Node_Id := Unit_Declaration_Node (Subp);
Body_Ent : Entity_Id; Body_Ent : Entity_Id;
Ent : Entity_Id; Ent : Entity_Id;
Bad_Call : Node_Id;
function Process (N : Node_Id) return Traverse_Result;
-- Look for calls to subprograms with no previous spec, declared
-- in the same enclosing package body.
-------------
-- Process --
-------------
function Process (N : Node_Id) return Traverse_Result is
begin
if Nkind (N) = N_Procedure_Call_Statement
or else Nkind (N) = N_Function_Call
then
if Is_Entity_Name (Name (N))
and then Comes_From_Source (Entity (Name (N)))
and then
Nkind (Unit_Declaration_Node (Entity (Name (N))))
= N_Subprogram_Body
and then In_Same_Extended_Unit (Subp, Entity (Name (N)))
then
Bad_Call := N;
return Abandon;
else
return OK;
end if;
else
return OK;
end if;
end Process;
function Has_Exposed_Call is new Traverse_Func (Process);
-- Start of processing for Back_End_Cannot_Inline
begin begin
if Nkind (Decl) = N_Subprogram_Declaration if Nkind (Decl) = N_Subprogram_Declaration
@ -454,19 +413,7 @@ package body Inline is
Next_Entity (Ent); Next_Entity (Ent);
end loop; end loop;
if Has_Exposed_Call return False;
(Unit_Declaration_Node (Corresponding_Body (Decl))) = Abandon
then
if Ineffective_Inline_Warnings then
Error_Msg_N
("?call to subprogram with no separate spec"
& " prevents inlining!!", Bad_Call);
end if;
return True;
else
return False;
end if;
end Back_End_Cannot_Inline; end Back_End_Cannot_Inline;
-- Start of processing for Add_Inlined_Subprogram -- Start of processing for Add_Inlined_Subprogram

View file

@ -1,3 +1,8 @@
2011-03-26 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt15.adb: New test.
* gnat.dg/opt15_pkg.ad[sb]: New helper.
2011-03-25 Tobias Burnus <burnus@net-b.de> 2011-03-25 Tobias Burnus <burnus@net-b.de>
PR fortran/48174 PR fortran/48174

View file

@ -0,0 +1,12 @@
-- { dg-do compile }
-- { dg-options "-O -gnatn -fdump-tree-optimized" }
with Opt15_Pkg; use Opt15_Pkg;
procedure Opt15 is
begin
Trace_Inlined;
end;
-- { dg-final { scan-tree-dump-not "trace_inlined" "optimized" } }
-- { dg-final { cleanup-tree-dump "optimized" } }

View file

@ -0,0 +1,13 @@
package body Opt15_Pkg is
procedure Trace_Non_Inlined is
begin
raise Program_Error;
end;
procedure Trace_Inlined is
begin
Trace_Non_Inlined;
end;
end Opt15_Pkg;

View file

@ -0,0 +1,6 @@
package Opt15_Pkg is
procedure Trace_Inlined;
pragma Inline (Trace_Inlined);
end Opt15_Pkg;