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>
* 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>

View file

@ -3793,6 +3793,20 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
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 (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. */
add_stmt_list (Pragmas_After (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
to err on the side of too little inlining. */
if (!inline_flag
&& !public_flag
&& current_function_decl
&& DECL_DECLARED_INLINE_P (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
-- 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.
----------------------------
@ -384,41 +378,6 @@ package body Inline is
Decl : constant Node_Id := Unit_Declaration_Node (Subp);
Body_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
if Nkind (Decl) = N_Subprogram_Declaration
@ -454,19 +413,7 @@ package body Inline is
Next_Entity (Ent);
end loop;
if Has_Exposed_Call
(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;
return False;
end Back_End_Cannot_Inline;
-- 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>
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;