Commit f658ad30 by Jan Hubicka Committed by Jan Hubicka

cgraphunit.c (symbol_table::process_new_functions): Call ipa_free_size_summary.


	* cgraphunit.c (symbol_table::process_new_functions): Call
	ipa_free_size_summary.
	* ipa-cp.c (ipcp_cloning_candidate_p): Update.
	(devirtualization_time_bonus): Update.
	(ipcp_propagate_stage): Update.
	* ipa-fnsummary.c (ipa_size_summaries): New.
	(ipa_fn_summary_alloc): Alloc size summary.
	(dump_ipa_call_summary): Update.
	(ipa_dump_fn_summary): Update.
	(analyze_function_body): Update.
	(compute_fn_summary): Likewise.
	(ipa_get_stack_frame_offset): New function.
	(inline_update_callee_summaries): Do not update frame offsets.
	(ipa_merge_fn_summary_after_inlining): Update frame offsets here;
	remove call and function summary.
	(ipa_update_overall_fn_summary): Update.
	(inline_read_section): Update.
	(ipa_fn_summary_write): Update.
	(ipa_free_fn_summary): Do not remove summaries.
	(ipa_free_size_summary): New.
	(release summary pass): Also run at WPA.
	* ipa-fnsummary.h (ipa_size_summary): Declare.
	(ipa_fn_summary): Remove size, self_size, stack_frame_offset,
	estimated_self_stack_size.
	(ipa_size_summary_t): New type.
	(ipa_size_summaries): Declare.
	(ipa_free_size_summary): Declare.
	(ipa_get_stack_frame_offset): Declare.
	* ipa-icf.c (sem_function::merge): Update.
	* ipa-inline-analysis.c (estimate_size_after_inlining): Update.
	(estimate_growth): Update.
	(growth_likely_positive): Update.
	(clone_inlined_nodes): Update.
	(inline_call): Update.
	* ipa-inline.c (caller_growth_limits): Update.
	(edge_badness): Update.
	(recursive_inlining): Update.
	(inline_small_functions): Update.
	(inline_to_all_callers_1): Update.
	* ipa-prop.h (ipa_edge_args_sum_t): Update comment.
	* lto-partition.c (add_symbol_to_partition_1): Update.
	(undo_parittion): Update.

