re PR ipa/63671 (21% tramp3d-v4 performance hit due to -fdevirtualize)
authorJan Hubicka <hubicka@ucw.cz>
Mon, 24 Nov 2014 16:15:46 +0000 (17:15 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 24 Nov 2014 16:15:46 +0000 (16:15 +0000)
PR ipa/63671
* ipa-inline-transform.c (can_remove_node_now_p_1): Handle alises
and -fno-devirtualize more carefully.
(can_remove_node_now_p): Update.

From-SVN: r218024

gcc/ChangeLog
gcc/ipa-inline-transform.c

index ffd21936ebf5a85b8e9ed503553d39a746f02abb..1ed780ca8558e3e398042ea5a88f48629e84af50 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-22  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/63671
+       * ipa-inline-transform.c (can_remove_node_now_p_1): Handle alises
+       and -fno-devirtualize more carefully.
+       (can_remove_node_now_p): Update.
+
 2014-11-24  Andrew Pinski  <apinski@cavium.com>
 
        PR rtl-opt/63972
index a64e4dd379cf1e2615786056eb36872ec287d0bc..063cd94cda67ac6e1a63e7332a8b0aa363249e28 100644 (file)
@@ -93,19 +93,28 @@ update_noncloned_frequencies (struct cgraph_node *node,
    copy of function was removed.  */
 
 static bool
-can_remove_node_now_p_1 (struct cgraph_node *node)
+can_remove_node_now_p_1 (struct cgraph_node *node, struct cgraph_edge *e)
 {
+  ipa_ref *ref;
+
+  FOR_EACH_ALIAS (node, ref)
+    {
+      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+      if ((alias->callers && alias->callers != e)
+          || !can_remove_node_now_p_1 (alias, e))
+       return false;
+    }
   /* FIXME: When address is taken of DECL_EXTERNAL function we still
      can remove its offline copy, but we would need to keep unanalyzed node in
      the callgraph so references can point to it.  */
   return (!node->address_taken
-         && !node->has_aliases_p ()
          && node->can_remove_if_no_direct_calls_p ()
          /* Inlining might enable more devirtualizing, so we want to remove
             those only after all devirtualizable virtual calls are processed.
             Lacking may edges in callgraph we just preserve them post
             inlining.  */
-         && !DECL_VIRTUAL_P (node->decl)
+         && (!DECL_VIRTUAL_P (node->decl)
+             || !opt_for_fn (node->decl, flag_devirtualize))
          /* During early inlining some unanalyzed cgraph nodes might be in the
             callgraph and they might reffer the function in question.  */
          && !cgraph_new_nodes.exists ());
@@ -119,7 +128,7 @@ static bool
 can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e)
 {
   struct cgraph_node *next;
-  if (!can_remove_node_now_p_1 (node))
+  if (!can_remove_node_now_p_1 (node, e))
     return false;
 
   /* When we see same comdat group, we need to be sure that all
@@ -128,9 +137,13 @@ can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e)
     return true;
   for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
        next != node; next = dyn_cast<cgraph_node *> (next->same_comdat_group))
-    if ((next->callers && next->callers != e)
-       || !can_remove_node_now_p_1 (next))
-      return false;
+    {
+      if (next->alias)
+       continue;
+      if ((next->callers && next->callers != e)
+         || !can_remove_node_now_p_1 (next, e))
+        return false;
+    }
   return true;
 }