Avoid quadratic behaviour in early inlining

Message ID 20191121081903.efceulgooy6gnoib@kam.mff.cuni.cz
State New
Headers show
Series
  • Avoid quadratic behaviour in early inlining
Related show

Commit Message

Jan Hubicka Nov. 21, 2019, 8:19 a.m.
Hi,
because early inliner is not producing call summaries, we do not want to
estimate calls to very large function when we already know that inlning
is going to fail.

Bootstrapped/regtested x86_64-linux.

	* ipa-inline.c (want_early_inline_function_p): Do not estimate
	edge growth when callee function is very large.
	* ipa-inline.h (estimate_min_edge_growth): New.

Patch

Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 278540)
+++ ipa-inline.c	(working copy)
@@ -672,14 +672,29 @@  want_early_inline_function_p (struct cgr
     }
   else
     {
-      int growth = estimate_edge_growth (e);
+      /* First take care of very large functions.  */
+      int min_growth = estimate_min_edge_growth (e), growth = 0;
       int n;
       int early_inlining_insns = opt_for_fn (e->caller->decl, optimize) >= 3
 				 ? param_early_inlining_insns
 				 : param_early_inlining_insns_o2;
 
+      if (min_growth > early_inlining_insns)
+	{
+	  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 "
+			     "at least by %i\n",
+			     e->caller, callee,
+			     min_growth);
+	  want_inline = false;
+	}
+      else
+        growth = estimate_edge_growth (e);
+
 
-      if (growth <= param_max_inline_insns_size)
+      if (!want_inline || growth <= param_max_inline_insns_size)
 	;
       else if (!e->maybe_hot_p ())
 	{
Index: ipa-inline.h
===================================================================
--- ipa-inline.h	(revision 278540)
+++ ipa-inline.h	(working copy)
@@ -79,6 +79,16 @@  estimate_edge_size (struct cgraph_edge *
   return entry->size - (entry->size > 0);
 }
 
+/* Return lower bound on estimated callee growth after inlining EDGE.  */
+
+static inline int
+estimate_min_edge_growth (struct cgraph_edge *edge)
+{
+  ipa_call_summary *s = ipa_call_summaries->get (edge);
+  struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
+  return (ipa_fn_summaries->get (callee)->min_size - s->call_stmt_size);
+}
+
 /* Return estimated callee growth after inlining EDGE.  */
 
 static inline int