Commit 6c69a029 by Jan Hubicka Committed by Jan Hubicka

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
parent 32dccc18
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
......
......@@ -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);
......
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