2016-02-22 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Feb 2016 09:32:35 +0000 (09:32 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Feb 2016 09:32:35 +0000 (09:32 +0000)
PR ipa/37448
* ipa-inline-transform.c (inline_call): When not updating
overall summaries adjust self size by the growth estimate.
* ipa-inline.c (inline_to_all_callers_1): Add to the callers
hash-set, do not update overall summaries here.  Renamed from ...
(inline_to_all_callers): ... this which is now wrapping the
above and performing delayed overall summary update.
(early_inline_small_functions): Delay updating of the overall
summary.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233598 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 88f7a23..b28ed88 100644 (file)
@@ -1,3 +1,15 @@
+2016-02-22  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/37448
+       * ipa-inline-transform.c (inline_call): When not updating
+       overall summaries adjust self size by the growth estimate.
+       * ipa-inline.c (inline_to_all_callers_1): Add to the callers
+       hash-set, do not update overall summaries here.  Renamed from ...
+       (inline_to_all_callers): ... this which is now wrapping the
+       above and performing delayed overall summary update.
+       (early_inline_small_functions): Delay updating of the overall
+       summary.
+
 2016-02-21  Markus Trippelsdorf  <markus@trippelsdorf.de>
 
        * tree-chkp.c (chkp_mark_invalid_bounds_walker): Initialize
index 759ab78..5dc0b5a 100644 (file)
@@ -301,9 +301,11 @@ inline_call (struct cgraph_edge *e, bool update_original,
   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
   bool new_edges_found = false;
 
+  int estimated_growth = 0;
+  if (! update_overall_summary)
+    estimated_growth = estimate_edge_growth (e);
   /* This is used only for assert bellow.  */
 #if 0
-  int estimated_growth = estimate_edge_growth (e);
   bool predicated = inline_edge_summary (e)->predicate != NULL;
 #endif
 
@@ -373,7 +375,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   check_speculations (e->callee);
   if (update_overall_summary)
-   inline_update_overall_summary (to);
+    inline_update_overall_summary (to);
+  else
+    /* Update self size by the estimate so overall function growth limits
+       work for further inlining into this function.  Before inlining
+       the function we inlined to again we expect the caller to update
+       the overall summary.  */
+    inline_summaries->get (to)->size += estimated_growth;
   new_size = inline_summaries->get (to)->size;
 
   if (callee->calls_comdat_local)
index 07e661e..57a4588 100644 (file)
@@ -2163,7 +2163,8 @@ flatten_function (struct cgraph_node *node, bool early)
    recursion.  */
 
 static bool
-inline_to_all_callers (struct cgraph_node *node, void *data)
+inline_to_all_callers_1 (struct cgraph_node *node, void *data,
+                        hash_set<cgraph_node *> *callers)
 {
   int *num_calls = (int *)data;
   bool callee_removed = false;
@@ -2193,7 +2194,10 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
                   inline_summaries->get (node->callers->caller)->size);
        }
 
-      inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
+      /* Remember which callers we inlined to, delaying updating the
+        overall summary.  */
+      callers->add (node->callers->caller);
+      inline_call (node->callers, true, NULL, NULL, false, &callee_removed);
       if (dump_file)
        fprintf (dump_file,
                 " Inlined into %s which now has %i size\n",
@@ -2211,6 +2215,23 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
   return false;
 }
 
+/* Wrapper around inline_to_all_callers_1 doing delayed overall summary
+   update.  */
+
+static bool
+inline_to_all_callers (struct cgraph_node *node, void *data)
+{
+  hash_set<cgraph_node *> callers;
+  bool res = inline_to_all_callers_1 (node, data, &callers);
+  /* Perform the delayed update of the overall summary of all callers
+     processed.  This avoids quadratic behavior in the cases where
+     we have a lot of calls to the same function.  */
+  for (hash_set<cgraph_node *>::iterator i = callers.begin ();
+       i != callers.end (); ++i)
+    inline_update_overall_summary (*i);
+  return res;
+}
+
 /* Output overall time estimate.  */
 static void
 dump_overall_stats (void)
@@ -2590,10 +2611,13 @@ early_inline_small_functions (struct cgraph_node *node)
        fprintf (dump_file, " Inlining %s into %s.\n",
                 xstrdup_for_dump (callee->name ()),
                 xstrdup_for_dump (e->caller->name ()));
-      inline_call (e, true, NULL, NULL, true);
+      inline_call (e, true, NULL, NULL, false);
       inlined = true;
     }
 
+  if (inlined)
+    inline_update_overall_summary (node);
+
   return inlined;
 }