OSDN Git Service

PR tree-optimization/45453
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 18 Sep 2010 23:13:17 +0000 (23:13 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 18 Sep 2010 23:13:17 +0000 (23:13 +0000)
* cgraphunit.c (cgraph_finalize_function): Consider comdat & external
virtual functions are reachable.
* ipa-inline.c (cgraph_clone_inlined_nodes): Likewise.
* ipa.c (cgraph_remove_unreachable_nodes): Likewise.
* ipa-prop.c (ipa_modify_formal_parameters): Clear DECL_VIRTUAL_P
when modifying function.

* g++.dg/tree-ssa/pr45453.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164405 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraphunit.c
gcc/ipa-inline.c
gcc/ipa-prop.c
gcc/ipa.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr45453.C [new file with mode: 0644]

index f650899..1258409 100644 (file)
@@ -1,5 +1,15 @@
 2010-09-18  Jan Hubicka  <jh@suse.cz>
 
+       PR tree-optimization/45453
+       * cgraphunit.c (cgraph_finalize_function): Consider comdat & external
+       virtual functions are reachable.
+       * ipa-inline.c (cgraph_clone_inlined_nodes): Likewise.
+       * ipa.c (cgraph_remove_unreachable_nodes): Likewise.
+       * ipa-prop.c (ipa_modify_formal_parameters): Clear DECL_VIRTUAL_P
+       when modifying function.
+
+2010-09-18  Jan Hubicka  <jh@suse.cz>
+
        PR tree-optimization/45605
        * cgraphunit.c (cgraph_analyze_functions): Allocate bitmap obstack.
        * gimple-fold.c (static_object_in_other_unit_p): New function.
index f296fe0..e390ec6 100644 (file)
@@ -363,7 +363,13 @@ cgraph_finalize_function (tree decl, bool nested)
      there.  */
   if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
       || DECL_STATIC_CONSTRUCTOR (decl)
-      || DECL_STATIC_DESTRUCTOR (decl))
+      || DECL_STATIC_DESTRUCTOR (decl)
+      /* COMDAT virtual functions may be referenced by vtable from
+        other compilatoin unit.  Still we want to devirtualize calls
+        to those so we need to analyze them.
+        FIXME: We should introduce may edges for this purpose and update
+        their handling in unreachable function removal and inliner too.  */
+      || (DECL_VIRTUAL_P (decl) && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
     cgraph_mark_reachable_node (node);
 
   /* If we've not yet emitted decl, tell the debug info about it.  */
index 964d03b..21e0b64 100644 (file)
@@ -251,6 +251,12 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
         In that case just go ahead and re-use it.  */
       if (!e->callee->callers->next_caller
          && cgraph_can_remove_if_no_direct_calls_p (e->callee)
+         /* 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 (e->callee->decl)
+             || (!DECL_COMDAT (e->callee->decl) && !DECL_EXTERNAL (e->callee->decl)))
          /* Don't reuse if more than one function shares a comdat group.
             If the other function(s) are needed, we need to emit even
             this function out of line.  */
index ec45d7c..e1d821e 100644 (file)
@@ -2120,6 +2120,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
     }
 
   TREE_TYPE (fndecl) = new_type;
+  DECL_VIRTUAL_P (fndecl) = 0;
   if (otypes)
     VEC_free (tree, heap, otypes);
   VEC_free (tree, heap, oparms);
index 8c0ca86..e4835c1 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -238,7 +238,12 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
 #endif
   varpool_reset_queue ();
   for (node = cgraph_nodes; node; node = node->next)
-    if (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
+    if ((!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
+        /* Keep around virtual functions for possible devirtualization.  */
+        || (!before_inlining_p
+            && !node->global.inlined_to
+            && DECL_VIRTUAL_P (node->decl)
+            && (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))))
        && ((!DECL_EXTERNAL (node->decl))
             || before_inlining_p))
       {
index 56d0fbd..805e4b8 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-18  Jan Hubicka  <jh@suse.cz>
+
+       PR tree-optimization/45453
+       * g++.dg/tree-ssa/pr45453.C: New testcase.
+
 2010-09-18  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/initlist44.C: New.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr45453.C b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C
new file mode 100644 (file)
index 0000000..78c6460
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+struct S
+{
+  S();
+  virtual inline void foo ()
+  {
+    foo();
+  }
+};
+
+void
+B ()
+{
+  S().foo ();
+}
+/* We should inline foo and devirtualize call to foo in the inlined version.  */
+// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 1 "optimized" } }
+// { dg-final { cleanup-tree-dump "optimized" } }