diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-11-24 17:15:46 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-11-24 16:15:46 +0000 |
commit | d142079af3ebd7e1d940a87c251d16bd794e8f78 (patch) | |
tree | 43174ebb8202281dbb77d8e7f7ce4901d574c71a /gcc/ipa-inline-transform.c | |
parent | 3f2012e4950247046107f0576259660fab1203bd (diff) | |
download | gcc-d142079af3ebd7e1d940a87c251d16bd794e8f78.zip gcc-d142079af3ebd7e1d940a87c251d16bd794e8f78.tar.gz gcc-d142079af3ebd7e1d940a87c251d16bd794e8f78.tar.bz2 |
re PR ipa/63671 (21% tramp3d-v4 performance hit due to -fdevirtualize)
PR ipa/63671
* ipa-inline-transform.c (can_remove_node_now_p_1): Handle alises
and -fno-devirtualize more carefully.
(can_remove_node_now_p): Update.
From-SVN: r218024
Diffstat (limited to 'gcc/ipa-inline-transform.c')
-rw-r--r-- | gcc/ipa-inline-transform.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index a64e4dd..063cd94 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -93,19 +93,28 @@ update_noncloned_frequencies (struct cgraph_node *node, copy of function was removed. */ static bool -can_remove_node_now_p_1 (struct cgraph_node *node) +can_remove_node_now_p_1 (struct cgraph_node *node, struct cgraph_edge *e) { + ipa_ref *ref; + + FOR_EACH_ALIAS (node, ref) + { + cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring); + if ((alias->callers && alias->callers != e) + || !can_remove_node_now_p_1 (alias, e)) + return false; + } /* 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 - && !node->has_aliases_p () && node->can_remove_if_no_direct_calls_p () /* 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_VIRTUAL_P (node->decl) + || !opt_for_fn (node->decl, flag_devirtualize)) /* During early inlining some unanalyzed cgraph nodes might be in the callgraph and they might reffer the function in question. */ && !cgraph_new_nodes.exists ()); @@ -119,7 +128,7 @@ static bool can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e) { struct cgraph_node *next; - if (!can_remove_node_now_p_1 (node)) + if (!can_remove_node_now_p_1 (node, e)) return false; /* When we see same comdat group, we need to be sure that all @@ -128,9 +137,13 @@ can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e) return true; for (next = dyn_cast<cgraph_node *> (node->same_comdat_group); next != node; next = dyn_cast<cgraph_node *> (next->same_comdat_group)) - if ((next->callers && next->callers != e) - || !can_remove_node_now_p_1 (next)) - return false; + { + if (next->alias) + continue; + if ((next->callers && next->callers != e) + || !can_remove_node_now_p_1 (next, e)) + return false; + } return true; } |