From 4ff935348d6ba09189df05b5ab9b9763b3d0068f Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 4 Oct 2018 17:50:28 -0400
Subject: [PATCH 09/51] {NEEDS CHANGELOG, B&R, REVIEW}:
 ipa-inline.c/tree-inline.c: port from fprintf to dump API (PR ipa/86395)

This patch ports from fprintf to using the dump API in various places

Doing so makes this information appear in -fopt-info and in
optimization records, rather than just in the dump_file.
---
 gcc/ipa-inline.c                              | 191 ++++++++++++++------------
 gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c |  44 ++++++
 gcc/tree-inline.c                             |  20 ++-
 3 files changed, 157 insertions(+), 98 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c

diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 4f8ed15..8d0762d 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -227,20 +227,21 @@ caller_growth_limits (struct cgraph_edge *e)
 static void
 report_inline_failed_reason (struct cgraph_edge *e)
 {
-  if (dump_file)
+  if (dump_enabled_p ())
     {
-      fprintf (dump_file, "  not inlinable: %s -> %s, %s\n",
-	       e->caller->dump_name (),
-	       e->callee->dump_name (),
-	       cgraph_inline_failed_string (e->inline_failed));
+      dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+		       "  not inlinable: %C -> %C, %s\n",
+		       e->caller, e->callee,
+		       cgraph_inline_failed_string (e->inline_failed));
       if ((e->inline_failed == CIF_TARGET_OPTION_MISMATCH
 	   || e->inline_failed == CIF_OPTIMIZATION_MISMATCH)
 	  && e->caller->lto_file_data
 	  && e->callee->ultimate_alias_target ()->lto_file_data)
 	{
-	  fprintf (dump_file, "  LTO objects: %s, %s\n",
-		   e->caller->lto_file_data->file_name,
-		   e->callee->ultimate_alias_target ()->lto_file_data->file_name);
+	  dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			   "  LTO objects: %s, %s\n",
+			   e->caller->lto_file_data->file_name,
+			   e->callee->ultimate_alias_target ()->lto_file_data->file_name);
 	}
       if (e->inline_failed == CIF_TARGET_OPTION_MISMATCH)
 	cl_target_option_print_diff
@@ -569,8 +570,9 @@ can_early_inline_edge_p (struct cgraph_edge *e)
   if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->caller->decl))
       || !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)))
     {
-      if (dump_file)
-	fprintf (dump_file, "  edge not inlinable: not in SSA form\n");
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			 "  edge not inlinable: not in SSA form\n");
       return false;
     }
   if (!can_inline_edge_p (e, true, true)
@@ -630,34 +632,34 @@ want_early_inline_function_p (struct cgraph_edge *e)
       else if (!e->maybe_hot_p ()
 	       && growth > 0)
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "  will not early inline: %s->%s, "
-		     "call is cold and code would grow by %i\n",
-		     e->caller->dump_name (),
-		     callee->dump_name (),
-		     growth);
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "  will not early inline: %C->%C, "
+			     "call is cold and code would grow by %i\n",
+			     e->caller, callee,
+			     growth);
 	  want_inline = false;
 	}
       else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "  will not early inline: %s->%s, "
-		     "growth %i exceeds --param early-inlining-insns\n",
-		     e->caller->dump_name (),
-		     callee->dump_name (),
-		     growth);
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "  will not early inline: %C->%C, "
+			     "growth %i exceeds --param early-inlining-insns\n",
+			     e->caller, callee,
+			     growth);
 	  want_inline = false;
 	}
       else if ((n = num_calls (callee)) != 0
 	       && growth * (n + 1) > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "  will not early inline: %s->%s, "
-		     "growth %i exceeds --param early-inlining-insns "
-		     "divided by number of calls\n",
-		     e->caller->dump_name (),
-		     callee->dump_name (),
-		     growth);
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "  will not early inline: %C->%C, "
+			     "growth %i exceeds --param early-inlining-insns "
+			     "divided by number of calls\n",
+			     e->caller, callee,
+			     growth);
 	  want_inline = false;
 	}
     }
@@ -936,8 +938,9 @@ want_inline_self_recursive_call_p (struct cgraph_edge *edge,
 	  want_inline = false;
 	}
     }
-  if (!want_inline && dump_file)
-    fprintf (dump_file, "   not inlining recursively: %s\n", reason);
+  if (!want_inline && dump_enabled_p ())
+    dump_printf_loc (MSG_MISSED_OPTIMIZATION, edge->call_stmt,
+		     "   not inlining recursively: %s\n", reason);
   return want_inline;
 }
 
