Avoid quadratic behaviour of early inliner.
authorJan Hubicka <jh@suse.cz>
Thu, 21 Nov 2019 08:15:47 +0000 (09:15 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 21 Nov 2019 08:15:47 +0000 (08:15 +0000)
* 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.

From-SVN: r278542

gcc/ChangeLog
gcc/ipa-inline.c
gcc/ipa-inline.h

index cab81d5e9100879d7c536ddf5f5d660b6e962a01..904b54c9ebe29cd25eced36b7592604fcc2d641a 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-20  Jan Hubicka  <jh@suse.cz>
+
+       * 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.
+
 2019-11-20  Jan Hubicka  <jh@suse.cz>
 
        * ipa-fnsummary.c (ipa_fn_summary::account_size_time): Allow
index 5d8b87a7bc3f3a5c25914f68dacb399eb18c1fba..6da3e96b45df69d41dcfc8d02856198526e9bf85 100644 (file)
@@ -672,14 +672,29 @@ want_early_inline_function_p (struct cgraph_edge *e)
     }
   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 626f264d5d0892976b6f611cfafaab813235e8f0..6273f0747f944e2994bf3d8b41adefb371a2c4dc 100644 (file)
@@ -79,6 +79,16 @@ estimate_edge_size (struct cgraph_edge *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