diff mbox

[Ada] Small tweaks related to inlining

Message ID 1533774.sr8g38lCbE@polaris
State New
Headers show

Commit Message

Eric Botcazou May 15, 2017, 8:27 a.m. UTC
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  <ebotcazou@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.
diff mbox

Patch

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