diff options
author | Jan Hubicka <jh@suse.cz> | 2011-04-17 16:22:20 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2011-04-17 14:22:20 +0000 |
commit | 4c0f767939eb659b721f9222cf7bdacd0194310b (patch) | |
tree | 437b0b8c6f18f8d396674a0c5a7fe26c430fa602 /gcc/ipa-inline-analysis.c | |
parent | 51c5169c60be01c229b8637d11283d843bc6e126 (diff) | |
download | gcc-4c0f767939eb659b721f9222cf7bdacd0194310b.zip gcc-4c0f767939eb659b721f9222cf7bdacd0194310b.tar.gz gcc-4c0f767939eb659b721f9222cf7bdacd0194310b.tar.bz2 |
lto-symtab.c (lto_cgraph_replace_node): When call statement is present, also set gimple_call_set_cannot_inline.
* lto-symtab.c (lto_cgraph_replace_node): When call statement is
present, also set gimple_call_set_cannot_inline.
* ipa-inline.c: Update toplevel comment.
(MAX_TIME): Remove.
(cgraph_clone_inlined_nodes): Fix linebreaks.
(cgraph_check_inline_limits): Restructure to ...
(caller_growth_limits): ... this one; be more tolerant
on growth in nested inline chains; add explanatory comment;
fix stack accounting thinko introduced by previous patch.
(cgraph_default_inline_p): Remove.
(report_inline_failed_reason): New function.
(can_inline_edge_p): New function.
(can_early_inline_edge_p): New function.
(leaf_node_p): Move upwards in file.
(want_early_inline_function_p): New function.
(want_inline_small_function_p): New function.
(want_inline_self_recursive_call_p): New function.
(cgraph_edge_badness): Rename to ...
(edge_badness) ... this one; fix linebreaks.
(update_edge_key): Update call of edge_baddness; add
detailed dump about queue updates.
(update_caller_keys): Use can_inline_edge_p and
want_inline_small_function_p.
(cgraph_decide_recursive_inlining): Rename to...
(recursive_inlining): Use can_inline_edge_p and
want_inline_self_recursive_call_p; simplify and
remove no longer valid FIXME.
(cgraph_set_inline_failed): Remove.
(add_new_edges_to_heap): Use can_inline_edge_p and
want_inline_small_function_p.
(cgraph_decide_inlining_of_small_functions): Rename to ...
(inline_small_functions): ... this one; cleanup; use
can/want predicates; cleanup debug ouput; work edges
till fibheap is exhausted and do not stop once unit
growth is reached; remove later loop processing remaining
edges.
(cgraph_flatten): Rename to ...
(flatten_function): ... this one; use can_inline_edge_p
and can_early_inline_edge_p predicates.
(cgraph_decide_inlining): Rename to ...
(ipa_inline): ... this one; remove unreachable nodes before
inlining functions called once; simplify the pass.
(cgraph_perform_always_inlining): Rename to ...
(inline_always_inline_functions): ... this one; use
DECL_DISREGARD_INLINE_LIMITS; use can_inline_edge_p
predicate
(cgraph_decide_inlining_incrementally): Rename to ...
(early_inline_small_functions): ... this one; simplify
using new predicates; cleanup; make dumps prettier.
(cgraph_early_inlining): Rename to ...
(early_inliner): newer inline regular functions into always-inlines;
fix updating of call stmt summaries.
(pass_early_inline): Update for new names.
(inline_transform): Fix formating.
(gate_cgraph_decide_inlining): Rename to ...
(pass_ipa_inline): ... this one.
* ipa-inline.h (inline_summary): Remove disregard_inline_limits.
* ipa-inline-analysis.c (dump_inline_summary): Update.
(compute_inline_parameters): Do not compute disregard_inline_limits;
look for mismatching arguments.
(estimate_growth): Fix handlig of non-trivial self recursion.
(inline_read_summary): Do not read info->disregard_inline_limits.
(inline_write_summary): Do not write info->disregard_inline_limits.
* tree-inline.c (inline_forbidden_into_p, tree_can_inline_p): Remove and
move all checks into can_inline_edge_p predicate; re-enable code comparing
optimization levels.
(expand_call_inline): Do not test inline_forbidden_into_p.
* Makefile.in (ipa-inline.o): Update arguments.
* gcc.dg/winline-5.c: Update testcase.
From-SVN: r172609
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index c225778..30fbcbc 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -131,7 +131,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node) struct inline_summary *s = inline_summary (node); fprintf (f, "Inline summary for %s/%i", cgraph_node_name (node), node->uid); - if (s->disregard_inline_limits) + if (DECL_DISREGARD_INLINE_LIMITS (node->decl)) fprintf (f, " always_inline"); if (s->inlinable) fprintf (f, " inlinable"); @@ -142,7 +142,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node) fprintf (f, " global time: %i\n", s->time); fprintf (f, " self size: %i, benefit: %i\n", s->self_size, s->size_inlining_benefit); - fprintf (f, " global size: %i", s->size); + fprintf (f, " global size: %i\n", s->size); fprintf (f, " self stack: %i\n", (int)s->estimated_self_stack_size); fprintf (f, " global stack: %i\n\n", @@ -303,6 +303,17 @@ estimate_function_body_sizes (struct cgraph_node *node) struct cgraph_edge *edge = cgraph_edge (node, stmt); edge->call_stmt_size = this_size; edge->call_stmt_time = this_time; + + /* Do not inline calls where we cannot triviall work around mismatches + in argument or return types. */ + if (edge->callee + && !gimple_check_call_matching_types (stmt, edge->callee->decl)) + { + edge->call_stmt_cannot_inline_p = true; + gimple_call_set_cannot_inline (stmt, true); + } + else + gcc_assert (!gimple_call_cannot_inline_p (stmt)); } this_time *= freq; @@ -364,8 +375,6 @@ compute_inline_parameters (struct cgraph_node *node) /* Can this function be inlined at all? */ info->inlinable = tree_inlinable_function_p (node->decl); - if (!info->inlinable) - info->disregard_inline_limits = 0; /* Inlinable functions always can change signature. */ if (info->inlinable) @@ -388,8 +397,6 @@ compute_inline_parameters (struct cgraph_node *node) info->estimated_growth = INT_MIN; info->stack_frame_offset = 0; info->estimated_stack_size = info->estimated_self_stack_size; - info->disregard_inline_limits - = DECL_DISREGARD_INLINE_LIMITS (node->decl); } @@ -483,25 +490,34 @@ estimate_growth (struct cgraph_node *node) for (e = node->callers; e; e = e->next_caller) { - if (e->caller == node) + gcc_checking_assert (e->inline_failed); + + if (e->caller == node + || (e->caller->global.inlined_to + && e->caller->global.inlined_to == node)) self_recursive = true; - if (e->inline_failed) - growth += estimate_edge_growth (e); + growth += estimate_edge_growth (e); + } + + + /* For self recursive functions the growth estimation really should be + infinity. We don't want to return very large values because the growth + plays various roles in badness computation fractions. Be sure to not + return zero or negative growths. */ + if (self_recursive) + growth = growth < info->size ? info->size : growth; + else + { + if (cgraph_will_be_removed_from_program_if_no_direct_calls (node) + && !DECL_EXTERNAL (node->decl)) + growth -= info->size; + /* COMDAT functions are very often not shared across multiple units since they + come from various template instantiations. Take this into account. */ + else if (DECL_COMDAT (node->decl) + && cgraph_can_remove_if_no_direct_calls_p (node)) + growth -= (info->size + * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY)) + 50) / 100; } - - /* ??? Wrong for non-trivially self recursive functions or cases where - we decide to not inline for different reasons, but it is not big deal - as in that case we will keep the body around, but we will also avoid - some inlining. */ - if (cgraph_will_be_removed_from_program_if_no_direct_calls (node) - && !DECL_EXTERNAL (node->decl) && !self_recursive) - growth -= info->size; - /* COMDAT functions are very often not shared across multiple units since they - come from various template instantiations. Take this into account. */ - else if (DECL_COMDAT (node->decl) && !self_recursive - && cgraph_can_remove_if_no_direct_calls_p (node)) - growth -= (info->size - * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY)) + 50) / 100; info->estimated_growth = growth; return growth; @@ -621,7 +637,6 @@ inline_read_summary (void) bp = lto_input_bitpack (ib); info->inlinable = bp_unpack_value (&bp, 1); info->versionable = bp_unpack_value (&bp, 1); - info->disregard_inline_limits = bp_unpack_value (&bp, 1); } lto_destroy_simple_input_block (file_data, @@ -688,7 +703,6 @@ inline_write_summary (cgraph_node_set set, bp = bitpack_create (ob->main_stream); bp_pack_value (&bp, info->inlinable, 1); bp_pack_value (&bp, info->versionable, 1); - bp_pack_value (&bp, info->disregard_inline_limits, 1); lto_output_bitpack (&bp); } } |