@@ -1562,14 +1565,14 @@ recursive_inlining (struct cgraph_edge *edge,
   if (!master_clone)
     return false;
 
-  if (dump_file)
-    fprintf (dump_file,
-	     "\n   Inlined %i times, "
-	     "body grown from size %i to %i, time %f to %f\n", n,
-	     ipa_fn_summaries->get (master_clone)->size,
-	     ipa_fn_summaries->get (node)->size,
-	     ipa_fn_summaries->get (master_clone)->time.to_double (),
-	     ipa_fn_summaries->get (node)->time.to_double ());
+  if (dump_enabled_p ())
+    dump_printf_loc (MSG_NOTE, edge->call_stmt,
+		     "\n   Inlined %i times, "
+		     "body grown from size %i to %i, time %f to %f\n", n,
+		     ipa_fn_summaries->get (master_clone)->size,
+		     ipa_fn_summaries->get (node)->size,
+		     ipa_fn_summaries->get (master_clone)->time.to_double (),
+		     ipa_fn_summaries->get (node)->time.to_double ());
 
   /* Remove master clone we used for inlining.  We rely that clones inlined
      into master clone gets queued just before master clone so we don't
@@ -2078,17 +2081,20 @@ inline_small_functions (void)
 	update_callee_keys (&edge_heap, n, updated_nodes);
       bitmap_clear (updated_nodes);
 
-      if (dump_file)
+      if (dump_enabled_p ())
 	{
 	  ipa_fn_summary *s = ipa_fn_summaries->get (edge->caller);
-	  fprintf (dump_file,
-		   " Inlined %s into %s which now has time %f and size %i, "
-		   "net change of %+i.\n",
-		   xstrdup_for_dump (edge->callee->name ()),
-		   xstrdup_for_dump (edge->caller->name ()),
-		   s->time.to_double (),
-		   s->size,
-		   overall_size - old_size);
+
+	  /* dump_printf can't handle %+i.  */
+	  char buf_net_change[100];
+	  snprintf (buf_net_change, sizeof buf_net_change, "%+i",
+		    overall_size - old_size);
+
+	  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
+			   " Inlined %C into %C which now has time %f and "
+			   "size %i, net change of %s.\n",
+			   edge->callee, edge->caller,
+			   s->time.to_double (), s->size, buf_net_change);
 	}
       if (min_size > overall_size)
 	{
@@ -2101,11 +2107,11 @@ inline_small_functions (void)
     }
 
   free_growth_caches ();
-  if (dump_file)
-    fprintf (dump_file,
-	     "Unit growth for small function inlining: %i->%i (%i%%)\n",
-	     initial_size, overall_size,
-	     initial_size ? overall_size * 100 / (initial_size) - 100: 0);
+  if (dump_enabled_p ())
+    dump_printf (MSG_NOTE,
+		 "Unit growth for small function inlining: %i->%i (%i%%)\n",
+		 initial_size, overall_size,
+		 initial_size ? overall_size * 100 / (initial_size) - 100: 0);
   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
 }
 
@@ -2130,11 +2136,10 @@ flatten_function (struct cgraph_node *node, bool early)
       /* We've hit cycle?  It is time to give up.  */
       if (callee->aux)
 	{
-	  if (dump_file)
-	    fprintf (dump_file,
-		     "Not inlining %s into %s to avoid cycle.\n",
-		     xstrdup_for_dump (callee->name ()),
-		     xstrdup_for_dump (e->caller->name ()));
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "Not inlining %C into %C to avoid cycle.\n",
+			     callee, e->caller);
 	  if (cgraph_inline_failed_type (e->inline_failed) != CIF_FINAL_ERROR)
 	    e->inline_failed = CIF_RECURSIVE_INLINING;
 	  continue;
@@ -2159,25 +2164,27 @@ flatten_function (struct cgraph_node *node, bool early)
 
       if (e->recursive_p ())
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "Not inlining: recursive call.\n");
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "Not inlining: recursive call.\n");
 	  continue;
 	}
 
       if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
 	  != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)))
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "Not inlining: SSA form does not match.\n");
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "Not inlining: SSA form does not match.\n");
 	  continue;
 	}
 
       /* Inline the edge and flatten the inline clone.  Avoid
          recursing through the original node if the node was cloned.  */
-      if (dump_file)
-	fprintf (dump_file, " Inlining %s into %s.\n",
-		 xstrdup_for_dump (callee->name ()),
-		 xstrdup_for_dump (e->caller->name ()));
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
+			 " Inlining %C into %C.\n",
+			 callee, e->caller);
       orig_callee = callee;
       inline_call (e, true, NULL, NULL, false);
       if (e->callee != orig_callee)
@@ -2589,13 +2596,12 @@ ipa_inline (void)
   /* Free ipa-prop structures if they are no longer needed.  */
   ipa_free_all_structures_after_iinln ();
 
+  if (dump_enabled_p ())
+    dump_printf (MSG_NOTE,
+		 "\nInlined %i calls, eliminated %i functions\n\n",
+		 ncalls_inlined, nfunctions_inlined);
   if (dump_file)
-    {
-      fprintf (dump_file,
-	       "\nInlined %i calls, eliminated %i functions\n\n",
-	       ncalls_inlined, nfunctions_inlined);
-      dump_inline_stats ();
-    }
+    dump_inline_stats ();
 
   if (dump_file)
     ipa_dump_fn_summaries (dump_file);
