re PR middle-end/54146 (Very slow compile with attribute((flatten)))
authorJan Hubicka <jh@suse.cz>
Fri, 10 Aug 2012 07:52:23 +0000 (09:52 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 10 Aug 2012 07:52:23 +0000 (07:52 +0000)
PR middle-end/54146
* ipa-inline-transform.c (inline_call): Add UPDATE_OVERALL_SUMMARY
parameter; honnor it.
* ipa-inline.c (recursive_inlining): Update call
of inline_call.
(inline_small_functions): Likewise.
(ipa_inline): Likewise.
(inline_always_inline_functions): Likewise.
(early_inline_small_functions): Likewise.
(flatten_function): Do separate update of summary info.
* ipa-inline.h (inline_update_overall_summary): Declare.
(inline_call): Update.
* ipa-inline-analysis.c (inline_merge_summary): Break out
updating code to ...
(inline_update_overall_summary): Likewise.

From-SVN: r190283

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

index 242e2f0b953ff70a871fafa500a38841b4f74bcb..f610bed02910306567437be4ee9e712766f60c69 100644 (file)
@@ -1,3 +1,21 @@
+2012-08-09  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/54146
+       * ipa-inline-transform.c (inline_call): Add UPDATE_OVERALL_SUMMARY
+       parameter; honnor it.
+       * ipa-inline.c (recursive_inlining): Update call
+       of inline_call.
+       (inline_small_functions): Likewise.
+       (ipa_inline): Likewise.
+       (inline_always_inline_functions): Likewise.
+       (early_inline_small_functions): Likewise.
+       (flatten_function): Do separate update of summary info.
+       * ipa-inline.h (inline_update_overall_summary): Declare.
+       (inline_call): Update.
+       * ipa-inline-analysis.c (inline_merge_summary): Break out
+       updating code to ...
+       (inline_update_overall_summary): Likewise.
+
 2012-08-09  Richard Henderson  <rth@redhat.com>
 
        * config/s390/s390.c (s390_expand_insv): Use VOIDmode in gen_rtx_SET.
index 970be1ebca2a817c4b6f3513cd2e91ab9dd80623..a444e916f9cc23c863414e27479a248c3a2a5381 100644 (file)
@@ -2680,13 +2680,6 @@ inline_merge_summary (struct cgraph_edge *edge)
     }
   remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
                        clause, &toplev_predicate);
-  info->size = 0;
-  info->time = 0;
-  for (i = 0; VEC_iterate (size_time_entry, info->entry, i, e); i++)
-    info->size += e->size, info->time += e->time;
-  estimate_calls_size_and_time (to, &info->size, &info->time,
-                               ~(clause_t)(1 << predicate_false_condition),
-                               NULL, NULL);
 
   inline_update_callee_summaries (edge->callee,
                                  inline_edge_summary (edge)->loop_depth);
@@ -2696,12 +2689,29 @@ inline_merge_summary (struct cgraph_edge *edge)
   /* Similarly remove param summaries.  */
   VEC_free (inline_param_summary_t, heap, es->param);
   VEC_free (int, heap, operand_map);
+}
+
+/* For performance reasons inline_merge_summary is not updating overall size
+   and time.  Recompute it.  */
 
+void
+inline_update_overall_summary (struct cgraph_node *node)
+{
+  struct inline_summary *info = inline_summary (node);
+  size_time_entry *e;
+  int i;
+
+  info->size = 0;
+  info->time = 0;
+  for (i = 0; VEC_iterate (size_time_entry, info->entry, i, e); i++)
+    info->size += e->size, info->time += e->time;
+  estimate_calls_size_and_time (node, &info->size, &info->time,
+                               ~(clause_t)(1 << predicate_false_condition),
+                               NULL, NULL);
   info->time = (info->time + INLINE_TIME_SCALE / 2) / INLINE_TIME_SCALE;
   info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE;
 }
 
-
 /* Estimate the time cost for the caller when inlining EDGE.
    Only to be called via estimate_edge_time, that handles the
    caching mechanism.
index d64c6129835ce40ce1f8f3d387932a9a8ce1b042..53c468717c7d2655217b253f33dc989569cb8035 100644 (file)
@@ -193,13 +193,17 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
 /* Mark edge E as inlined and update callgraph accordingly.  UPDATE_ORIGINAL
    specify whether profile of original function should be updated.  If any new
    indirect edges are discovered in the process, add them to NEW_EDGES, unless
-   it is NULL.  Return true iff any new callgraph edges were discovered as a
+   it is NULL. If UPDATE_OVERALL_SUMMARY is false, do not bother to recompute overall
+   size of caller after inlining. Caller is required to eventually do it via
+   inline_update_overall_summary.
+
+   Return true iff any new callgraph edges were discovered as a
    result of inlining.  */
 
 bool
 inline_call (struct cgraph_edge *e, bool update_original,
             VEC (cgraph_edge_p, heap) **new_edges,
-            int *overall_size)
+            int *overall_size, bool update_overall_summary)
 {
   int old_size = 0, new_size = 0;
   struct cgraph_node *to = NULL;
@@ -244,6 +248,8 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   old_size = inline_summary (to)->size;
   inline_merge_summary (e);
+  if (update_overall_summary)
+   inline_update_overall_summary (to);
   new_size = inline_summary (to)->size;
   if (overall_size)
     *overall_size += new_size - old_size;
index 1a4594d746f7f536146e957586315c2c1a27c363..d8b66e673061c7157adcf7a2eafc18d2d71a30d1 100644 (file)
@@ -1209,7 +1209,7 @@ recursive_inlining (struct cgraph_edge *edge,
        }
 
       cgraph_redirect_edge_callee (curr, master_clone);
-      inline_call (curr, false, new_edges, &overall_size);
+      inline_call (curr, false, new_edges, &overall_size, true);
       lookup_recursive_calls (node, curr->callee, heap);
       n++;
     }
@@ -1480,7 +1480,7 @@ inline_small_functions (void)
            fprintf (dump_file, " Peeling recursion with depth %i\n", depth);
 
          gcc_checking_assert (!callee->global.inlined_to);
-         inline_call (edge, true, &new_indirect_edges, &overall_size);
+         inline_call (edge, true, &new_indirect_edges, &overall_size, true);
          if (flag_indirect_inlining)
            add_new_edges_to_heap (heap, new_indirect_edges);
 
@@ -1602,7 +1602,7 @@ flatten_function (struct cgraph_node *node, bool early)
                 xstrdup (cgraph_node_name (callee)),
                 xstrdup (cgraph_node_name (e->caller)));
       orig_callee = callee;
-      inline_call (e, true, NULL, NULL);
+      inline_call (e, true, NULL, NULL, false);
       if (e->callee != orig_callee)
        orig_callee->symbol.aux = (void *) node;
       flatten_function (e->callee, early);
@@ -1611,6 +1611,8 @@ flatten_function (struct cgraph_node *node, bool early)
     }
 
   node->symbol.aux = NULL;
+  if (!node->global.inlined_to)
+    inline_update_overall_summary (node);
 }
 
 /* Decide on the inlining.  We do so in the topological order to avoid
@@ -1710,7 +1712,7 @@ ipa_inline (void)
                               inline_summary (node->callers->caller)->size);
                    }
 
-                 inline_call (node->callers, true, NULL, NULL);
+                 inline_call (node->callers, true, NULL, NULL, true);
                  if (dump_file)
                    fprintf (dump_file,
                             " Inlined into %s which now has %i size\n",
@@ -1768,9 +1770,11 @@ inline_always_inline_functions (struct cgraph_node *node)
        fprintf (dump_file, "  Inlining %s into %s (always_inline).\n",
                 xstrdup (cgraph_node_name (e->callee)),
                 xstrdup (cgraph_node_name (e->caller)));
-      inline_call (e, true, NULL, NULL);
+      inline_call (e, true, NULL, NULL, false);
       inlined = true;
     }
+  if (inlined)
+    inline_update_overall_summary (node);
 
   return inlined;
 }
@@ -1818,7 +1822,7 @@ early_inline_small_functions (struct cgraph_node *node)
        fprintf (dump_file, " Inlining %s into %s.\n",
                 xstrdup (cgraph_node_name (callee)),
                 xstrdup (cgraph_node_name (e->caller)));
-      inline_call (e, true, NULL, NULL);
+      inline_call (e, true, NULL, NULL, true);
       inlined = true;
     }
 
index 824a6c5035069af93649be0a2e6d92b4142c1704..fbd0b9982b7cbf022a0bafa94fb2b7012728e1dc 100644 (file)
@@ -173,6 +173,7 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
                                        int *, int *);
 int do_estimate_growth (struct cgraph_node *);
 void inline_merge_summary (struct cgraph_edge *edge);
+void inline_update_overall_summary (struct cgraph_node *node);
 int do_estimate_edge_growth (struct cgraph_edge *edge);
 int do_estimate_edge_time (struct cgraph_edge *edge);
 void initialize_growth_caches (void);
@@ -180,7 +181,7 @@ void free_growth_caches (void);
 void compute_inline_parameters (struct cgraph_node *, bool);
 
 /* In ipa-inline-transform.c  */
-bool inline_call (struct cgraph_edge *, bool, VEC (cgraph_edge_p, heap) **, int *);
+bool inline_call (struct cgraph_edge *, bool, VEC (cgraph_edge_p, heap) **, int *, bool);
 unsigned int inline_transform (struct cgraph_node *);
 void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *);