diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-09 04:53:54 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-09 04:53:54 +0000 |
commit | b12b920e1e57309423ba7563820dcf4501297512 (patch) | |
tree | 4d0fa49deb182f96c355f84d405543db33394f5d /gcc/cgraph.c | |
parent | 4b8069b91bda2547201d4e26a74f88fa0fa09587 (diff) | |
download | gcc-b12b920e1e57309423ba7563820dcf4501297512.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221277 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r-- | gcc/cgraph.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c index b2109bd5172..e4d5505d697 100644 --- a/gcc/cgraph.c +++ b/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); } |