Commit d142079a by Jan Hubicka Committed by Jan Hubicka

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
parent 3f2012e4
2014-11-22 Jan Hubicka <hubicka@ucw.cz>
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.
2014-11-24 Andrew Pinski <apinski@cavium.com> 2014-11-24 Andrew Pinski <apinski@cavium.com>
PR rtl-opt/63972 PR rtl-opt/63972
...@@ -93,19 +93,28 @@ update_noncloned_frequencies (struct cgraph_node *node, ...@@ -93,19 +93,28 @@ update_noncloned_frequencies (struct cgraph_node *node,
copy of function was removed. */ copy of function was removed. */
static bool 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 /* 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 can remove its offline copy, but we would need to keep unanalyzed node in
the callgraph so references can point to it. */ the callgraph so references can point to it. */
return (!node->address_taken return (!node->address_taken
&& !node->has_aliases_p ()
&& node->can_remove_if_no_direct_calls_p () && node->can_remove_if_no_direct_calls_p ()
/* Inlining might enable more devirtualizing, so we want to remove /* Inlining might enable more devirtualizing, so we want to remove
those only after all devirtualizable virtual calls are processed. those only after all devirtualizable virtual calls are processed.
Lacking may edges in callgraph we just preserve them post Lacking may edges in callgraph we just preserve them post
inlining. */ 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 /* During early inlining some unanalyzed cgraph nodes might be in the
callgraph and they might reffer the function in question. */ callgraph and they might reffer the function in question. */
&& !cgraph_new_nodes.exists ()); && !cgraph_new_nodes.exists ());
...@@ -119,7 +128,7 @@ static bool ...@@ -119,7 +128,7 @@ static bool
can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e) can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e)
{ {
struct cgraph_node *next; struct cgraph_node *next;
if (!can_remove_node_now_p_1 (node)) if (!can_remove_node_now_p_1 (node, e))
return false; return false;
/* When we see same comdat group, we need to be sure that all /* 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) ...@@ -128,9 +137,13 @@ can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e)
return true; return true;
for (next = dyn_cast<cgraph_node *> (node->same_comdat_group); for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
next != node; next = dyn_cast<cgraph_node *> (next->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)) if (next->alias)
return false; continue;
if ((next->callers && next->callers != e)
|| !can_remove_node_now_p_1 (next, e))
return false;
}
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment