aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2011-04-17 16:22:20 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2011-04-17 14:22:20 +0000
commit4c0f767939eb659b721f9222cf7bdacd0194310b (patch)
tree437b0b8c6f18f8d396674a0c5a7fe26c430fa602 /gcc/ipa-inline-analysis.c
parent51c5169c60be01c229b8637d11283d843bc6e126 (diff)
downloadgcc-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.c64
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);
}
}