ipa-inline-analysis.c (check_callers): Check node->can_remove_if_no_direct_calls_and_refs_p.
* ipa-inline-analysis.c (check_callers): Check node->can_remove_if_no_direct_calls_and_refs_p. (growth_likely_positive): Reorganize to call can_remove_if_no_direct_calls_p later. * cgraph.h (will_be_removed_from_program_if_no_direct_calls_p, will_be_removed_from_program_if_no_direct_calls_p): Add will_inline parameter. * cgraph.c (cgraph_node::can_remove_if_no_direct_calls_p, cgraph_node::will_be_removed_from_program_if_no_direct_calls_p): Handle inliner case correctly. From-SVN: r221277
This commit is contained in:
parent
68ca4ac90b
commit
e0d514da7b
4 changed files with 68 additions and 32 deletions
|
@ -1,3 +1,16 @@
|
|||
2015-03-08 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* ipa-inline-analysis.c (check_callers): Check
|
||||
node->can_remove_if_no_direct_calls_and_refs_p.
|
||||
(growth_likely_positive): Reorganize to call
|
||||
can_remove_if_no_direct_calls_p later.
|
||||
* cgraph.h (will_be_removed_from_program_if_no_direct_calls_p,
|
||||
will_be_removed_from_program_if_no_direct_calls_p): Add
|
||||
will_inline parameter.
|
||||
* cgraph.c (cgraph_node::can_remove_if_no_direct_calls_p,
|
||||
cgraph_node::will_be_removed_from_program_if_no_direct_calls_p):
|
||||
Handle inliner case correctly.
|
||||
|
||||
2015-03-09 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
PR tree-optimization/63743
|
||||
|
|
33
gcc/cgraph.c
33
gcc/cgraph.c
|
@ -2415,7 +2415,7 @@ nonremovable_p (cgraph_node *node, void *)
|
|||
calls to THIS. */
|
||||
|
||||
bool
|
||||
cgraph_node::can_remove_if_no_direct_calls_p (void)
|
||||
cgraph_node::can_remove_if_no_direct_calls_p (bool will_inline)
|
||||
{
|
||||
struct ipa_ref *ref;
|
||||
|
||||
|
@ -2430,6 +2430,9 @@ cgraph_node::can_remove_if_no_direct_calls_p (void)
|
|||
return !call_for_symbol_and_aliases (nonremovable_p, NULL, true);
|
||||
}
|
||||
|
||||
if (will_inline && address_taken)
|
||||
return false;
|
||||
|
||||
/* Otheriwse check if we can remove the symbol itself and then verify
|
||||
that only uses of the comdat groups are direct call to THIS
|
||||
or its aliases. */
|
||||
|
@ -2454,12 +2457,16 @@ cgraph_node::can_remove_if_no_direct_calls_p (void)
|
|||
/* If we see different symbol than THIS, be sure to check calls. */
|
||||
if (next->ultimate_alias_target () != target)
|
||||
for (cgraph_edge *e = next->callers; e; e = e->next_caller)
|
||||
if (e->caller->get_comdat_group () != get_comdat_group ())
|
||||
if (e->caller->get_comdat_group () != get_comdat_group ()
|
||||
|| will_inline)
|
||||
return false;
|
||||
|
||||
for (int i = 0; next->iterate_referring (i, ref); i++)
|
||||
if (ref->referring->get_comdat_group () != get_comdat_group ())
|
||||
return false;
|
||||
/* If function is not being inlined, we care only about
|
||||
references outside of the comdat group. */
|
||||
if (!will_inline)
|
||||
for (int i = 0; next->iterate_referring (i, ref); i++)
|
||||
if (ref->referring->get_comdat_group () != get_comdat_group ())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2479,9 +2486,9 @@ cgraph_node::can_remove_if_no_direct_calls_p (void)
|
|||
linkonce section. */
|
||||
|
||||
bool
|
||||
cgraph_node::will_be_removed_from_program_if_no_direct_calls_p (void)
|
||||
cgraph_node::will_be_removed_from_program_if_no_direct_calls_p
|
||||
(bool will_inline)
|
||||
{
|
||||
struct ipa_ref *ref;
|
||||
gcc_assert (!global.inlined_to);
|
||||
if (DECL_EXTERNAL (decl))
|
||||
return true;
|
||||
|
@ -2496,6 +2503,9 @@ cgraph_node::will_be_removed_from_program_if_no_direct_calls_p (void)
|
|||
if (same_comdat_group && externally_visible)
|
||||
{
|
||||
struct cgraph_node *target = ultimate_alias_target ();
|
||||
|
||||
if (will_inline && address_taken)
|
||||
return true;
|
||||
for (cgraph_node *next = dyn_cast<cgraph_node *> (same_comdat_group);
|
||||
next != this;
|
||||
next = dyn_cast<cgraph_node *> (next->same_comdat_group))
|
||||
|
@ -2510,18 +2520,15 @@ cgraph_node::will_be_removed_from_program_if_no_direct_calls_p (void)
|
|||
be sure to check calls. */
|
||||
if (next->ultimate_alias_target () != target)
|
||||
for (cgraph_edge *e = next->callers; e; e = e->next_caller)
|
||||
if (e->caller->get_comdat_group () != get_comdat_group ())
|
||||
if (e->caller->get_comdat_group () != get_comdat_group ()
|
||||
|| will_inline)
|
||||
return false;
|
||||
|
||||
for (int i = 0; next->iterate_referring (i, ref); i++)
|
||||
if (ref->referring->get_comdat_group () != get_comdat_group ())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return can_remove_if_no_direct_calls_p ();
|
||||
return can_remove_if_no_direct_calls_p (will_inline);
|
||||
}
|
||||
|
||||
|
||||
|
|
17
gcc/cgraph.h
17
gcc/cgraph.h
|
@ -1110,16 +1110,23 @@ public:
|
|||
all uses of COMDAT function does not make it necessarily disappear from
|
||||
the program unless we are compiling whole program or we do LTO. In this
|
||||
case we know we win since dynamic linking will not really discard the
|
||||
linkonce section. */
|
||||
bool will_be_removed_from_program_if_no_direct_calls_p (void);
|
||||
linkonce section.
|
||||
|
||||
If WILL_INLINE is true, assume that function will be inlined into all the
|
||||
direct calls. */
|
||||
bool will_be_removed_from_program_if_no_direct_calls_p
|
||||
(bool will_inline = false);
|
||||
|
||||
/* Return true when function can be removed from callgraph
|
||||
if all direct calls are eliminated. */
|
||||
if all direct calls and references are eliminated. The function does
|
||||
not take into account comdat groups. */
|
||||
bool can_remove_if_no_direct_calls_and_refs_p (void);
|
||||
|
||||
/* Return true when function cgraph_node and its aliases can be removed from
|
||||
callgraph if all direct calls are eliminated. */
|
||||
bool can_remove_if_no_direct_calls_p (void);
|
||||
callgraph if all direct calls are eliminated.
|
||||
If WILL_INLINE is true, assume that function will be inlined into all the
|
||||
direct calls. */
|
||||
bool can_remove_if_no_direct_calls_p (bool will_inline = false);
|
||||
|
||||
/* Return true when callgraph node is a function with Gimple body defined
|
||||
in current unit. Functions can also be define externally or they
|
||||
|
|
|
@ -3978,6 +3978,9 @@ check_callers (cgraph_node *node, int *max_callers)
|
|||
{
|
||||
ipa_ref *ref;
|
||||
|
||||
if (!node->can_remove_if_no_direct_calls_and_refs_p ())
|
||||
return true;
|
||||
|
||||
for (cgraph_edge *e = node->callers; e; e = e->next_caller)
|
||||
{
|
||||
(*max_callers)--;
|
||||
|
@ -4007,8 +4010,28 @@ growth_likely_positive (struct cgraph_node *node,
|
|||
struct cgraph_edge *e;
|
||||
gcc_checking_assert (edge_growth > 0);
|
||||
|
||||
/* First quickly check if NODE is removable at all. */
|
||||
if (DECL_EXTERNAL (node->decl))
|
||||
return true;
|
||||
if (!node->can_remove_if_no_direct_calls_and_refs_p ()
|
||||
|| node->address_taken)
|
||||
return true;
|
||||
|
||||
max_callers = inline_summaries->get (node)->size * 4 / edge_growth + 2;
|
||||
|
||||
for (e = node->callers; e; e = e->next_caller)
|
||||
{
|
||||
max_callers--;
|
||||
if (!max_callers
|
||||
|| cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
|
||||
return true;
|
||||
}
|
||||
|
||||
ipa_ref *ref;
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
if (check_callers (dyn_cast <cgraph_node *> (ref->referring), &max_callers))
|
||||
return true;
|
||||
|
||||
/* Unlike for functions called once, we play unsafe with
|
||||
COMDATs. We can allow that since we know functions
|
||||
in consideration are small (and thus risk is small) and
|
||||
|
@ -4024,20 +4047,6 @@ growth_likely_positive (struct cgraph_node *node,
|
|||
}
|
||||
else if (!node->will_be_removed_from_program_if_no_direct_calls_p ())
|
||||
return true;
|
||||
max_callers = inline_summaries->get (node)->size * 4 / edge_growth + 2;
|
||||
|
||||
for (e = node->callers; e; e = e->next_caller)
|
||||
{
|
||||
max_callers--;
|
||||
if (!max_callers
|
||||
|| cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
|
||||
return true;
|
||||
}
|
||||
|
||||
ipa_ref *ref;
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
if (check_callers (dyn_cast <cgraph_node *> (ref->referring), &max_callers))
|
||||
return true;
|
||||
|
||||
return estimate_growth (node) > 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue