diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-12-30 11:36:00 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-12-30 11:36:00 +0000 |
commit | f4e523eb26d44966eeaa6fa8b6aeb1c37fa0bf51 (patch) | |
tree | 7ff78c50ac4ee43a35521dc67f161dfcffa3b4e3 /gcc/ipa-inline-analysis.c | |
parent | 374658e5b117c80cd22317f58b71a0fa8800bd3d (diff) | |
download | gcc-f4e523eb26d44966eeaa6fa8b6aeb1c37fa0bf51.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219108 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 61 |
1 files changed, 55 insertions, 6 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 7da373ec3b6..5cc0a2500ee 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -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); |