From 09411461d2e1d7dfcc3aed713bddc68e34ba223d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 8 Jul 2010 18:46:49 +0200 Subject: [PATCH] cgraph.c (cgraph_will_be_removed_from_program_if_no_direct_calls): New function. * cgraph.c (cgraph_will_be_removed_from_program_if_no_direct_calls): New function. * cgraph.h (cgraph_will_be_removed_from_program_if_no_direct_calls): Declare. * ipa-cp.c (ipcp_estimate_growth): Use it. * ipa-inline.c (cgraph_estimate_growth, cgraph_decide_inlining): Likewise. From-SVN: r161966 --- gcc/ChangeLog | 10 ++++++++++ gcc/cgraph.c | 25 +++++++++++++++++++++++++ gcc/cgraph.h | 2 ++ gcc/ipa-cp.c | 5 +++-- gcc/ipa-inline.c | 7 +++---- 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7a6e177566..8d5962d2500 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2010-07-08 Jan Hubicka + + * cgraph.c (cgraph_will_be_removed_from_program_if_no_direct_calls): + New function. + * cgraph.h (cgraph_will_be_removed_from_program_if_no_direct_calls): + Declare. + * ipa-cp.c (ipcp_estimate_growth): Use it. + * ipa-inline.c (cgraph_estimate_growth, cgraph_decide_inlining): + Likewise. + 2010-07-08 Jan Hubicka * tree-inline.c (declare_return_variable): Allocate annotation for new diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 33653df1549..fff437a6265 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2651,4 +2651,29 @@ cgraph_edge_cannot_lead_to_return (struct cgraph_edge *e) return cgraph_node_cannot_return (e->callee); } +/* Return true when function NODE can be excpected to be removed + from program when direct calls in this compilation unit are removed. + + As a special case COMDAT functions are + cgraph_can_remove_if_no_direct_calls_p while the are not + cgraph_only_called_directly_p (it is possible they are called from other + unit) + + This function behaves as cgraph_only_called_directly_p because eliminating + all uses of COMDAT function does not make it neccesarily 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 +cgraph_will_be_removed_from_program_if_no_direct_calls (struct cgraph_node *node) +{ + if (node->local.used_from_object_file) + return false; + if (!in_lto_p && !flag_whole_program) + return cgraph_only_called_directly_p (node); + else + return cgraph_can_remove_if_no_direct_calls_p (node); +} + #include "gt-cgraph.h" diff --git a/gcc/cgraph.h b/gcc/cgraph.h index bbce3d8ef03..2dcdf2f22f3 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -664,6 +664,8 @@ void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *); void cgraph_materialize_all_clones (void); gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *); bool cgraph_propagate_frequency (struct cgraph_node *node); +bool cgraph_will_be_removed_from_program_if_no_direct_calls + (struct cgraph_node *node); /* In cgraphbuild.c */ unsigned int rebuild_cgraph_edges (void); void cgraph_rebuild_references (void); diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 8f9937320a1..be1956962a8 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -951,7 +951,8 @@ ipcp_estimate_growth (struct cgraph_node *node) struct cgraph_edge *cs; int redirectable_node_callers = 0; int removable_args = 0; - bool need_original = !cgraph_only_called_directly_p (node); + bool need_original + = !cgraph_will_be_removed_from_program_if_no_direct_calls (node); struct ipa_node_params *info; int i, count; int growth; @@ -1134,7 +1135,7 @@ ipcp_insert_stage (void) for (cs = node->callers; cs != NULL; cs = cs->next_caller) if (cs->caller == node || ipcp_need_redirect_p (cs)) break; - if (!cs && cgraph_only_called_directly_p (node)) + if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node)) bitmap_set_bit (dead_nodes, node->uid); info = IPA_NODE_REF (node); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 201e04af277..e65c6968ab4 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -389,7 +389,7 @@ cgraph_estimate_growth (struct cgraph_node *node) we decide to not inline for different reasons, but it is not big deal as in that case we will keep the body around, but we will also avoid some inlining. */ - if (cgraph_only_called_directly_p (node) + if (cgraph_will_be_removed_from_program_if_no_direct_calls (node) && !DECL_EXTERNAL (node->decl) && !self_recursive) growth -= node->global.size; @@ -1496,14 +1496,13 @@ cgraph_decide_inlining (void) if (node->callers && !node->callers->next_caller - && cgraph_only_called_directly_p (node) + && cgraph_will_be_removed_from_program_if_no_direct_calls (node) && node->local.inlinable && node->callers->inline_failed && node->callers->caller != node && node->callers->caller->global.inlined_to != node && !node->callers->call_stmt_cannot_inline_p - && !DECL_EXTERNAL (node->decl) - && !DECL_COMDAT (node->decl)) + && !DECL_EXTERNAL (node->decl)) { cgraph_inline_failed_t reason; old_size = overall_size; -- 2.30.2