Commit b48ccf0d by Jan Hubicka Committed by Jan Hubicka

ipa-inline.c (edge_badness): Reduce precision; use scc hints.

	* ipa-inline.c (edge_badness): Reduce precision; use scc hints.
	(inline_small_functions): Fix dumps; update all callees after inlining.
	* ipa-inline.h (INLINE_HINT_in_scc, INLINE_HINT_same_scc): New constants.
	(inline summary): Add SCC_NO.
	* ipa-inline-analysis.c (dump_inline_hints): Dump SCC hints.
	(reset_inline_summary): Reset scc_no.
	(estimate_node_size_and_time): Set in_scc hint.
	(do_estimate_edge_time): Add same_scc hint.
	(do_estimate_edge_hints): Likewise.

From-SVN: r192888
parent f457c50c
2012-10-28 Jan Hubicka <jh@suse.cz>
* ipa-inline.c (edge_badness): Reduce precision; use scc hints.
(inline_small_functions): Fix dumps; update all callees after inlining.
* ipa-inline.h (INLINE_HINT_in_scc, INLINE_HINT_same_scc): New constants.
(inline summary): Add SCC_NO.
* ipa-inline-analysis.c (dump_inline_hints): Dump SCC hints.
(reset_inline_summary): Reset scc_no.
(estimate_node_size_and_time): Set in_scc hint.
(do_estimate_edge_time): Add same_scc hint.
(do_estimate_edge_hints): Likewise.
2012-10-28 Andreas Schwab <schwab@linux-m68k.org>
* doc/cppopts.texi: Fix use of @item vs. @itemx inside @table.
......@@ -639,6 +639,16 @@ dump_inline_hints (FILE *f, inline_hints hints)
hints &= ~INLINE_HINT_loop_stride;
fprintf (f, " loop_stride");
}
if (hints & INLINE_HINT_same_scc)
{
hints &= ~INLINE_HINT_same_scc;
fprintf (f, " same_scc");
}
if (hints & INLINE_HINT_in_scc)
{
hints &= ~INLINE_HINT_in_scc;
fprintf (f, " in_scc");
}
gcc_assert (!hints);
}
......@@ -973,6 +983,7 @@ reset_inline_summary (struct cgraph_node *node)
info->stack_frame_offset = 0;
info->size = 0;
info->time = 0;
info->scc_no = 0;
if (info->loop_iterations)
{
pool_free (edge_predicate_pool, info->loop_iterations);
......@@ -2825,7 +2836,8 @@ estimate_node_size_and_time (struct cgraph_node *node,
if (info->loop_stride
&& !evaluate_predicate (info->loop_stride, possible_truths))
hints |=INLINE_HINT_loop_stride;
if (info->scc_no)
hints |= INLINE_HINT_in_scc;
estimate_calls_size_and_time (node, &size, &time, &hints, possible_truths,
known_vals, known_binfos, known_aggs);
......@@ -3323,6 +3335,9 @@ do_estimate_edge_time (struct cgraph_edge *edge)
/* When caching, update the cache entry. */
if (edge_growth_cache)
{
struct cgraph_node *to = (edge->caller->global.inlined_to
? edge->caller->global.inlined_to
: edge->caller);
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache)
<= edge->uid)
VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache,
......@@ -3332,6 +3347,9 @@ do_estimate_edge_time (struct cgraph_edge *edge)
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size
= size + (size >= 0);
if (inline_summary (to)->scc_no
&& inline_summary (to)->scc_no == inline_summary (callee)->scc_no)
hints |= INLINE_HINT_same_scc;
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints
= hints + 1;
}
......@@ -3392,6 +3410,9 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
VEC (tree, heap) *known_vals;
VEC (tree, heap) *known_binfos;
VEC (ipa_agg_jump_function_p, heap) *known_aggs;
struct cgraph_node *to = (edge->caller->global.inlined_to
? edge->caller->global.inlined_to
: edge->caller);
/* When we do caching, use do_estimate_edge_time to populate the entry. */
......@@ -3417,6 +3438,9 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
VEC_free (tree, heap, known_vals);
VEC_free (tree, heap, known_binfos);
VEC_free (ipa_agg_jump_function_p, heap, known_aggs);
if (inline_summary (to)->scc_no
&& inline_summary (to)->scc_no == inline_summary (callee)->scc_no)
hints |= INLINE_HINT_same_scc;
return hints;
}
......
......@@ -845,8 +845,8 @@ edge_badness (struct cgraph_edge *edge, bool dump)
precision for small bandesses (those are interesting) yet we don't
overflow for growths that are still in interesting range.
Fixed point arithmetic with point at 8th bit. */
badness = ((gcov_type)growth) * (1<<(19+8));
Fixed point arithmetic with point at 6th bit. */
badness = ((gcov_type)growth) * (1<<(19+6));
badness = (badness + div / 2) / div;
/* Overall growth of inlining all calls of function matters: we want to
......@@ -861,9 +861,9 @@ edge_badness (struct cgraph_edge *edge, bool dump)
We might mix the valud into the fraction by taking into account
relative growth of the unit, but for now just add the number
into resulting fraction. */
if (badness > INT_MAX / 2)
if (badness > INT_MAX / 4)
{
badness = INT_MAX / 2;
badness = INT_MAX / 4;
if (dump)
fprintf (dump_file, "Badness overflow\n");
}
......@@ -871,6 +871,10 @@ edge_badness (struct cgraph_edge *edge, bool dump)
| INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride))
badness /= 8;
if (hints & (INLINE_HINT_same_scc))
badness *= 4;
if (hints & (INLINE_HINT_in_scc))
badness *= 2;
if (dump)
{
fprintf (dump_file,
......@@ -1337,16 +1341,10 @@ inline_small_functions (void)
if (flag_indirect_inlining)
new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8);
if (dump_file)
fprintf (dump_file,
"\nDeciding on inlining of small functions. Starting with size %i.\n",
initial_size);
/* Compute overall unit size and other global parameters used by badness
metrics. */
max_count = 0;
initialize_growth_caches ();
FOR_EACH_DEFINED_FUNCTION (node)
if (!node->global.inlined_to)
......@@ -1355,15 +1353,25 @@ inline_small_functions (void)
|| node->thunk.thunk_p)
{
struct inline_summary *info = inline_summary (node);
struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->symbol.aux;
if (!DECL_EXTERNAL (node->symbol.decl))
initial_size += info->size;
info->scc_no = (dfs && dfs->next_cycle && dfs->next_cycle != node
? dfs->scc_no + 1 : 0);
}
for (edge = node->callers; edge; edge = edge->next_caller)
if (max_count < edge->count)
max_count = edge->count;
}
ipa_free_postorder_info ();
initialize_growth_caches ();
if (dump_file)
fprintf (dump_file,
"\nDeciding on inlining of small functions. Starting with size %i.\n",
initial_size);
overall_size = initial_size;
max_size = compute_max_insns (overall_size);
......@@ -1528,7 +1536,7 @@ inline_small_functions (void)
reset_edge_caches (edge->callee);
reset_node_growth_cache (callee);
update_callee_keys (edge_heap, edge->callee, updated_nodes);
update_callee_keys (edge_heap, where, updated_nodes);
}
where = edge->caller;
if (where->global.inlined_to)
......
......@@ -47,7 +47,9 @@ typedef struct GTY(()) condition
enum inline_hints_vals {
INLINE_HINT_indirect_call = 1,
INLINE_HINT_loop_iterations = 2,
INLINE_HINT_loop_stride = 4
INLINE_HINT_loop_stride = 4,
INLINE_HINT_same_scc = 8,
INLINE_HINT_in_scc = 16
};
typedef int inline_hints;
......@@ -127,6 +129,8 @@ struct GTY(()) inline_summary
/* Predicate on when some loop in the function becomes to have known
stride. */
struct predicate * GTY((skip)) loop_stride;
/* Number of SCC on the beggining of inlining process. */
int scc_no;
};
......
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