Commit 263e19c7 by Jan Hubicka Committed by Jan Hubicka

ipa-inline-analysis.c (cgraph_2edge_hook_list, [...]): Remove.

	* ipa-inline-analysis.c (cgraph_2edge_hook_list, cgraph_edge_hook_list,
	inline_edge_removal_hook, inline_edge_duplication_hook): Remove.
	(inline_edge_summary_vec): Turn into ...
	(ipa_call_summaries): ... this one.
	(redirect_to_unreachable, edge_set_predicate,
	evaluate_properties_for_edge, inline_summary_alloc,
	reset_ipa_call_summary, reset_inline_summary,
	inline_summary_t::duplicate): Update.
	(inline_edge_duplication_hook): Turn to ...
	(ipa_call_summary_t::duplicate): ... this one.
	(inline_edge_removal_hook): Turn to ...
	(ipa_call_summary_t::remove): ... this one.
	(dump_inline_edge_summary): Turn to ...
	(dump_ipa_call_summary): ... this one.
	(estimate_function_body_sizes): Update.
	(inline_update_callee_summaries): Update.
	(remap_edge_change_prob): Update.
	(remap_edge_summaries): Update.
	(inline_merge_summary): Update.
	(do_estimate_edge_time): Update.
	(inline_generate_summary): Update.
	(inline_read_section): Update.
	(inline_read_summary): Update.
	(inline_free_summary): Update.
	* ipa-inline.c (can_inline_edge_p): Update.
	(compute_inlined_call_time): Update.
	(want_inline_small_function_p): Update.
	(edge_badness): Update.
	(early_inliner): Update.
	* ipa-inline.h (inline_edge_summary): Turn to ...
	(ipa_call_summary): ... this one.
	(ipa_call_summary_t): New class.
	(inline_edge_summary_t, inline_edge_summary_vec): Remove.
	(ipa_call_summaries): New.
	(inline_edge_summary): Remove.
	(estimate_edge_growth): Update.
	* ipa-profile.c (ipa_propagate_frequency_1): Update.
	* ipa-prop.c (ipa_make_edge_direct_to_target): Update.
	* ipa-split.c (execute_split_functions): Update.
	* ipa.c (symbol_table::remove_unreachable_nodes): Update.

