Commit c170d40f by Jan Hubicka Committed by Jan Hubicka

re PR middle-end/54146 (Very slow compile with attribute((flatten)))


	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
parent 938ff79a
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> 2012-08-09 Richard Henderson <rth@redhat.com>
* config/s390/s390.c (s390_expand_insv): Use VOIDmode in gen_rtx_SET. * config/s390/s390.c (s390_expand_insv): Use VOIDmode in gen_rtx_SET.
......
...@@ -2680,13 +2680,6 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -2680,13 +2680,6 @@ inline_merge_summary (struct cgraph_edge *edge)
} }
remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map, remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
clause, &toplev_predicate); 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_update_callee_summaries (edge->callee,
inline_edge_summary (edge)->loop_depth); inline_edge_summary (edge)->loop_depth);
...@@ -2696,12 +2689,29 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -2696,12 +2689,29 @@ inline_merge_summary (struct cgraph_edge *edge)
/* Similarly remove param summaries. */ /* Similarly remove param summaries. */
VEC_free (inline_param_summary_t, heap, es->param); VEC_free (inline_param_summary_t, heap, es->param);
VEC_free (int, heap, operand_map); 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->time = (info->time + INLINE_TIME_SCALE / 2) / INLINE_TIME_SCALE;
info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE; info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE;
} }
/* Estimate the time cost for the caller when inlining EDGE. /* Estimate the time cost for the caller when inlining EDGE.
Only to be called via estimate_edge_time, that handles the Only to be called via estimate_edge_time, that handles the
caching mechanism. caching mechanism.
......
...@@ -193,13 +193,17 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, ...@@ -193,13 +193,17 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
/* Mark edge E as inlined and update callgraph accordingly. UPDATE_ORIGINAL /* Mark edge E as inlined and update callgraph accordingly. UPDATE_ORIGINAL
specify whether profile of original function should be updated. If any new 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 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. */ result of inlining. */
bool bool
inline_call (struct cgraph_edge *e, bool update_original, inline_call (struct cgraph_edge *e, bool update_original,
VEC (cgraph_edge_p, heap) **new_edges, VEC (cgraph_edge_p, heap) **new_edges,
int *overall_size) int *overall_size, bool update_overall_summary)
{ {
int old_size = 0, new_size = 0; int old_size = 0, new_size = 0;
struct cgraph_node *to = NULL; struct cgraph_node *to = NULL;
...@@ -244,6 +248,8 @@ inline_call (struct cgraph_edge *e, bool update_original, ...@@ -244,6 +248,8 @@ inline_call (struct cgraph_edge *e, bool update_original,
old_size = inline_summary (to)->size; old_size = inline_summary (to)->size;
inline_merge_summary (e); inline_merge_summary (e);
if (update_overall_summary)
inline_update_overall_summary (to);
new_size = inline_summary (to)->size; new_size = inline_summary (to)->size;
if (overall_size) if (overall_size)
*overall_size += new_size - old_size; *overall_size += new_size - old_size;
......
...@@ -1209,7 +1209,7 @@ recursive_inlining (struct cgraph_edge *edge, ...@@ -1209,7 +1209,7 @@ recursive_inlining (struct cgraph_edge *edge,
} }
cgraph_redirect_edge_callee (curr, master_clone); 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); lookup_recursive_calls (node, curr->callee, heap);
n++; n++;
} }
...@@ -1480,7 +1480,7 @@ inline_small_functions (void) ...@@ -1480,7 +1480,7 @@ inline_small_functions (void)
fprintf (dump_file, " Peeling recursion with depth %i\n", depth); fprintf (dump_file, " Peeling recursion with depth %i\n", depth);
gcc_checking_assert (!callee->global.inlined_to); 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) if (flag_indirect_inlining)
add_new_edges_to_heap (heap, new_indirect_edges); add_new_edges_to_heap (heap, new_indirect_edges);
...@@ -1602,7 +1602,7 @@ flatten_function (struct cgraph_node *node, bool early) ...@@ -1602,7 +1602,7 @@ flatten_function (struct cgraph_node *node, bool early)
xstrdup (cgraph_node_name (callee)), xstrdup (cgraph_node_name (callee)),
xstrdup (cgraph_node_name (e->caller))); xstrdup (cgraph_node_name (e->caller)));
orig_callee = callee; orig_callee = callee;
inline_call (e, true, NULL, NULL); inline_call (e, true, NULL, NULL, false);
if (e->callee != orig_callee) if (e->callee != orig_callee)
orig_callee->symbol.aux = (void *) node; orig_callee->symbol.aux = (void *) node;
flatten_function (e->callee, early); flatten_function (e->callee, early);
...@@ -1611,6 +1611,8 @@ flatten_function (struct cgraph_node *node, bool early) ...@@ -1611,6 +1611,8 @@ flatten_function (struct cgraph_node *node, bool early)
} }
node->symbol.aux = NULL; 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 /* Decide on the inlining. We do so in the topological order to avoid
...@@ -1710,7 +1712,7 @@ ipa_inline (void) ...@@ -1710,7 +1712,7 @@ ipa_inline (void)
inline_summary (node->callers->caller)->size); inline_summary (node->callers->caller)->size);
} }
inline_call (node->callers, true, NULL, NULL); inline_call (node->callers, true, NULL, NULL, true);
if (dump_file) if (dump_file)
fprintf (dump_file, fprintf (dump_file,
" Inlined into %s which now has %i size\n", " Inlined into %s which now has %i size\n",
...@@ -1768,9 +1770,11 @@ inline_always_inline_functions (struct cgraph_node *node) ...@@ -1768,9 +1770,11 @@ inline_always_inline_functions (struct cgraph_node *node)
fprintf (dump_file, " Inlining %s into %s (always_inline).\n", fprintf (dump_file, " Inlining %s into %s (always_inline).\n",
xstrdup (cgraph_node_name (e->callee)), xstrdup (cgraph_node_name (e->callee)),
xstrdup (cgraph_node_name (e->caller))); xstrdup (cgraph_node_name (e->caller)));
inline_call (e, true, NULL, NULL); inline_call (e, true, NULL, NULL, false);
inlined = true; inlined = true;
} }
if (inlined)
inline_update_overall_summary (node);
return inlined; return inlined;
} }
...@@ -1818,7 +1822,7 @@ early_inline_small_functions (struct cgraph_node *node) ...@@ -1818,7 +1822,7 @@ early_inline_small_functions (struct cgraph_node *node)
fprintf (dump_file, " Inlining %s into %s.\n", fprintf (dump_file, " Inlining %s into %s.\n",
xstrdup (cgraph_node_name (callee)), xstrdup (cgraph_node_name (callee)),
xstrdup (cgraph_node_name (e->caller))); xstrdup (cgraph_node_name (e->caller)));
inline_call (e, true, NULL, NULL); inline_call (e, true, NULL, NULL, true);
inlined = true; inlined = true;
} }
......
...@@ -173,6 +173,7 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *, ...@@ -173,6 +173,7 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
int *, int *); int *, int *);
int do_estimate_growth (struct cgraph_node *); int do_estimate_growth (struct cgraph_node *);
void inline_merge_summary (struct cgraph_edge *edge); 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_growth (struct cgraph_edge *edge);
int do_estimate_edge_time (struct cgraph_edge *edge); int do_estimate_edge_time (struct cgraph_edge *edge);
void initialize_growth_caches (void); void initialize_growth_caches (void);
...@@ -180,7 +181,7 @@ void free_growth_caches (void); ...@@ -180,7 +181,7 @@ void free_growth_caches (void);
void compute_inline_parameters (struct cgraph_node *, bool); void compute_inline_parameters (struct cgraph_node *, bool);
/* In ipa-inline-transform.c */ /* 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 *); unsigned int inline_transform (struct cgraph_node *);
void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *); void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment