cgraph.c (cgraph_will_be_removed_from_program_if_no_direct_calls): New function.
authorJan Hubicka <jh@suse.cz>
Thu, 8 Jul 2010 16:46:49 +0000 (18:46 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 8 Jul 2010 16:46:49 +0000 (16:46 +0000)
* 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
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-cp.c
gcc/ipa-inline.c

index c7a6e17..8d5962d 100644 (file)
@@ -1,5 +1,15 @@
 2010-07-08  Jan Hubicka  <jh@suse.cz>
 
+       * 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  <jh@suse.cz>
+
        * tree-inline.c (declare_return_variable): Allocate annotation for new
        temporary.
 
index 33653df..fff437a 100644 (file)
@@ -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"
index bbce3d8..2dcdf2f 100644 (file)
@@ -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);
index 8f99373..be19569 100644 (file)
@@ -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);
index 201e04a..e65c696 100644 (file)
@@ -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;