From-SVN: r248262
parent 035ab826
2017-05-19 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline-analysis.c (cgraph_2edge_hook_list, cgraph_edge_hook_list,
inline_edge_removal_hook, inline_edge_duplication_hook): Remove.
(inline_edge_summary_vec): Turn into ...
(ipa_call_summaries): ... this one.
(redirect_to_unreachable, edge_set_predicate,
evaluate_properties_for_edge, inline_summary_alloc,
reset_ipa_call_summary, reset_inline_summary,
inline_summary_t::duplicate): Update.
(inline_edge_duplication_hook): Turn to ...
(ipa_call_summary_t::duplicate): ... this one.
(inline_edge_removal_hook): Turn to ...
(ipa_call_summary_t::remove): ... this one.
(dump_inline_edge_summary): Turn to ...
(dump_ipa_call_summary): ... this one.
(estimate_function_body_sizes): Update.
(inline_update_callee_summaries): Update.
(remap_edge_change_prob): Update.
(remap_edge_summaries): Update.
(inline_merge_summary): Update.
(do_estimate_edge_time): Update.
(inline_generate_summary): Update.
(inline_read_section): Update.
(inline_read_summary): Update.
(inline_free_summary): Update.
* ipa-inline.c (can_inline_edge_p): Update.
(compute_inlined_call_time): Update.
(want_inline_small_function_p): Update.
(edge_badness): Update.
(early_inliner): Update.
* ipa-inline.h (inline_edge_summary): Turn to ...
(ipa_call_summary): ... this one.
(ipa_call_summary_t): New class.
(inline_edge_summary_t, inline_edge_summary_vec): Remove.
(ipa_call_summaries): New.
(inline_edge_summary): Remove.
(estimate_edge_growth): Update.
* ipa-profile.c (ipa_propagate_frequency_1): Update.
* ipa-prop.c (ipa_make_edge_direct_to_target): Update.
* ipa-split.c (execute_split_functions): Update.
* ipa.c (symbol_table::remove_unreachable_nodes): Update.
2017-05-19 Richard Biener <rguenther@suse.de> 2017-05-19 Richard Biener <rguenther@suse.de>
PR middle-end/80764 PR middle-end/80764
......
...@@ -86,17 +86,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -86,17 +86,9 @@ along with GCC; see the file COPYING3. If not see
#include "cfgexpand.h" #include "cfgexpand.h"
#include "gimplify.h" #include "gimplify.h"
/* Holders of ipa cgraph hooks: */ /* Summaries. */
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
static void inline_edge_removal_hook (struct cgraph_edge *, void *);
static void inline_edge_duplication_hook (struct cgraph_edge *,
struct cgraph_edge *, void *);
/* VECtor holding inline summaries.
In GGC memory because conditions might point to constant trees. */
function_summary <inline_summary *> *inline_summaries; function_summary <inline_summary *> *inline_summaries;
vec<inline_edge_summary_t> inline_edge_summary_vec; call_summary <ipa_call_summary *> *ipa_call_summaries;
/* Cached node/edge growths. */ /* Cached node/edge growths. */
vec<edge_growth_cache_entry> edge_growth_cache; vec<edge_growth_cache_entry> edge_growth_cache;
...@@ -254,7 +246,7 @@ redirect_to_unreachable (struct cgraph_edge *e) ...@@ -254,7 +246,7 @@ redirect_to_unreachable (struct cgraph_edge *e)
e->make_direct (target); e->make_direct (target);
else else
e->redirect_callee (target); e->redirect_callee (target);
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
e->inline_failed = CIF_UNREACHABLE; e->inline_failed = CIF_UNREACHABLE;
e->frequency = 0; e->frequency = 0;
e->count = 0; e->count = 0;
...@@ -279,7 +271,7 @@ edge_set_predicate (struct cgraph_edge *e, predicate *predicate) ...@@ -279,7 +271,7 @@ edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
&& (!e->speculative || e->callee)) && (!e->speculative || e->callee))
e = redirect_to_unreachable (e); e = redirect_to_unreachable (e);
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
if (predicate && *predicate != true) if (predicate && *predicate != true)
{ {
if (!es->predicate) if (!es->predicate)
...@@ -457,7 +449,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, ...@@ -457,7 +449,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
{ {
struct ipa_node_params *parms_info; struct ipa_node_params *parms_info;
struct ipa_edge_args *args = IPA_EDGE_REF (e); struct ipa_edge_args *args = IPA_EDGE_REF (e);
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
int i, count = ipa_get_cs_argument_count (args); int i, count = ipa_get_cs_argument_count (args);
if (e->caller->global.inlined_to) if (e->caller->global.inlined_to)
...@@ -540,36 +532,25 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, ...@@ -540,36 +532,25 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
static void static void
inline_summary_alloc (void) inline_summary_alloc (void)
{ {
if (!edge_removal_hook_holder)
edge_removal_hook_holder =
symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
if (!edge_duplication_hook_holder)
edge_duplication_hook_holder =
symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
if (!inline_summaries) if (!inline_summaries)
inline_summaries = (inline_summary_t*) inline_summary_t::create_ggc (symtab); inline_summaries = inline_summary_t::create_ggc (symtab);
if (!ipa_call_summaries)
if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid) ipa_call_summaries = new ipa_call_summary_t (symtab, false);
inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
} }
/* We are called multiple time for given function; clear /* We are called multiple time for given function; clear
data from previous run so they are not cumulated. */ data from previous run so they are not cumulated. */
static void static void
reset_inline_edge_summary (struct cgraph_edge *e) reset_ipa_call_summary (struct cgraph_edge *e)
{ {
if (e->uid < (int) inline_edge_summary_vec.length ()) struct ipa_call_summary *es = ipa_call_summaries->get (e);
{
struct inline_edge_summary *es = inline_edge_summary (e);
es->call_stmt_size = es->call_stmt_time = 0; es->call_stmt_size = es->call_stmt_time = 0;
if (es->predicate) if (es->predicate)
edge_predicate_pool.remove (es->predicate); edge_predicate_pool.remove (es->predicate);
es->predicate = NULL; es->predicate = NULL;
es->param.release (); es->param.release ();
}
} }
/* We are called multiple time for given function; clear /* We are called multiple time for given function; clear
...@@ -608,9 +589,9 @@ reset_inline_summary (struct cgraph_node *node, ...@@ -608,9 +589,9 @@ reset_inline_summary (struct cgraph_node *node,
vec_free (info->conds); vec_free (info->conds);
vec_free (info->entry); vec_free (info->entry);
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
reset_inline_edge_summary (e); reset_ipa_call_summary (e);
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = e->next_callee)
reset_inline_edge_summary (e); reset_ipa_call_summary (e);
info->fp_expressions = false; info->fp_expressions = false;
} }
...@@ -726,7 +707,7 @@ inline_summary_t::duplicate (cgraph_node *src, ...@@ -726,7 +707,7 @@ inline_summary_t::duplicate (cgraph_node *src,
for (edge = dst->callees; edge; edge = next) for (edge = dst->callees; edge; edge = next)
{ {
predicate new_predicate; predicate new_predicate;
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
next = edge->next_callee; next = edge->next_callee;
if (!edge->inline_failed) if (!edge->inline_failed)
...@@ -745,7 +726,7 @@ inline_summary_t::duplicate (cgraph_node *src, ...@@ -745,7 +726,7 @@ inline_summary_t::duplicate (cgraph_node *src,
for (edge = dst->indirect_calls; edge; edge = next) for (edge = dst->indirect_calls; edge; edge = next)
{ {
predicate new_predicate; predicate new_predicate;
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
next = edge->next_callee; next = edge->next_callee;
gcc_checking_assert (edge->inline_failed); gcc_checking_assert (edge->inline_failed);
...@@ -799,17 +780,13 @@ inline_summary_t::duplicate (cgraph_node *src, ...@@ -799,17 +780,13 @@ inline_summary_t::duplicate (cgraph_node *src,
/* Hook that is called by cgraph.c when a node is duplicated. */ /* Hook that is called by cgraph.c when a node is duplicated. */
static void void
inline_edge_duplication_hook (struct cgraph_edge *src, ipa_call_summary_t::duplicate (struct cgraph_edge *src,
struct cgraph_edge *dst, struct cgraph_edge *dst,
ATTRIBUTE_UNUSED void *data) struct ipa_call_summary *srcinfo,
struct ipa_call_summary *info)
{ {
struct inline_edge_summary *info; *info = *srcinfo;
struct inline_edge_summary *srcinfo;
inline_summary_alloc ();
info = inline_edge_summary (dst);
srcinfo = inline_edge_summary (src);
memcpy (info, srcinfo, sizeof (struct inline_edge_summary));
info->predicate = NULL; info->predicate = NULL;
edge_set_predicate (dst, srcinfo->predicate); edge_set_predicate (dst, srcinfo->predicate);
info->param = srcinfo->param.copy (); info->param = srcinfo->param.copy ();
...@@ -825,13 +802,13 @@ inline_edge_duplication_hook (struct cgraph_edge *src, ...@@ -825,13 +802,13 @@ inline_edge_duplication_hook (struct cgraph_edge *src,
/* Keep edge cache consistent across edge removal. */ /* Keep edge cache consistent across edge removal. */
static void void
inline_edge_removal_hook (struct cgraph_edge *edge, ipa_call_summary_t::remove (struct cgraph_edge *edge,
void *data ATTRIBUTE_UNUSED) struct ipa_call_summary *)
{ {
if (edge_growth_cache.exists ()) if (edge_growth_cache.exists ())
reset_edge_growth_cache (edge); reset_edge_growth_cache (edge);
reset_inline_edge_summary (edge); reset_ipa_call_summary (edge);
} }
...@@ -858,13 +835,13 @@ free_growth_caches (void) ...@@ -858,13 +835,13 @@ free_growth_caches (void)
Indent by INDENT. */ Indent by INDENT. */
static void static void
dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node, dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
struct inline_summary *info) struct inline_summary *info)
{ {
struct cgraph_edge *edge; struct cgraph_edge *edge;
for (edge = node->callees; edge; edge = edge->next_callee) for (edge = node->callees; edge; edge = edge->next_callee)
{ {
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
struct cgraph_node *callee = edge->callee->ultimate_alias_target (); struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
int i; int i;
...@@ -906,12 +883,12 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node, ...@@ -906,12 +883,12 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
(int) inline_summaries->get (callee)->stack_frame_offset, (int) inline_summaries->get (callee)->stack_frame_offset,
(int) inline_summaries->get (callee)->estimated_self_stack_size, (int) inline_summaries->get (callee)->estimated_self_stack_size,
(int) inline_summaries->get (callee)->estimated_stack_size); (int) inline_summaries->get (callee)->estimated_stack_size);
dump_inline_edge_summary (f, indent + 2, callee, info); dump_ipa_call_summary (f, indent + 2, callee, info);
} }
} }
for (edge = node->indirect_calls; edge; edge = edge->next_callee) for (edge = node->indirect_calls; edge; edge = edge->next_callee)
{ {
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
fprintf (f, "%*sindirect call loop depth:%2i freq:%4i size:%2i" fprintf (f, "%*sindirect call loop depth:%2i freq:%4i size:%2i"
" time: %2i", " time: %2i",
indent, "", indent, "",
...@@ -991,7 +968,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node) ...@@ -991,7 +968,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
s->array_index->dump (f, s->conds); s->array_index->dump (f, s->conds);
} }
fprintf (f, " calls:\n"); fprintf (f, " calls:\n");
dump_inline_edge_summary (f, 4, node, s); dump_ipa_call_summary (f, 4, node, s);
fprintf (f, "\n"); fprintf (f, "\n");
} }
} }
...@@ -2234,7 +2211,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) ...@@ -2234,7 +2211,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
&& !gimple_call_internal_p (stmt)) && !gimple_call_internal_p (stmt))
{ {
struct cgraph_edge *edge = node->get_edge (stmt); struct cgraph_edge *edge = node->get_edge (stmt);
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
/* Special case: results of BUILT_IN_CONSTANT_P will be always /* Special case: results of BUILT_IN_CONSTANT_P will be always
resolved as constant. We however don't want to optimize resolved as constant. We however don't want to optimize
...@@ -2487,7 +2464,7 @@ compute_inline_parameters (struct cgraph_node *node, bool early) ...@@ -2487,7 +2464,7 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
if (node->thunk.thunk_p) if (node->thunk.thunk_p)
{ {
struct inline_edge_summary *es = inline_edge_summary (node->callees); struct ipa_call_summary *es = ipa_call_summaries->get (node->callees);
predicate t = true; predicate t = true;
node->local.can_change_signature = false; node->local.can_change_signature = false;
...@@ -2687,7 +2664,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size, ...@@ -2687,7 +2664,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
vec<ipa_agg_jump_function_p> known_aggs, vec<ipa_agg_jump_function_p> known_aggs,
inline_hints *hints) inline_hints *hints)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
int call_size = es->call_stmt_size; int call_size = es->call_stmt_size;
int call_time = es->call_stmt_time; int call_time = es->call_stmt_time;
int cur_size; int cur_size;
...@@ -2725,10 +2702,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size, ...@@ -2725,10 +2702,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size,
struct cgraph_edge *e; struct cgraph_edge *e;
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
{ {
if (inline_edge_summary_vec.length () <= (unsigned) e->uid) struct ipa_call_summary *es = ipa_call_summaries->get (e);
continue;
struct inline_edge_summary *es = inline_edge_summary (e);
/* Do not care about zero sized builtins. */ /* Do not care about zero sized builtins. */
if (e->inline_failed && !es->call_stmt_size) if (e->inline_failed && !es->call_stmt_size)
...@@ -2759,10 +2733,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size, ...@@ -2759,10 +2733,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size,
} }
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = e->next_callee)
{ {
if (inline_edge_summary_vec.length () <= (unsigned) e->uid) struct ipa_call_summary *es = ipa_call_summaries->get (e);
continue;
struct inline_edge_summary *es = inline_edge_summary (e);
if (!es->predicate if (!es->predicate
|| es->predicate->evaluate (possible_truths)) || es->predicate->evaluate (possible_truths))
estimate_edge_size_and_time (e, size, estimate_edge_size_and_time (e, size,
...@@ -2964,10 +2935,10 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth) ...@@ -2964,10 +2935,10 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
{ {
if (!e->inline_failed) if (!e->inline_failed)
inline_update_callee_summaries (e->callee, depth); inline_update_callee_summaries (e->callee, depth);
inline_edge_summary (e)->loop_depth += depth; ipa_call_summaries->get (e)->loop_depth += depth;
} }
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = e->next_callee)
inline_edge_summary (e)->loop_depth += depth; ipa_call_summaries->get (e)->loop_depth += depth;
} }
/* Update change_prob of EDGE after INLINED_EDGE has been inlined. /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
...@@ -2984,9 +2955,9 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge, ...@@ -2984,9 +2955,9 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
{ {
int i; int i;
struct ipa_edge_args *args = IPA_EDGE_REF (edge); struct ipa_edge_args *args = IPA_EDGE_REF (edge);
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
struct inline_edge_summary *inlined_es struct ipa_call_summary *inlined_es
= inline_edge_summary (inlined_edge); = ipa_call_summaries->get (inlined_edge);
for (i = 0; i < ipa_get_cs_argument_count (args); i++) for (i = 0; i < ipa_get_cs_argument_count (args); i++)
{ {
...@@ -3033,7 +3004,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, ...@@ -3033,7 +3004,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
struct cgraph_edge *e, *next; struct cgraph_edge *e, *next;
for (e = node->callees; e; e = next) for (e = node->callees; e; e = next)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
predicate p; predicate p;
next = e->next_callee; next = e->next_callee;
...@@ -3059,7 +3030,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, ...@@ -3059,7 +3030,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
} }
for (e = node->indirect_calls; e; e = next) for (e = node->indirect_calls; e; e = next)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
predicate p; predicate p;
next = e->next_callee; next = e->next_callee;
...@@ -3120,7 +3091,7 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -3120,7 +3091,7 @@ inline_merge_summary (struct cgraph_edge *edge)
int i; int i;
predicate toplev_predicate; predicate toplev_predicate;
predicate true_p = true; predicate true_p = true;
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
if (es->predicate) if (es->predicate)
toplev_predicate = *es->predicate; toplev_predicate = *es->predicate;
...@@ -3210,7 +3181,7 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -3210,7 +3181,7 @@ inline_merge_summary (struct cgraph_edge *edge)
operand_map, offset_map, clause, &toplev_predicate); operand_map, offset_map, clause, &toplev_predicate);
inline_update_callee_summaries (edge->callee, inline_update_callee_summaries (edge->callee,
inline_edge_summary (edge)->loop_depth); ipa_call_summaries->get (edge)->loop_depth);
/* We do not maintain predicates of inlined edges, free it. */ /* We do not maintain predicates of inlined edges, free it. */
edge_set_predicate (edge, &true_p); edge_set_predicate (edge, &true_p);
...@@ -3284,7 +3255,7 @@ do_estimate_edge_time (struct cgraph_edge *edge) ...@@ -3284,7 +3255,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
vec<tree> known_vals; vec<tree> known_vals;
vec<ipa_polymorphic_call_context> known_contexts; vec<ipa_polymorphic_call_context> known_contexts;
vec<ipa_agg_jump_function_p> known_aggs; vec<ipa_agg_jump_function_p> known_aggs;
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
int min_size; int min_size;
callee = edge->callee->ultimate_alias_target (); callee = edge->callee->ultimate_alias_target ();
...@@ -3419,7 +3390,7 @@ int ...@@ -3419,7 +3390,7 @@ int
estimate_size_after_inlining (struct cgraph_node *node, estimate_size_after_inlining (struct cgraph_node *node,
struct cgraph_edge *edge) struct cgraph_edge *edge)
{ {
struct inline_edge_summary *es = inline_edge_summary (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
if (!es->predicate || *es->predicate != false) if (!es->predicate || *es->predicate != false)
{ {
int size = inline_summaries->get (node)->size + estimate_edge_growth (edge); int size = inline_summaries->get (node)->size + estimate_edge_growth (edge);
...@@ -3666,9 +3637,9 @@ inline_generate_summary (void) ...@@ -3666,9 +3637,9 @@ inline_generate_summary (void)
/* Write inline summary for edge E to OB. */ /* Write inline summary for edge E to OB. */
static void static void
read_inline_edge_summary (struct lto_input_block *ib, struct cgraph_edge *e) read_ipa_call_summary (struct lto_input_block *ib, struct cgraph_edge *e)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
predicate p; predicate p;
int length, i; int length, i;
...@@ -3772,9 +3743,9 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, ...@@ -3772,9 +3743,9 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
p.stream_in (&ib); p.stream_in (&ib);
set_hint_predicate (&info->array_index, p); set_hint_predicate (&info->array_index, p);
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
read_inline_edge_summary (&ib, e); read_ipa_call_summary (&ib, e);
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = e->next_callee)
read_inline_edge_summary (&ib, e); read_ipa_call_summary (&ib, e);
} }
lto_free_section_data (file_data, LTO_section_inline_summary, NULL, data, lto_free_section_data (file_data, LTO_section_inline_summary, NULL, data,
...@@ -3826,9 +3797,9 @@ inline_read_summary (void) ...@@ -3826,9 +3797,9 @@ inline_read_summary (void)
/* Write inline summary for edge E to OB. */ /* Write inline summary for edge E to OB. */
static void static void
write_inline_edge_summary (struct output_block *ob, struct cgraph_edge *e) write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct ipa_call_summary *es = ipa_call_summaries->get (e);
int i; int i;
streamer_write_uhwi (ob, es->call_stmt_size); streamer_write_uhwi (ob, es->call_stmt_size);
...@@ -3922,9 +3893,9 @@ inline_write_summary (void) ...@@ -3922,9 +3893,9 @@ inline_write_summary (void)
else else
streamer_write_uhwi (ob, 0); streamer_write_uhwi (ob, 0);
for (edge = cnode->callees; edge; edge = edge->next_callee) for (edge = cnode->callees; edge; edge = edge->next_callee)
write_inline_edge_summary (ob, edge); write_ipa_call_summary (ob, edge);
for (edge = cnode->indirect_calls; edge; edge = edge->next_callee) for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
write_inline_edge_summary (ob, edge); write_ipa_call_summary (ob, edge);
} }
} }
streamer_write_char_stream (ob->main_stream, 0); streamer_write_char_stream (ob->main_stream, 0);
...@@ -3942,19 +3913,15 @@ void ...@@ -3942,19 +3913,15 @@ void
inline_free_summary (void) inline_free_summary (void)
{ {
struct cgraph_node *node; struct cgraph_node *node;
if (edge_removal_hook_holder) if (!ipa_call_summaries)
symtab->remove_edge_removal_hook (edge_removal_hook_holder);
edge_removal_hook_holder = NULL;
if (edge_duplication_hook_holder)
symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
edge_duplication_hook_holder = NULL;
if (!inline_edge_summary_vec.exists ())
return; return;
FOR_EACH_DEFINED_FUNCTION (node) FOR_EACH_DEFINED_FUNCTION (node)
if (!node->alias) if (!node->alias)
reset_inline_summary (node, inline_summaries->get (node)); reset_inline_summary (node, inline_summaries->get (node));
inline_summaries->release (); inline_summaries->release ();
inline_summaries = NULL; inline_summaries = NULL;
inline_edge_summary_vec.release (); ipa_call_summaries->release ();
delete ipa_call_summaries;
ipa_call_summaries = NULL;
edge_predicate_pool.release (); edge_predicate_pool.release ();
} }
...@@ -493,7 +493,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, ...@@ -493,7 +493,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
> opt_for_fn (caller->decl, optimize))) > opt_for_fn (caller->decl, optimize)))
{ {
if (estimate_edge_time (e) if (estimate_edge_time (e)
>= 20 + inline_edge_summary (e)->call_stmt_time) >= 20 + ipa_call_summaries->get (e)->call_stmt_time)
{ {
e->inline_failed = CIF_OPTIMIZATION_MISMATCH; e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
inlinable = false; inlinable = false;
...@@ -672,7 +672,7 @@ compute_inlined_call_time (struct cgraph_edge *edge, ...@@ -672,7 +672,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
/* This calculation should match one in ipa-inline-analysis.c /* This calculation should match one in ipa-inline-analysis.c
(estimate_edge_size_and_time). */ (estimate_edge_size_and_time). */
time -= (sreal) edge->frequency time -= (sreal) edge->frequency
* inline_edge_summary (edge)->call_stmt_time / CGRAPH_FREQ_BASE; * ipa_call_summaries->get (edge)->call_stmt_time / CGRAPH_FREQ_BASE;
time += caller_time; time += caller_time;
if (time <= 0) if (time <= 0)
time = ((sreal) 1) >> 8; time = ((sreal) 1) >> 8;
...@@ -722,16 +722,16 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) ...@@ -722,16 +722,16 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
else if ((!DECL_DECLARED_INLINE_P (callee->decl) else if ((!DECL_DECLARED_INLINE_P (callee->decl)
&& (!e->count || !e->maybe_hot_p ())) && (!e->count || !e->maybe_hot_p ()))
&& inline_summaries->get (callee)->min_size && inline_summaries->get (callee)->min_size
- inline_edge_summary (e)->call_stmt_size - ipa_call_summaries->get (e)->call_stmt_size
> MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO)) > (unsigned)MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
{ {
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT; e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
want_inline = false; want_inline = false;
} }
else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count) else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
&& inline_summaries->get (callee)->min_size && inline_summaries->get (callee)->min_size
- inline_edge_summary (e)->call_stmt_size - ipa_call_summaries->get (e)->call_stmt_size
> 16 * MAX_INLINE_INSNS_SINGLE) > (unsigned)16 * MAX_INLINE_INSNS_SINGLE)
{ {
e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl) e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT ? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT
...@@ -1172,7 +1172,7 @@ edge_badness (struct cgraph_edge *edge, bool dump) ...@@ -1172,7 +1172,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
of functions fully inlined in program. */ of functions fully inlined in program. */
else else
{ {
int nest = MIN (inline_edge_summary (edge)->loop_depth, 8); int nest = MIN (ipa_call_summaries->get (edge)->loop_depth, 8);
badness = growth; badness = growth;
/* Decrease badness if call is nested. */ /* Decrease badness if call is nested. */
...@@ -2691,14 +2691,11 @@ early_inliner (function *fun) ...@@ -2691,14 +2691,11 @@ early_inliner (function *fun)
statements that don't have inline parameters computed. */ statements that don't have inline parameters computed. */
for (edge = node->callees; edge; edge = edge->next_callee) for (edge = node->callees; edge; edge = edge->next_callee)
{ {
if (inline_edge_summary_vec.length () > (unsigned) edge->uid) struct ipa_call_summary *es = ipa_call_summaries->get (edge);
{ es->call_stmt_size
struct inline_edge_summary *es = inline_edge_summary (edge); = estimate_num_insns (edge->call_stmt, &eni_size_weights);
es->call_stmt_size es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_size_weights); = estimate_num_insns (edge->call_stmt, &eni_time_weights);
es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_time_weights);
}
} }
inline_update_overall_summary (node); inline_update_overall_summary (node);
inlined = false; inlined = false;
...@@ -2719,14 +2716,12 @@ early_inliner (function *fun) ...@@ -2719,14 +2716,12 @@ early_inliner (function *fun)
for (edge = node->callees; edge; edge = edge->next_callee) for (edge = node->callees; edge; edge = edge->next_callee)
{ {
/* We have no summary for new bound store calls yet. */ /* We have no summary for new bound store calls yet. */
if (inline_edge_summary_vec.length () > (unsigned)edge->uid) struct ipa_call_summary *es = ipa_call_summaries->get (edge);
{ es->call_stmt_size
struct inline_edge_summary *es = inline_edge_summary (edge); = estimate_num_insns (edge->call_stmt, &eni_size_weights);
es->call_stmt_size es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_size_weights); = estimate_num_insns (edge->call_stmt, &eni_time_weights);
es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_time_weights);
}
if (edge->callee->decl if (edge->callee->decl
&& !gimple_check_call_matching_types ( && !gimple_check_call_matching_types (
edge->call_stmt, edge->callee->decl, false)) edge->call_stmt, edge->callee->decl, false))
......
...@@ -183,24 +183,33 @@ public: ...@@ -183,24 +183,33 @@ public:
extern GTY(()) function_summary <inline_summary *> *inline_summaries; extern GTY(()) function_summary <inline_summary *> *inline_summaries;
/* Information kept about callgraph edges. */ /* Information kept about callgraph edges. */
struct inline_edge_summary struct ipa_call_summary
{ {
/* Estimated size and time of the call statement. */
int call_stmt_size;
int call_stmt_time;
/* Depth of loop nest, 0 means no nesting. */
unsigned short int loop_depth;
class predicate *predicate; class predicate *predicate;
/* Array indexed by parameters. /* Vector indexed by parameters. */
0 means that parameter change all the time, REG_BR_PROB_BASE means
that parameter is constant. */
vec<inline_param_summary> param; vec<inline_param_summary> param;
/* Estimated size and time of the call statement. */
unsigned int call_stmt_size;
unsigned int call_stmt_time;
/* Depth of loop nest, 0 means no nesting. */
unsigned int loop_depth;
}; };
/* Need a typedef for inline_edge_summary because of inline function class ipa_call_summary_t: public call_summary <ipa_call_summary *>
'inline_edge_summary' below. */ {
typedef struct inline_edge_summary inline_edge_summary_t; public:
extern vec<inline_edge_summary_t> inline_edge_summary_vec; ipa_call_summary_t (symbol_table *symtab, bool ggc):
call_summary <ipa_call_summary *> (symtab, ggc) {}
/* Hook that is called by summary when an edge is duplicated. */
virtual void remove (cgraph_edge *cs, ipa_call_summary *);
/* Hook that is called by summary when an edge is duplicated. */
virtual void duplicate (cgraph_edge *src, cgraph_edge *dst,
ipa_call_summary *src_data,
ipa_call_summary *dst_data);
};
extern call_summary <ipa_call_summary *> *ipa_call_summaries;
/* Data we cache about callgraph edges during inlining to avoid expensive /* Data we cache about callgraph edges during inlining to avoid expensive
re-computations during the greedy algorithm. */ re-computations during the greedy algorithm. */
...@@ -256,12 +265,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *, ...@@ -256,12 +265,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
extern int ncalls_inlined; extern int ncalls_inlined;
extern int nfunctions_inlined; extern int nfunctions_inlined;
static inline struct inline_edge_summary *
inline_edge_summary (struct cgraph_edge *edge)
{
return &inline_edge_summary_vec[edge->uid];
}
/* Return estimated size of the inline sequence of EDGE. */ /* Return estimated size of the inline sequence of EDGE. */
...@@ -280,10 +283,10 @@ estimate_edge_size (struct cgraph_edge *edge) ...@@ -280,10 +283,10 @@ estimate_edge_size (struct cgraph_edge *edge)
static inline int static inline int
estimate_edge_growth (struct cgraph_edge *edge) estimate_edge_growth (struct cgraph_edge *edge)
{ {
gcc_checking_assert (inline_edge_summary (edge)->call_stmt_size gcc_checking_assert (ipa_call_summaries->get (edge)->call_stmt_size
|| !edge->callee->analyzed); || !edge->callee->analyzed);
return (estimate_edge_size (edge) return (estimate_edge_size (edge)
- inline_edge_summary (edge)->call_stmt_size); - ipa_call_summaries->get (edge)->call_stmt_size);
} }
/* Return estimated callee runtime increase after inlining /* Return estimated callee runtime increase after inlining
......
...@@ -348,7 +348,7 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data) ...@@ -348,7 +348,7 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
fprintf (dump_file, " Called by %s that is executed once\n", fprintf (dump_file, " Called by %s that is executed once\n",
edge->caller->name ()); edge->caller->name ());
d->maybe_unlikely_executed = false; d->maybe_unlikely_executed = false;
if (inline_edge_summary (edge)->loop_depth) if (ipa_call_summaries->get (edge)->loop_depth)
{ {
d->maybe_executed_once = false; d->maybe_executed_once = false;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
......
...@@ -2828,7 +2828,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, ...@@ -2828,7 +2828,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
bool speculative) bool speculative)
{ {
struct cgraph_node *callee; struct cgraph_node *callee;
struct inline_edge_summary *es = inline_edge_summary (ie); struct ipa_call_summary *es = ipa_call_summaries->get (ie);
bool unreachable = false; bool unreachable = false;
if (TREE_CODE (target) == ADDR_EXPR) if (TREE_CODE (target) == ADDR_EXPR)
...@@ -2977,7 +2977,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, ...@@ -2977,7 +2977,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
for direct call (adjusted by inline_edge_duplication_hook). */ for direct call (adjusted by inline_edge_duplication_hook). */
if (ie == orig) if (ie == orig)
{ {
es = inline_edge_summary (ie); es = ipa_call_summaries->get (ie);
es->call_stmt_size -= (eni_size_weights.indirect_call_cost es->call_stmt_size -= (eni_size_weights.indirect_call_cost
- eni_size_weights.call_cost); - eni_size_weights.call_cost);
es->call_stmt_time -= (eni_time_weights.indirect_call_cost es->call_stmt_time -= (eni_time_weights.indirect_call_cost
......
...@@ -1742,7 +1742,7 @@ execute_split_functions (void) ...@@ -1742,7 +1742,7 @@ execute_split_functions (void)
} }
/* This can be relaxed; function might become inlinable after splitting /* This can be relaxed; function might become inlinable after splitting
away the uninlinable part. */ away the uninlinable part. */
if (inline_edge_summary_vec.exists () if (inline_summaries
&& !inline_summaries->get (node)->inlinable) && !inline_summaries->get (node)->inlinable)
{ {
if (dump_file) if (dump_file)
......
...@@ -698,7 +698,7 @@ symbol_table::remove_unreachable_nodes (FILE *file) ...@@ -698,7 +698,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
symtab_node::checking_verify_symtab_nodes (); symtab_node::checking_verify_symtab_nodes ();
/* If we removed something, perhaps profile could be improved. */ /* If we removed something, perhaps profile could be improved. */
if (changed && optimize && inline_edge_summary_vec.exists ()) if (changed && optimize && ipa_call_summaries)
FOR_EACH_DEFINED_FUNCTION (node) FOR_EACH_DEFINED_FUNCTION (node)
ipa_propagate_frequency (node); ipa_propagate_frequency (node);
......
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