ipa-inline-analysis.c (edge_set_predicate): Reset size/time when target is UNREACHABLE.

* ipa-inline-analysis.c (edge_set_predicate): Reset size/time when
	target is UNREACHABLE.
	(evaluate_properties_for_edge): If call statemet is available, use it
	to determine compile time constants.
	(estimate_function_body_sizes): Enable predicates for early inliner.
	(estimate_calls_size_and_time): Speedup.
	(inline_merge_summary): Evaluate properties for early inliner, too.

From-SVN: r219108
This commit is contained in:
Jan Hubicka 2014-12-30 12:36:00 +01:00 committed by Jan Hubicka
parent 6a81690ec8
commit bc9b4a9285
4 changed files with 94 additions and 6 deletions

View File

@ -1,3 +1,13 @@
2014-12-30 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline-analysis.c (edge_set_predicate): Reset size/time when
target is UNREACHABLE.
(evaluate_properties_for_edge): If call statemet is available, use it
to determine compile time constants.
(estimate_function_body_sizes): Enable predicates for early inliner.
(estimate_calls_size_and_time): Speedup.
(inline_merge_summary): Evaluate properties for early inliner, too.
2014-12-29 Steve Ellcey <sellcey@mips.com>
* config/mips/t-mti-linux (MULTILIB_EXCEPTIONS): Add exceptions

View File

@ -770,6 +770,8 @@ edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
e->redirect_callee (cgraph_node::get_create
(builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
e->inline_failed = CIF_UNREACHABLE;
es->call_stmt_size = 0;
es->call_stmt_time = 0;
if (callee)
callee->remove_symbol_and_inline_clones ();
}
@ -940,6 +942,14 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
{
struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
tree cst = ipa_value_from_jfunc (parms_info, jf);
if (!cst && e->call_stmt
&& i < (int)gimple_call_num_args (e->call_stmt))
{
cst = gimple_call_arg (e->call_stmt, i);
if (!is_gimple_min_invariant (cst))
cst = NULL;
}
if (cst)
{
gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
@ -958,6 +968,22 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
known_aggs[i] = &jf->agg;
}
}
else if (e->call_stmt && !e->call_stmt_cannot_inline_p
&& ((clause_ptr && info->conds) || known_vals_ptr))
{
int i, count = (int)gimple_call_num_args (e->call_stmt);
if (count && (info->conds || known_vals_ptr))
known_vals.safe_grow_cleared (count);
for (i = 0; i < count; i++)
{
tree cst = gimple_call_arg (e->call_stmt, i);
if (!is_gimple_min_invariant (cst))
cst = NULL;
if (cst)
known_vals[i] = cst;
}
}
if (clause_ptr)
*clause_ptr = evaluate_conditions_for_known_args (callee, inline_p,
@ -2464,10 +2490,22 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
info->conds = NULL;
info->entry = NULL;
if (opt_for_fn (node->decl, optimize) && !early)
/* When optimizing and analyzing for IPA inliner, initialize loop optimizer
so we can produce proper inline hints.
When optimizing and analyzing for early inliner, initialize node params
so we can produce correct BB predicates. */
if (opt_for_fn (node->decl, optimize))
{
calculate_dominance_info (CDI_DOMINATORS);
loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
if (!early)
loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
else
{
ipa_check_create_node_params ();
ipa_initialize_node_params (node);
}
if (ipa_node_params_sum)
{
@ -2704,7 +2742,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
time = MAX_TIME;
free (order);
if (!early && nonconstant_names.exists ())
if (nonconstant_names.exists () && !early)
{
struct loop *loop;
predicate loop_iterations = true_predicate ();
@ -2809,9 +2847,12 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
inline_summaries->get (node)->self_time = time;
inline_summaries->get (node)->self_size = size;
nonconstant_names.release ();
if (opt_for_fn (node->decl, optimize) && !early)
if (opt_for_fn (node->decl, optimize))
{
loop_optimizer_finalize ();
if (!early)
loop_optimizer_finalize ();
else
ipa_free_all_node_params ();
free_dominance_info (CDI_DOMINATORS);
}
if (dump_file)
@ -3062,6 +3103,13 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size,
for (e = node->callees; e; e = e->next_callee)
{
struct inline_edge_summary *es = inline_edge_summary (e);
/* Do not care about zero sized builtins. */
if (e->inline_failed && !es->call_stmt_size)
{
gcc_checking_assert (!es->call_stmt_time);
continue;
}
if (!es->predicate
|| evaluate_predicate (es->predicate, possible_truths))
{
@ -3522,13 +3570,14 @@ inline_merge_summary (struct cgraph_edge *edge)
else
toplev_predicate = true_predicate ();
if (callee_info->conds)
evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL);
if (ipa_node_params_sum && callee_info->conds)
{
struct ipa_edge_args *args = IPA_EDGE_REF (edge);
int count = ipa_get_cs_argument_count (args);
int i;
evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL);
if (count)
{
operand_map.safe_grow_cleared (count);

View File

@ -1,3 +1,7 @@
2014-12-30 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/ipa/inline-7.c: New testcase.
2014-12-29 Janus Weil <janus@gcc.gnu.org>
PR fortran/60357

View File

@ -0,0 +1,25 @@
/* Check that early inliner works out that a is empty of parameter 0. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-einline -fno-partial-inlining" } */
void t(void);
int a (int b)
{
if (!b)
{
t();
t();
t();
t();
t();
t();
t();
}
}
void
m()
{
a(1);
a(0);
}
/* { dg-final { scan-tree-dump-times "Inlining a into m" 1 "einline" } } */
/* { dg-final { cleanup-tree-dump "einline" } } */