In Ada, pragma Inline_Always (which is specific to GNAT) guarantees both that
all direct calls are inlined and that there are no indirect references to the
subprogram. That's why the out-of-line body of a subprogram subject to pragma
Inline_Always can always be eliminated.
Tested on x86_64-suse-linux, applied on the mainline.
2017-05-15 Eric Botcazou <ebotca...@adacore.com>
* gcc-interface/trans.c (Compilation_Unit_to_gnu): Skip subprograms on
the inlined list that are not public.
* gcc-interface/utils.c (create_subprog_decl): Clear TREE_PUBLIC if
there is a pragma Inline_Always on the subprogram.
--
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c (revision 248050)
+++ gcc-interface/trans.c (working copy)
@@ -5472,6 +5472,15 @@ Compilation_Unit_to_gnu (Node_Id gnat_no
if (!optimize && !Has_Pragma_Inline_Always (gnat_entity))
continue;
+ /* The set of inlined subprograms is computed from data recorded early
+ during expansion and it can be a strict superset of the final set
+ computed after semantic analysis, for example if a call to such a
+ subprogram occurs in a pragma Assert and assertions are disabled.
+ In that case, semantic analysis resets Is_Public to false but the
+ entry for the subprogram in the inlining tables is stalled. */
+ if (!Is_Public (gnat_entity))
+ continue;
+
gnat_body = Parent (Declaration_Node (gnat_entity));
if (Nkind (gnat_body) != N_Subprogram_Body)
{
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c (revision 248050)
+++ gcc-interface/utils.c (working copy)
@@ -3220,10 +3220,19 @@ create_subprog_decl (tree name, tree asm
case is_required:
if (Back_End_Inlining)
- decl_attributes (&subprog_decl,
- tree_cons (get_identifier ("always_inline"),
- NULL_TREE, NULL_TREE),
- ATTR_FLAG_TYPE_IN_PLACE);
+ {
+ decl_attributes (&subprog_decl,
+ tree_cons (get_identifier ("always_inline"),
+ NULL_TREE, NULL_TREE),
+ ATTR_FLAG_TYPE_IN_PLACE);
+
+ /* Inline_Always guarantees that every direct call is inlined and
+ that there is no indirect reference to the subprogram, so the
+ instance in the original package (as well as its clones in the
+ client packages created for inter-unit inlining) can be made
+ private, which causes the out-of-line body to be eliminated. */
+ TREE_PUBLIC (subprog_decl) = 0;
+ }
/* ... fall through ... */