@@ -2618,9 +2624,10 @@ inline_always_inline_functions (struct cgraph_node *node)
 
       if (e->recursive_p ())
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "  Not inlining recursive call to %s.\n",
-		     e->callee->name ());
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "  Not inlining recursive call to %C.\n",
+			     e->callee);
 	  e->inline_failed = CIF_RECURSIVE_INLINING;
 	  continue;
 	}
@@ -2636,10 +2643,10 @@ inline_always_inline_functions (struct cgraph_node *node)
 	  continue;
 	}
 
-      if (dump_file)
-	fprintf (dump_file, "  Inlining %s into %s (always_inline).\n",
-		 xstrdup_for_dump (e->callee->name ()),
-		 xstrdup_for_dump (e->caller->name ()));
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
+			 "  Inlining %C into %C (always_inline).\n",
+			 e->callee, e->caller);
       inline_call (e, true, NULL, NULL, false);
       inlined = true;
     }
@@ -2675,27 +2682,29 @@ early_inline_small_functions (struct cgraph_node *node)
 	  && !opt_for_fn (node->decl, flag_inline_functions))
 	continue;
 
-      if (dump_file)
-	fprintf (dump_file, "Considering inline candidate %s.\n",
-		 callee->name ());
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_NOTE, e->call_stmt,
+			 "Considering inline candidate %C.\n",
+			 callee);
 
       if (!can_early_inline_edge_p (e))
 	continue;
 
       if (e->recursive_p ())
 	{
-	  if (dump_file)
-	    fprintf (dump_file, "  Not inlining: recursive call.\n");
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+			     "  Not inlining: recursive call.\n");
 	  continue;
 	}
 
       if (!want_early_inline_function_p (e))
 	continue;
 
-      if (dump_file)
-	fprintf (dump_file, " Inlining %s into %s.\n",
-		 xstrdup_for_dump (callee->name ()),
-		 xstrdup_for_dump (e->caller->name ()));
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
+			 " Inlining %C into %C.\n",
+			 callee, e->caller);
       inline_call (e, true, NULL, NULL, false);
       inlined = true;
     }
@@ -2755,9 +2764,9 @@ early_inliner (function *fun)
     {
       /* When the function is marked to be flattened, recursively inline
 	 all calls in it.  */
-      if (dump_file)
-	fprintf (dump_file,
-		 "Flattening %s\n", node->name ());
+      if (dump_enabled_p ())
+	dump_printf (MSG_OPTIMIZED_LOCATIONS,
+		     "Flattening %C\n", node);
       flatten_function (node, true);
       inlined = true;
     }
diff --git a/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c b/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c
new file mode 100644
index 0000000..4032ad1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c
@@ -0,0 +1,44 @@
+/* { dg-options "-O3 -fopt-info-inline-optimized-missed" } */
+
+static int foo (int a)
+{
+  return a + 10;
+}
+
+static int bar (int b)
+{
+  return b - 20;
+}
+
+static int boo (int a, int b)
+{
+  return (foo (a)     /* { dg-optimized "Inlining foo/\[0-9\]+ into boo/\[0-9\]+" } */
+	  + bar (b)); /* { dg-optimized "Inlining bar/\[0-9\]+ into boo/\[0-9\]+" } */
+}
+
+extern int v_a, v_b;
+extern int result;
+
+int compute ()
+{
+  result = boo (v_a, v_b); /* { dg-optimized "Inlining boo/\[0-9\]+ into compute/\[0-9\]+" } */
+
+  return result;
+}
+
+extern void not_available(int);
+
+int __attribute__ ((noinline,noclone)) get_input(void)
+{
+  return 1;
+}
+
+int test_1 ()
+{
+  return get_input (); /* { dg-missed "not inlinable: test_1/\[0-9\]+ -> get_input/\[0-9\]+, function not inlinable" } */
+}
+
+void test_2 (int v)
+{
+  not_available (1); /* { dg-missed "not inlinable: test_2/\[0-9\]+ -> not_available/\[0-9\]+, function body not available" } */
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 297fcd7..6c42e99 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4673,14 +4673,20 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
   /* Add local vars in this inlined callee to caller.  */
   add_local_variables (id->src_cfun, cfun, id);
 
-  if (dump_file && (dump_flags & TDF_DETAILS))
+  if (dump_enabled_p ())
     {
-      fprintf (dump_file, "Inlining %s to %s with frequency %4.2f\n",
-	       id->src_node->dump_name (),
-	       id->dst_node->dump_name (),
-	       cg_edge->sreal_frequency ().to_double ());
-      id->src_node->dump (dump_file);
-      id->dst_node->dump (dump_file);
+      char buf[128];
+      snprintf (buf, sizeof(buf), "%4.2f",
+		cg_edge->sreal_frequency ().to_double ());
+      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | MSG_PRIORITY_INTERNALS,
+		       call_stmt,
+		       "Inlining %C to %C with frequency %s\n",
+		       id->src_node, id->dst_node, buf);
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	{
+	  id->src_node->dump (dump_file);
+	  id->dst_node->dump (dump_file);
+	}
     }
 
   /* This is it.  Duplicate the callee body.  Assume callee is
-- 
1.8.5.3

