OSDN Git Service

2009-09-04 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 Sep 2009 18:54:01 +0000 (18:54 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 Sep 2009 18:54:01 +0000 (18:54 +0000)
PR middle-end/41257
* (cgraph_finalize_compilation_unit): Move finalizing aliases
after emitting tunks.  Move emitting thunks and ctors from ...
(cgraph_optimize): ... here.  Remove redundant
cgraph_analyze_functions.
* varasm.c (find_decl_and_mark_needed): Remove no longer
necessary check.
(finish_aliases_1): Adjust check for thunk aliases.

* g++.dg/torture/pr41257.C: New testcase.

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

gcc/ChangeLog
gcc/cgraphunit.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr41257.C [new file with mode: 0644]
gcc/varasm.c

index 34bc5c2..6af6c2b 100644 (file)
@@ -1,3 +1,14 @@
+2009-09-04  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41257
+       * (cgraph_finalize_compilation_unit): Move finalizing aliases
+       after emitting tunks.  Move emitting thunks and ctors from ...
+       (cgraph_optimize): ... here.  Remove redundant
+       cgraph_analyze_functions.
+       * varasm.c (find_decl_and_mark_needed): Remove no longer
+       necessary check.
+       (finish_aliases_1): Adjust check for thunk aliases.
+
 2009-09-04  Daniel Gutson  <dgutson@codesourcery.com>
 
        * config/arm/arm.md (ctzsi2): Added braces
index 1505b56..0acc472 100644 (file)
@@ -1018,6 +1018,30 @@ cgraph_analyze_functions (void)
   ggc_collect ();
 }
 
+
+/* Emit thunks for every node in the cgraph.
+   FIXME: We really ought to emit thunks only for functions that are needed.  */
+
+static void
+cgraph_emit_thunks (void)
+{
+  struct cgraph_node *n;
+
+  for (n = cgraph_nodes; n; n = n->next)
+    {
+      /* Only emit thunks on functions defined in this TU.
+        Note that this may emit more thunks than strictly necessary.
+        During optimization some nodes may disappear.  It would be
+        nice to only emit thunks only for the functions that will be
+        emitted, but we cannot know that until the inliner and other
+        IPA passes have run (see the sequencing of the call to
+        cgraph_mark_functions_to_output in cgraph_optimize).  */
+      if (!DECL_EXTERNAL (n->decl))
+       lang_hooks.callgraph.emit_associated_thunks (n->decl);
+    }
+}
+
+
 /* Analyze the whole compilation unit once it is parsed completely.  */
 
 void
@@ -1026,8 +1050,16 @@ cgraph_finalize_compilation_unit (void)
   /* Do not skip analyzing the functions if there were errors, we
      miss diagnostics for following functions otherwise.  */
 
+  /* Emit size functions we didn't inline.  */
   finalize_size_functions ();
-  finish_aliases_1 ();
+
+  /* Emit thunks, if needed.  */
+  if (lang_hooks.callgraph.emit_associated_thunks)
+    cgraph_emit_thunks ();
+
+  /* Call functions declared with the "constructor" or "destructor"
+     attribute.  */
+  cgraph_build_cdtor_fns ();
 
   if (!quiet_flag)
     {
@@ -1035,6 +1067,10 @@ cgraph_finalize_compilation_unit (void)
       fflush (stderr);
     }
 
+  /* Mark alias targets necessary and emit diagnostics.  */
+  finish_aliases_1 ();
+
+  /* Gimplify and lower all functions.  */
   timevar_push (TV_CGRAPH);
   cgraph_analyze_functions ();
   timevar_pop (TV_CGRAPH);
@@ -1322,29 +1358,6 @@ ipa_passes (void)
 }
 
 
-/* Emit thunks for every node in the cgraph.
-   FIXME: We really ought to emit thunks only for functions that are needed.  */
-
-static void
-cgraph_emit_thunks (void)
-{
-  struct cgraph_node *n;
-
-  for (n = cgraph_nodes; n; n = n->next)
-    {
-      /* Only emit thunks on functions defined in this TU.
-        Note that this may emit more thunks than strictly necessary.
-        During optimization some nodes may disappear.  It would be
-        nice to only emit thunks only for the functions that will be
-        emitted, but we cannot know that until the inliner and other
-        IPA passes have run (see the sequencing of the call to
-        cgraph_mark_functions_to_output in cgraph_optimize).  */
-      if (!DECL_EXTERNAL (n->decl))
-       lang_hooks.callgraph.emit_associated_thunks (n->decl);
-    }
-}
-
-
 /* Perform simple optimizations based on callgraph.  */
 
 static void
@@ -1357,22 +1370,9 @@ cgraph_optimize (void)
   verify_cgraph ();
 #endif
 
-  /* Emit thunks, if needed.  */
-  if (lang_hooks.callgraph.emit_associated_thunks)
-    {
-      cgraph_emit_thunks ();
-      if (errorcount || sorrycount)
-       return;
-    }
-
-  /* Call functions declared with the "constructor" or "destructor"
-     attribute.  */
-  cgraph_build_cdtor_fns ();
-
   /* Frontend may output common variables after the unit has been finalized.
      It is safe to deal with them here as they are always zero initialized.  */
   varpool_analyze_pending_decls ();
-  cgraph_analyze_functions ();
 
   timevar_push (TV_CGRAPHOPT);
   if (pre_ipa_mem_report)
index d51cc02..b9c772b 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-04  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41257
+       * g++.dg/torture/pr41257.C: New testcase.
+
 2009-09-04  Martin Jambor  <mjambor@suse.cz>
 
        PR tree-optimization/41112
diff --git a/gcc/testsuite/g++.dg/torture/pr41257.C b/gcc/testsuite/g++.dg/torture/pr41257.C
new file mode 100644 (file)
index 0000000..60cfc53
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+struct A
+{
+  virtual void foo();
+  virtual ~A();
+  int i;
+};
+
+struct B : virtual A {};
+
+struct C : B
+{
+  virtual void foo();
+};
+
+void bar()
+{
+  C().foo();
+}
index d7f8611..864ab16 100644 (file)
@@ -5395,13 +5395,7 @@ find_decl_and_mark_needed (tree decl, tree target)
 
   if (fnode)
     {
-      /* We can't mark function nodes as used after cgraph global info
-        is finished.  This wouldn't generally be necessary, but C++
-        virtual table thunks are introduced late in the game and
-        might seem like they need marking, although in fact they
-        don't.  */
-      if (! cgraph_global_info_ready)
-       cgraph_mark_needed_node (fnode);
+      cgraph_mark_needed_node (fnode);
       return fnode->decl;
     }
   else if (vnode)
@@ -5571,7 +5565,7 @@ finish_aliases_1 (void)
                  to bind locally.  Of course this is a hack - to keep it
                  working do the following (which is not strictly correct).  */
               && (! TREE_CODE (target_decl) == FUNCTION_DECL
-                  || ! TREE_STATIC (target_decl))
+                  || ! DECL_VIRTUAL_P (target_decl))
               && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
        error ("%q+D aliased to external symbol %qE",
               p->decl, p->target);