Incremental updating of inline summaries.
authorJan Hubicka <jh@suse.cz>
Thu, 21 Nov 2019 08:03:01 +0000 (09:03 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 21 Nov 2019 08:03:01 +0000 (08:03 +0000)
        * ipa-fnsummary.c (ipa_fn_summary::account_size_time): Allow
negative time in calls summary; correct roundoff errors
leading to negative times.
(ipa_merge_fn_summary_after_inlining): Update calls size time table
if present.
(ipa_update_overall_fn_summary): Add RESET parameter.
* ipa-fnsummary.h (ipa_update_overall_fn_summary): Update prototype.
* ipa-inline-transform.c (inline_call): Enable incremental updates.

From-SVN: r278541

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

index cf06e3aad080ef458fabfba1a286360ec372879a..cab81d5e9100879d7c536ddf5f5d660b6e962a01 100644 (file)
@@ -1,3 +1,14 @@
+2019-11-20  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-fnsummary.c (ipa_fn_summary::account_size_time): Allow
+       negative time in calls summary; correct roundoff errors
+       leading to negative times.
+       (ipa_merge_fn_summary_after_inlining): Update calls size time table
+       if present.
+       (ipa_update_overall_fn_summary): Add RESET parameter.
+       * ipa-fnsummary.h (ipa_update_overall_fn_summary): Update prototype.
+       * ipa-inline-transform.c (inline_call): Enable incremental updates.
+       
 2019-11-20  Richard Sandiford  <richard.sandiford@arm.com>
 
        * tree-vect-slp.c (vect_schedule_slp_instance): Restore stmt
index 0652207220a66f4fc89d3a5081a6a317a6244fc3..d0bbe71c979066040857d9658f4f12c63201d4e4 100644 (file)
@@ -176,7 +176,8 @@ ipa_fn_summary::account_size_time (int size, sreal time,
   if (!size && time == 0 && table)
     return;
 
-  gcc_assert (time >= 0);
+  /* Only for calls we are unaccounting what we previously recoreded.  */
+  gcc_checking_assert (time >= 0 || call);
 
   for (i = 0; vec_safe_iterate (table, i, &e); i++)
     if (e->exec_predicate == exec_pred
@@ -226,6 +227,10 @@ ipa_fn_summary::account_size_time (int size, sreal time,
     {
       e->size += size;
       e->time += time;
+      gcc_checking_assert (e->time >= -1);
+      /* Tolerate small roundoff issues.  */
+      if (e->time < 0)
+       e->time = 0;
     }
 }
 
@@ -3897,6 +3902,21 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
     info->estimated_stack_size = peak;
 
   inline_update_callee_summaries (edge->callee, es->loop_depth);
+  if (info->call_size_time_table)
+    {
+      int edge_size = 0;
+      sreal edge_time = 0;
+
+      estimate_edge_size_and_time (edge, &edge_size, NULL, &edge_time, vNULL,
+                                  vNULL, vNULL, 0);
+      /* Unaccount size and time of the optimized out call.  */
+      info->account_size_time (-edge_size, -edge_time,
+                              es->predicate ? *es->predicate : true,
+                              es->predicate ? *es->predicate : true,
+                              true);
+      /* Account new calls.  */
+      summarize_calls_size_and_time (edge->callee, info);
+    }
 
   /* Free summaries that are not maintained for inline clones/edges.  */
   ipa_call_summaries->remove (edge);
@@ -3905,10 +3925,11 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
 }
 
 /* For performance reasons ipa_merge_fn_summary_after_inlining is not updating
-   overall size and time.  Recompute it.  */
+   overall size and time.  Recompute it.
+   If RESET is true also recompute call_time_size_table.  */
 
 void
-ipa_update_overall_fn_summary (struct cgraph_node *node)
+ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset)
 {
   class ipa_fn_summary *info = ipa_fn_summaries->get (node);
   class ipa_size_summary *size_info = ipa_size_summaries->get (node);
@@ -3923,7 +3944,8 @@ ipa_update_overall_fn_summary (struct cgraph_node *node)
       info->time += e->time;
     }
   info->min_size = (*info->size_time_table)[0].size;
-  vec_free (info->call_size_time_table);
+  if (reset)
+    vec_free (info->call_size_time_table);
   if (node->callees || node->indirect_calls)
     estimate_calls_size_and_time (node, &size_info->size, &info->min_size,
                                  &info->time, NULL,
index 5822adbce203816039290e50cd58ea272eaa5589..a50978aacb8914e4c2e3bbc224055c452a7b71c9 100644 (file)
@@ -358,7 +358,7 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
                                        int *, sreal *, sreal *,
                                        ipa_hints *);
 void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
-void ipa_update_overall_fn_summary (struct cgraph_node *node);
+void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
 void compute_fn_summary (struct cgraph_node *, bool);
 
 
index 8b9588982f325431f4d6a08ea0c3e79387526da5..e54752191b738ab4db93e4cb4d44c15aa1e70b69 100644 (file)
@@ -489,9 +489,9 @@ inline_call (struct cgraph_edge *e, bool update_original,
     mark_all_inlined_calls_cdtor (e->callee);
   if (opt_for_fn (e->caller->decl, optimize))
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
-  check_speculations (e->callee, new_edges);
+  bool removed_p = check_speculations (e->callee, new_edges);
   if (update_overall_summary)
-    ipa_update_overall_fn_summary (to);
+    ipa_update_overall_fn_summary (to, new_edges_found || removed_p);
   else
     /* Update self size by the estimate so overall function growth limits
        work for further inlining into this function.  Before inlining