From-SVN: r277424
parent 90a15807
2019-10-24 Jan Hubicka <hubicka@ucw.cz>
* cgraphunit.c (symbol_table::process_new_functions): Call
ipa_free_size_summary.
* ipa-cp.c (ipcp_cloning_candidate_p): Update.
(devirtualization_time_bonus): Update.
(ipcp_propagate_stage): Update.
* ipa-fnsummary.c (ipa_size_summaries): New.
(ipa_fn_summary_alloc): Alloc size summary.
(dump_ipa_call_summary): Update.
(ipa_dump_fn_summary): Update.
(analyze_function_body): Update.
(compute_fn_summary): Likewise.
(ipa_get_stack_frame_offset): New function.
(inline_update_callee_summaries): Do not update frame offsets.
(ipa_merge_fn_summary_after_inlining): Update frame offsets here;
remove call and function summary.
(ipa_update_overall_fn_summary): Update.
(inline_read_section): Update.
(ipa_fn_summary_write): Update.
(ipa_free_fn_summary): Do not remove summaries.
(ipa_free_size_summary): New.
(release summary pass): Also run at WPA.
* ipa-fnsummary.h (ipa_size_summary): Declare.
(ipa_fn_summary): Remove size, self_size, stack_frame_offset,
estimated_self_stack_size.
(ipa_size_summary_t): New type.
(ipa_size_summaries): Declare.
(ipa_free_size_summary): Declare.
(ipa_get_stack_frame_offset): Declare.
* ipa-icf.c (sem_function::merge): Update.
* ipa-inline-analysis.c (estimate_size_after_inlining): Update.
(estimate_growth): Update.
(growth_likely_positive): Update.
(clone_inlined_nodes): Update.
(inline_call): Update.
* ipa-inline.c (caller_growth_limits): Update.
(edge_badness): Update.
(recursive_inlining): Update.
(inline_small_functions): Update.
(inline_to_all_callers_1): Update.
* ipa-prop.h (ipa_edge_args_sum_t): Update comment.
2019-10-24 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/altivec.md (altivec_vavgu<VI_char>): Rename to...
......@@ -340,7 +340,10 @@ symbol_table::process_new_functions (void)
and splitting. This is redundant for functions added late.
Just throw away whatever it did. */
if (!summaried_computed)
ipa_free_fn_summary ();
{
ipa_free_fn_summary ();
ipa_free_size_summary ();
}
}
else if (ipa_fn_summaries != NULL)
compute_fn_summary (node, true);
......
......@@ -731,7 +731,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
init_caller_stats (&stats);
node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
if (ipa_fn_summaries->get (node)->self_size < stats.n_calls)
if (ipa_size_summaries->get (node)->self_size < stats.n_calls)
{
if (dump_file)
fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
......@@ -2629,13 +2629,14 @@ devirtualization_time_bonus (struct cgraph_node *node,
if (!isummary->inlinable)
continue;
int size = ipa_size_summaries->get (callee)->size;
/* FIXME: The values below need re-considering and perhaps also
integrating into the cost metrics, at lest in some very basic way. */
if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)
if (size <= MAX_INLINE_INSNS_AUTO / 4)
res += 31 / ((int)speculative + 1);
else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)
else if (size <= MAX_INLINE_INSNS_AUTO / 2)
res += 15 / ((int)speculative + 1);
else if (isummary->size <= MAX_INLINE_INSNS_AUTO
else if (size <= MAX_INLINE_INSNS_AUTO
|| DECL_DECLARED_INLINE_P (callee->decl))
res += 7 / ((int)speculative + 1);
}
......@@ -3334,7 +3335,7 @@ ipcp_propagate_stage (class ipa_topo_info *topo)
ipa_get_param_count (info));
initialize_node_lattices (node);
}
ipa_fn_summary *s = ipa_fn_summaries->get (node);
ipa_size_summary *s = ipa_size_summaries->get (node);
if (node->definition && !node->alias && s != NULL)
overall_size += s->self_size;
max_count = max_count.max (node->count.ipa ());
......
......@@ -82,6 +82,30 @@ public:
sreal GTY((skip)) time;
};
/* Summary about function and stack frame sizes. We keep this info
for inline clones and also for WPA streaming. For this reason this is not
part of ipa_fn_summary which exists only for offline functions. */
class ipa_size_summary
{
public:
/* Estimated stack frame consumption by the function. */
HOST_WIDE_INT estimated_self_stack_size;
/* Size of the function body. */
int self_size;
/* Estimated size of the function after inlining. */
int size;
ipa_size_summary ()
: estimated_self_stack_size (0), self_size (0), size (0)
{
}
/* Copy constructor. */
ipa_size_summary (const ipa_size_summary &s)
: estimated_self_stack_size (0), self_size (s.self_size), size (s.size)
{
}
};
/* Function inlining information. */
class GTY(()) ipa_fn_summary
{
......@@ -89,10 +113,10 @@ public:
/* Keep all field empty so summary dumping works during its computation.
This is useful for debugging. */
ipa_fn_summary ()
: estimated_self_stack_size (0), self_size (0), min_size (0),
: min_size (0),
inlinable (false), single_caller (false),
fp_expressions (false), estimated_stack_size (false),
stack_frame_offset (false), time (0), size (0), conds (NULL),
time (0), conds (NULL),
size_time_table (NULL), loop_iterations (NULL), loop_stride (NULL),
growth (0), scc_no (0)
{
......@@ -100,13 +124,11 @@ public:
/* Copy constructor. */
ipa_fn_summary (const ipa_fn_summary &s)
: estimated_self_stack_size (s.estimated_self_stack_size),
self_size (s.self_size), min_size (s.min_size),
: min_size (s.min_size),
inlinable (s.inlinable), single_caller (s.single_caller),
fp_expressions (s.fp_expressions),
estimated_stack_size (s.estimated_stack_size),
stack_frame_offset (s.stack_frame_offset), time (s.time), size (s.size),
conds (s.conds), size_time_table (s.size_time_table),
time (s.time), conds (s.conds), size_time_table (s.size_time_table),
loop_iterations (s.loop_iterations), loop_stride (s.loop_stride),
growth (s.growth), scc_no (s.scc_no)
{}
......@@ -116,10 +138,6 @@ public:
/* Information about the function body itself. */
/* Estimated stack frame consumption by the function. */
HOST_WIDE_INT estimated_self_stack_size;
/* Size of the function body. */
int self_size;
/* Minimal size increase after inlining. */
int min_size;
......@@ -137,11 +155,8 @@ public:
/* Estimated stack frame consumption by the function. */
HOST_WIDE_INT estimated_stack_size;
/* Expected offset of the stack frame of function. */
HOST_WIDE_INT stack_frame_offset;
/* Estimated size of the function after inlining. */
/* Estimated runtime of function after inlining. */
sreal GTY((skip)) time;
int size;
/* Conditional size/time information. The summaries are being
merged during inlining. */
......@@ -201,6 +216,24 @@ public:
extern GTY(()) fast_function_summary <ipa_fn_summary *, va_gc>
*ipa_fn_summaries;
class ipa_size_summary_t:
public fast_function_summary <ipa_size_summary *, va_gc>
{
public:
ipa_size_summary_t (symbol_table *symtab):
fast_function_summary <ipa_size_summary *, va_gc> (symtab) {}
static ipa_size_summary_t *create_ggc (symbol_table *symtab)
{
class ipa_size_summary_t *summary = new (ggc_alloc <ipa_size_summary_t> ())
ipa_size_summary_t (symtab);
summary->disable_insertion_hook ();
return summary;
}
};
extern fast_function_summary <ipa_size_summary *, va_heap>
*ipa_size_summaries;
/* Information kept about callgraph edges. */
class ipa_call_summary
{
......@@ -256,6 +289,7 @@ void ipa_dump_fn_summaries (FILE *f);
void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node);
void ipa_dump_hints (FILE *f, ipa_hints);
void ipa_free_fn_summary (void);
void ipa_free_size_summary (void);
void inline_analyze_function (struct cgraph_node *node);
void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
vec<tree>,
......@@ -289,5 +323,6 @@ void estimate_node_size_and_time (struct cgraph_node *node,
inline_param_summary);
void ipa_fnsummary_c_finalize (void);
HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
#endif /* GCC_IPA_FNSUMMARY_H */
......@@ -1142,8 +1142,8 @@ sem_function::merge (sem_item *alias_item)
"cannot create wrapper of stdarg function.\n");
}
else if (ipa_fn_summaries
&& ipa_fn_summaries->get (alias) != NULL
&& ipa_fn_summaries->get (alias)->self_size <= 2)
&& ipa_size_summaries->get (alias) != NULL
&& ipa_size_summaries->get (alias)->self_size <= 2)
{
if (dump_enabled_p ())
dump_printf (MSG_MISSED_OPTIMIZATION, "Wrapper creation is not "
......
......@@ -161,7 +161,8 @@ do_estimate_edge_time (struct cgraph_edge *edge)
/* When caching, update the cache entry. */
if (edge_growth_cache != NULL)
{
ipa_fn_summaries->get_create (edge->callee)->min_size = min_size;
ipa_fn_summaries->get (edge->callee->function_symbol ())->min_size
= min_size;
edge_growth_cache_entry *entry
= edge_growth_cache->get_create (edge);
entry->time = time;
......@@ -265,7 +266,7 @@ estimate_size_after_inlining (struct cgraph_node *node,
struct cgraph_edge *edge)
{
class ipa_call_summary *es = ipa_call_summaries->get (edge);
ipa_fn_summary *s = ipa_fn_summaries->get (node);
ipa_size_summary *s = ipa_size_summaries->get (node);
if (!es->predicate || *es->predicate != false)
{
int size = s->size + estimate_edge_growth (edge);
......@@ -321,7 +322,7 @@ int
estimate_growth (struct cgraph_node *node)
{
struct growth_data d = { node, false, false, 0 };
class ipa_fn_summary *info = ipa_fn_summaries->get (node);
class ipa_size_summary *info = ipa_size_summaries->get (node);
node->call_for_symbol_and_aliases (do_estimate_growth_1, &d, true);
......@@ -396,7 +397,7 @@ growth_likely_positive (struct cgraph_node *node,
|| node->address_taken)
return true;
max_callers = ipa_fn_summaries->get (node)->size * 4 / edge_growth + 2;
max_callers = ipa_size_summaries->get (node)->size * 4 / edge_growth + 2;
for (e = node->callers; e; e = e->next_caller)
{
......
......@@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
{
gcc_assert (!e->callee->alias);
if (overall_size)
*overall_size -= ipa_fn_summaries->get (e->callee)->size;
*overall_size -= ipa_size_summaries->get (e->callee)->size;
nfunctions_inlined++;
}
duplicate = false;
......@@ -478,7 +478,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
gcc_assert (curr->callee->global.inlined_to == to);
old_size = ipa_fn_summaries->get (to)->size;
old_size = ipa_size_summaries->get (to)->size;
ipa_merge_fn_summary_after_inlining (e);
if (e->in_polymorphic_cdtor)
mark_all_inlined_calls_cdtor (e->callee);
......@@ -492,8 +492,8 @@ inline_call (struct cgraph_edge *e, bool update_original,
work for further inlining into this function. Before inlining
the function we inlined to again we expect the caller to update
the overall summary. */
ipa_fn_summaries->get (to)->size += estimated_growth;
new_size = ipa_fn_summaries->get (to)->size;
ipa_size_summaries->get (to)->size += estimated_growth;
new_size = ipa_size_summaries->get (to)->size;
if (callee->calls_comdat_local)
to->calls_comdat_local = true;
......
......@@ -150,8 +150,7 @@ caller_growth_limits (struct cgraph_edge *e)
int newsize;
int limit = 0;
HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
ipa_fn_summary *info, *what_info;
ipa_fn_summary *outer_info = ipa_fn_summaries->get (to);
ipa_size_summary *outer_info = ipa_size_summaries->get (to);
/* Look for function e->caller is inlined to. While doing
so work out the largest function body on the way. As
......@@ -163,28 +162,29 @@ caller_growth_limits (struct cgraph_edge *e)
too much in order to prevent compiler from exploding". */
while (true)
{
info = ipa_fn_summaries->get (to);
if (limit < info->self_size)
limit = info->self_size;
if (stack_size_limit < info->estimated_self_stack_size)
stack_size_limit = info->estimated_self_stack_size;
ipa_size_summary *size_info = ipa_size_summaries->get (to);
if (limit < size_info->self_size)
limit = size_info->self_size;
if (stack_size_limit < size_info->estimated_self_stack_size)
stack_size_limit = size_info->estimated_self_stack_size;
if (to->global.inlined_to)
to = to->callers->caller;
else
break;
}
what_info = ipa_fn_summaries->get (what);
ipa_fn_summary *what_info = ipa_fn_summaries->get (what);
ipa_size_summary *what_size_info = ipa_size_summaries->get (what);
if (limit < what_info->self_size)
limit = what_info->self_size;
if (limit < what_size_info->self_size)
limit = what_size_info->self_size;
limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
/* Check the size after inlining against the function limits. But allow
the function to shrink if it went over the limits by forced inlining. */
newsize = estimate_size_after_inlining (to, e);
if (newsize >= info->size
if (newsize >= ipa_size_summaries->get (what)->size
&& newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
&& newsize > limit)
{
......@@ -203,7 +203,7 @@ caller_growth_limits (struct cgraph_edge *e)
stack_size_limit += ((gcov_type)stack_size_limit
* PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);
inlined_stack = (outer_info->stack_frame_offset
inlined_stack = (ipa_get_stack_frame_offset (to)
+ outer_info->estimated_self_stack_size
+ what_info->estimated_stack_size);
/* Check new stack consumption with stack consumption at the place
......@@ -213,7 +213,7 @@ caller_growth_limits (struct cgraph_edge *e)
inline call, we can inline, too.
This bit overoptimistically assume that we are good at stack
packing. */
&& inlined_stack > info->estimated_stack_size
&& inlined_stack > ipa_fn_summaries->get (to)->estimated_stack_size
&& inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))
{
e->inline_failed = CIF_LARGE_STACK_FRAME_GROWTH_LIMIT;
......@@ -1115,7 +1115,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
gcc_checking_assert ((edge_time * 100
- callee_info->time * 101).to_int () <= 0
|| callee->count.ipa ().initialized_p ());
gcc_checking_assert (growth <= callee_info->size);
gcc_checking_assert (growth <= ipa_size_summaries->get (callee)->size);
if (dump)
{
......@@ -1219,7 +1219,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
and it is not called once. */
if (!caller_info->single_caller && overall_growth < caller_growth
&& caller_info->inlinable
&& caller_info->size
&& ipa_size_summaries->get (caller)->size
< (DECL_DECLARED_INLINE_P (caller->decl)
? inline_insns_single (caller, false)
: inline_insns_auto (caller, false)))
......@@ -1243,7 +1243,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
overall_growth += 256 * 256 - 256;
denominator *= overall_growth;
}
denominator *= ipa_fn_summaries->get (caller)->size + growth;
denominator *= ipa_size_summaries->get (caller)->size + growth;
badness = - numerator / denominator;
......@@ -1646,8 +1646,8 @@ recursive_inlining (struct cgraph_edge *edge,
dump_printf_loc (MSG_NOTE, edge->call_stmt,
"\n Inlined %i times, "
"body grown from size %i to %i, time %f to %f\n", n,
ipa_fn_summaries->get (master_clone)->size,
ipa_fn_summaries->get (node)->size,
ipa_size_summaries->get (master_clone)->size,
ipa_size_summaries->get (node)->size,
ipa_fn_summaries->get (master_clone)->time.to_double (),
ipa_fn_summaries->get (node)->time.to_double ());
......@@ -1871,7 +1871,7 @@ inline_small_functions (void)
/* Do not account external functions, they will be optimized out
if not inlined. Also only count the non-cold portion of program. */
if (inline_account_function_p (node))
initial_size += info->size;
initial_size += ipa_size_summaries->get (node)->size;
info->growth = estimate_growth (node);
int num_calls = 0;
......@@ -1887,7 +1887,8 @@ inline_small_functions (void)
n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle)
if (opt_for_fn (n2->decl, optimize))
{
ipa_fn_summary *info2 = ipa_fn_summaries->get (n2);
ipa_fn_summary *info2 = ipa_fn_summaries->get
(n2->global.inlined_to ? n2->global.inlined_to : n2);
if (info2->scc_no)
break;
info2->scc_no = id;
......@@ -2048,7 +2049,7 @@ inline_small_functions (void)
fprintf (dump_file,
"\nConsidering %s with %i size\n",
callee->dump_name (),
ipa_fn_summaries->get (callee)->size);
ipa_size_summaries->get (callee)->size);
fprintf (dump_file,
" to be inlined into %s in %s:%i\n"
" Estimated badness is %f, frequency %.2f.\n",
......@@ -2174,7 +2175,7 @@ inline_small_functions (void)
if (dump_enabled_p ())
{
ipa_fn_summary *s = ipa_fn_summaries->get (edge->caller);
ipa_fn_summary *s = ipa_fn_summaries->get (where);
/* dump_printf can't handle %+i. */
char buf_net_change[100];
......@@ -2185,7 +2186,9 @@ inline_small_functions (void)
" Inlined %C into %C which now has time %f and "
"size %i, net change of %s.\n",
edge->callee, edge->caller,
s->time.to_double (), s->size, buf_net_change);
s->time.to_double (),
ipa_size_summaries->get (edge->caller)->size,
buf_net_change);
}
if (min_size > overall_size)
{
......@@ -2322,11 +2325,11 @@ inline_to_all_callers_1 (struct cgraph_node *node, void *data,
fprintf (dump_file,
"\nInlining %s size %i.\n",
ultimate->name (),
ipa_fn_summaries->get (ultimate)->size);
ipa_size_summaries->get (ultimate)->size);
fprintf (dump_file,
" Called once from %s %i insns.\n",
node->callers->caller->name (),
ipa_fn_summaries->get (node->callers->caller)->size);
ipa_size_summaries->get (node->callers->caller)->size);
}
/* Remember which callers we inlined to, delaying updating the
......@@ -2337,7 +2340,7 @@ inline_to_all_callers_1 (struct cgraph_node *node, void *data,
fprintf (dump_file,
" Inlined into %s which now has %i size\n",
caller->name (),
ipa_fn_summaries->get (caller)->size);
ipa_size_summaries->get (caller)->size);
if (!(*num_calls)--)
{
if (dump_file)
......
......@@ -641,7 +641,7 @@ class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
ipa_edge_args_sum_t (symbol_table *table, bool ggc)
: call_summary<ipa_edge_args *> (table, ggc) { }
/* Hook that is called by summary when an edge is duplicated. */
/* Hook that is called by summary when an edge is removed. */
virtual void remove (cgraph_edge *cs, ipa_edge_args *args);
/* Hook that is called by summary when an edge is duplicated. */
virtual void duplicate (cgraph_edge *src,
......
2019-10-24 Jan Hubicka <hubicka@ucw.cz>
* lto-partition.c (add_symbol_to_partition_1): Update.
(undo_parittion): Update.
2019-10-23 Jan Hubicka <hubicka@ucw.cz>
* lto-common.c (lto_file_finalize): Add order attribute.
......
......@@ -171,7 +171,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
{
struct cgraph_edge *e;
if (!node->alias && c == SYMBOL_PARTITION)
part->insns += ipa_fn_summaries->get (cnode)->size;
part->insns += ipa_size_summaries->get (cnode)->size;
/* Add all inline clones and callees that are duplicated. */
for (e = cnode->callees; e; e = e->next_callee)
......@@ -291,7 +291,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node))
&& node->get_partitioning_class () == SYMBOL_PARTITION)
partition->insns -= ipa_fn_summaries->get (cnode)->size;
partition->insns -= ipa_size_summaries->get (cnode)->size;
lto_symtab_encoder_delete_node (partition->encoder, node);
node->aux = (void *)((size_t)node->aux - 1);
}
......@@ -528,7 +528,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
else
order.safe_push (node);
if (!node->alias)
total_size += ipa_fn_summaries->get (node)->size;
total_size += ipa_size_summaries->get (node)->size;
}
original_total_size = total_size;
......
......@@ -498,9 +498,9 @@ do_whole_program_analysis (void)
else
gcc_unreachable ();
/* Inline summaries are needed for balanced partitioning. Free them now so
/* Size summaries are needed for balanced partitioning. Free them now so
the memory can be used for streamer caches. */
ipa_free_fn_summary ();
ipa_free_size_summary ();
/* AUX pointers are used by partitioning code to bookkeep number of
partitions symbol is in. This is no longer needed. */
......
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