PR debug/39086
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Mar 2009 05:01:30 +0000 (05:01 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Mar 2009 05:01:30 +0000 (05:01 +0000)
        * tree-nrv.c (tree_nrv): Don't do this optimization if the front
        end already did.  Notice GIMPLE_CALL modifications of the result.
        Don't copy debug information from an ignored decl or a decl from
        another function.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/nrv15.C [new file with mode: 0644]
gcc/tree-nrv.c

index 7325c22..069a96c 100644 (file)
@@ -1,3 +1,11 @@
+2009-03-11  Jason Merrill  <jason@redhat.com>
+
+       PR debug/39086
+       * tree-nrv.c (tree_nrv): Don't do this optimization if the front
+       end already did.  Notice GIMPLE_CALL modifications of the result.
+       Don't copy debug information from an ignored decl or a decl from
+       another function.
+
 2009-03-10  Richard Guenther  <rguenther@suse.de>
            Nathan Froyd  <froydnj@codesourcery.com>
 
index c418e2b..711eba2 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-11  Jason Merrill  <jason@redhat.com>
+
+       PR debug/39086
+       * g++.dg/opt/nrv15.C: New test.
+
 2009-03-10  Ira Rosen  <irar@il.ibm.com>
 
        PR tree-optimization/39422
diff --git a/gcc/testsuite/g++.dg/opt/nrv15.C b/gcc/testsuite/g++.dg/opt/nrv15.C
new file mode 100644 (file)
index 0000000..23511b2
--- /dev/null
@@ -0,0 +1,97 @@
+// PR debug/39086
+// { dg-options "-g -O -fno-tree-sra" }
+
+struct A { int v; };
+
+A ax;
+
+struct B
+{
+  static A f1 () { return ax; }
+  static bool f2 ();
+  static A f3 ();
+};
+
+struct C
+{
+  A f4 ()
+  {
+    A x;
+    if (__builtin_expect (this->f6 () < this->f12 (), true))
+      x = B::f1 ();
+    else
+      x = this->f7 ();
+    return x;
+  }
+  A f5 ()
+  {
+    A y;
+    if (this->f6 () < this->f12 ())
+      y = B::f1 ();
+    else
+      y = this->f7 ();
+    return y;
+  }
+  void *f6 () const;
+  void *f12 () const;
+  virtual A f7 ();
+};
+
+C *dx;
+
+struct D
+{
+  C *f8 () const;
+};
+
+class E : virtual public D
+{
+  void f11 ();
+  void f9 ();
+  void f10 ();
+};
+
+struct G
+{
+  explicit G ();
+  operator bool () const;
+};
+
+void
+E::f11 (void)
+{
+  A d = B::f3 ();
+  d = this->f8 ()->f4 ();
+}
+
+void
+E::f9 ()
+{
+  G c;
+  if (c)
+    {
+      const A e = B::f3 ();
+      C * f = this->f8 ();
+      A d = f->f5 ();
+      if (B::f2 ())
+       ;
+      else if (B::f2 ())
+       f->f4 ();
+    }
+}
+
+void
+E::f10 ()
+{
+  G c;
+  if (c)
+    {
+      const A e = B::f3 ();
+      C * f = this->f8 ();
+      A d = f->f5 ();
+      if (B::f2 ())
+       ;
+      else if (B::f2 ())
+       f->f4 ();
+    }
+}
index 40e7508..7e811cf 100644 (file)
@@ -121,6 +121,10 @@ tree_nrv (void)
   if (is_gimple_reg_type (result_type))
     return 0;
 
+  /* If the front end already did something like this, don't do it here.  */
+  if (DECL_NAME (result))
+    return 0;
+
   /* Look through each block for assignments to the RESULT_DECL.  */
   FOR_EACH_BB (bb)
     {
@@ -138,8 +142,8 @@ tree_nrv (void)
              if (ret_val)
                gcc_assert (ret_val == result);
            }
-         else if (is_gimple_assign (stmt)
-                  && gimple_assign_lhs (stmt) == result)
+         else if (gimple_has_lhs (stmt)
+                  && gimple_get_lhs (stmt) == result)
            {
               tree rhs;
 
@@ -173,9 +177,9 @@ tree_nrv (void)
                                                TREE_TYPE (found)))
                return 0;
            }
-         else if (is_gimple_assign (stmt))
+         else if (gimple_has_lhs (stmt))
            {
-             tree addr = get_base_address (gimple_assign_lhs (stmt));
+             tree addr = get_base_address (gimple_get_lhs (stmt));
               /* If there's any MODIFY of component of RESULT, 
                  then bail out.  */
              if (addr && addr == result)
@@ -199,10 +203,17 @@ tree_nrv (void)
 
   /* At this point we know that all the return statements return the
      same local which has suitable attributes for NRV.   Copy debugging
-     information from FOUND to RESULT.  */
-  DECL_NAME (result) = DECL_NAME (found);
-  DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (found);
-  DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found);
+     information from FOUND to RESULT if it will be useful.  But don't set
+     DECL_ABSTRACT_ORIGIN to point at another function.  */
+  if (!DECL_IGNORED_P (found)
+      && !(DECL_ABSTRACT_ORIGIN (found)
+          && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (found)) != current_function_decl))
+    {
+      DECL_NAME (result) = DECL_NAME (found);
+      DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (found);
+      DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found);
+    }
+
   TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (found);
 
   /* Now walk through the function changing all references to VAR to be