diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-10 11:43:01 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-10 11:43:01 +0000 |
commit | 82626cb06c7b17265e44329c4adc0876fd6cc043 (patch) | |
tree | 1d26feeab584ee3df009ef00a986f63acea4c6bd /gcc/ipa-inline-transform.c | |
parent | a7107e583f0557e7573105c28a7a35921d7c51c5 (diff) | |
download | gcc-82626cb06c7b17265e44329c4adc0876fd6cc043.tar.gz |
* ipa-inline-transform.c (can_remove_node_now_p): Move out of...
(clone_inlined_nodes): ... here.
(inline_call): Use cgraph_function_or_thunk_node; redirect edge
to real destination prior inlining.
* ipa-inline.c (caller_growth_limits, can_inline_edge_p,
can_early_inline_edge_p, want_early_inline_function_p,
want_early_inline_function_p, want_inline_small_function_p,
want_inline_self_recursive_call_p, want_inline_function_called_once_p,
edge_badness, update_all_callee_keys, lookup_recursive_calls,
add_new_edges_to_heap, inline_small_functions, flatten_function,
inline_always_inline_functions, early_inline_small_functions): Use
cgraph_function_or_thunk_node.
* ipa-inline-analysis.c (evaluate_conditions_for_edge,
dump_inline_edge_summary, estimate_function_body_sizes): Likewise.
(do_estimate_edge_growth_1): Break out from ...
(do_estimate_growth) ... here; walk aliases.
(inline_generate_summary): Skip aliases.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@174901 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-transform.c')
-rw-r--r-- | gcc/ipa-inline-transform.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 85a47f8a018..c5f32a34b76 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -76,6 +76,35 @@ update_noncloned_frequencies (struct cgraph_node *node, } } +/* We removed or are going to remove the last call to NODE. + Return true if we can and want proactively remove the NODE now. + This is important to do, since we want inliner to know when offline + copy of function was removed. */ + +static bool +can_remove_node_now_p (struct cgraph_node *node) +{ + /* FIXME: When address is taken of DECL_EXTERNAL function we still + can remove its offline copy, but we would need to keep unanalyzed node in + the callgraph so references can point to it. */ + return (!node->address_taken + && cgraph_can_remove_if_no_direct_calls_p (node) + /* Inlining might enable more devirtualizing, so we want to remove + those only after all devirtualizable virtual calls are processed. + Lacking may edges in callgraph we just preserve them post + inlining. */ + && (!DECL_VIRTUAL_P (node->decl) + || (!DECL_COMDAT (node->decl) + && !DECL_EXTERNAL (node->decl))) + /* Don't reuse if more than one function shares a comdat group. + If the other function(s) are needed, we need to emit even + this function out of line. */ + && !node->same_comdat_group + /* During early inlining some unanalyzed cgraph nodes might be in the + callgraph and they might reffer the function in question. */ + && !cgraph_new_nodes); +} + /* E is expected to be an edge being inlined. Clone destination node of the edge and redirect it to the new clone. @@ -97,25 +126,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, /* Recursive inlining never wants the master clone to be overwritten. */ && update_original - /* FIXME: When address is taken of DECL_EXTERNAL function we still - can remove its offline copy, but we would need to keep unanalyzed - node in the callgraph so references can point to it. */ - && !e->callee->address_taken - && cgraph_can_remove_if_no_direct_calls_p (e->callee) - /* Inlining might enable more devirtualizing, so we want to remove - those only after all devirtualizable virtual calls are processed. - Lacking may edges in callgraph we just preserve them post - inlining. */ - && (!DECL_VIRTUAL_P (e->callee->decl) - || (!DECL_COMDAT (e->callee->decl) - && !DECL_EXTERNAL (e->callee->decl))) - /* Don't reuse if more than one function shares a comdat group. - If the other function(s) are needed, we need to emit even - this function out of line. */ - && !e->callee->same_comdat_group - /* During early inlining some unanalyzed cgraph nodes might be in the - callgraph and they might reffer the function in question. */ - && !cgraph_new_nodes) + && can_remove_node_now_p (e->callee)) { gcc_assert (!e->callee->global.inlined_to); if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->decl)) @@ -164,19 +175,25 @@ inline_call (struct cgraph_edge *e, bool update_original, int old_size = 0, new_size = 0; struct cgraph_node *to = NULL; struct cgraph_edge *curr = e; + struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL); /* Don't inline inlined edges. */ gcc_assert (e->inline_failed); /* Don't even think of inlining inline clone. */ - gcc_assert (!e->callee->global.inlined_to); + gcc_assert (!callee->global.inlined_to); e->inline_failed = CIF_OK; - DECL_POSSIBLY_INLINED (e->callee->decl) = true; + DECL_POSSIBLY_INLINED (callee->decl) = true; to = e->caller; if (to->global.inlined_to) to = to->global.inlined_to; + /* If aliases are involved, redirect edge to the actual destination and + possibly remove the aliases. */ + if (e->callee != callee) + cgraph_redirect_edge_callee (e, callee); + clone_inlined_nodes (e, true, update_original, overall_size); gcc_assert (curr->callee->global.inlined_to == to); |