ipa-inline-analysis.c (check_callers): Check node->can_remove_if_no_direct_calls_and_...
authorJan Hubicka <hubicka@ucw.cz>
Mon, 9 Mar 2015 04:53:54 +0000 (05:53 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 9 Mar 2015 04:53:54 +0000 (04:53 +0000)
* 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

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-inline-analysis.c

index 07430ae567a1ef5e90eb25909a04f451a2661889..62b299f0d00fe6e9eaf1eb76c8e6ac27fc969bb7 100644 (file)
@@ -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
index b2109bd5172abfda49593da6a8739550e9292fe9..e4d5505d697a57b5862c8172be5eafcc9626eeb8 100644 (file)
@@ -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);
 }
 
 
index dcf383bf35adba6f6e0d2dca957df1ab8cc1dbab..2b96b6bcd06c94e5c9fbc4b153e84c61871cdc3a 100644 (file)
@@ -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
index d74716306170fc91dbe290edf6a1761ccbc15869..5707f6c9603ea021ac8871eb4e7ace7420489de9 100644 (file)
@@ -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,23 +4010,13 @@ 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;
-  /* 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
-     moreover grow estimates already accounts that COMDAT
-     functions may or may not disappear when eliminated from
-     current unit. With good probability making aggressive
-     choice in all units is going to make overall program
-     smaller.  */
-  if (DECL_COMDAT (node->decl))
-    {
-      if (!node->can_remove_if_no_direct_calls_p ())
-       return true;
-    }
-  else if (!node->will_be_removed_from_program_if_no_direct_calls_p ())
+  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)
@@ -4039,6 +4032,22 @@ growth_likely_positive (struct cgraph_node *node,
     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
+     moreover grow estimates already accounts that COMDAT
+     functions may or may not disappear when eliminated from
+     current unit. With good probability making aggressive
+     choice in all units is going to make overall program
+     smaller.  */
+  if (DECL_COMDAT (node->decl))
+    {
+      if (!node->can_remove_if_no_direct_calls_p ())
+       return true;
+    }
+  else if (!node->will_be_removed_from_program_if_no_direct_calls_p ())
+    return true;
+
   return estimate_growth (node) > 0;
 }