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