ipa-inline-transform.c (+can_remove_node_now_p_1): Break out from...

* ipa-inline-transform.c (+can_remove_node_now_p_1): Break out from...
	(can_remove_node_now_p): ... here; handle same comdat groups.
	(clone_inlined_nodes): Update use of can_remove_node_now_p add TODO.
	(inline_call): Update use of can_remove_node_now_p.

From-SVN: r174989
This commit is contained in:
Jan Hubicka 2011-06-13 15:12:23 +02:00 committed by Jan Hubicka
parent 32dccc18a1
commit 6c69a0297a
2 changed files with 40 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2011-06-13 Jan Hubicka <jh@suse.cz>
* ipa-inline-transform.c (+can_remove_node_now_p_1): Break out from...
(can_remove_node_now_p): ... here; handle same comdat groups.
(clone_inlined_nodes): Update use of can_remove_node_now_p add TODO.
(inline_call): Update use of can_remove_node_now_p.
2011-06-13 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
* config/h8300/h8300.md (bsetqi_msx, bclrqi_msx, bnotqi_msx): Added

View File

@ -83,7 +83,7 @@ update_noncloned_frequencies (struct cgraph_node *node,
copy of function was removed. */
static bool
can_remove_node_now_p (struct cgraph_node *node)
can_remove_node_now_p_1 (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
@ -98,15 +98,34 @@ can_remove_node_now_p (struct cgraph_node *node)
&& (!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);
}
/* We are going to eliminate last direct call to NODE (or alias of it) via edge E.
Verify that the NODE can be removed from unit and if it is contained in comdat
group that the whole comdat group is removable. */
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))
return false;
/* When we see same comdat group, we need to be sure that all
items can be removed. */
if (!node->same_comdat_group)
return true;
for (next = node->same_comdat_group;
next != node; next = next->same_comdat_group)
if (node->callers && node->callers != e
&& !can_remove_node_now_p_1 (node))
return false;
return true;
}
/* E is expected to be an edge being inlined. Clone destination node of
the edge and redirect it to the new clone.
@ -128,8 +147,15 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
/* Recursive inlining never wants the master clone to
be overwritten. */
&& update_original
&& can_remove_node_now_p (e->callee))
&& can_remove_node_now_p (e->callee, e))
{
/* TODO: When callee is in a comdat group, we could remove all of it,
including all inline clones inlined into it. That would however
need small function inlining to register edge removal hook to
maintain the priority queue.
For now we keep the ohter functions in the group in program until
cgraph_remove_unreachable_functions gets rid of them. */
gcc_assert (!e->callee->global.inlined_to);
if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->decl))
{
@ -200,7 +226,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
while (alias && alias != callee)
{
if (!alias->callers
&& can_remove_node_now_p (alias))
&& can_remove_node_now_p (alias, e))
{
next_alias = cgraph_alias_aliased_node (alias);
cgraph_remove_node (alias);