re PR debug/39086 (ICE in decl_ultimate_origin, at dwarf2out.c:5770 when compiling with -fno-tree-sra)
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. From-SVN: r144772
This commit is contained in:
parent
874b0a9e62
commit
7716876bbd
4 changed files with 129 additions and 8 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
97
gcc/testsuite/g++.dg/opt/nrv15.C
Normal file
97
gcc/testsuite/g++.dg/opt/nrv15.C
Normal file
|
@ -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 ();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue