diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f9f4b246e77fa5caaff38f4f1947558a764c3543..409799b315716e92fb4ac2489465129d91c779cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-07-02 Jakub Jelinek <jakub@redhat.com> + + * tree-nrv.c (dest_safe_for_nrv_p): Grok any handled_component_p, + SSA_NAMEs, RESULT_DECLs and PARM_DECLs. + 2007-07-02 Richard Guenther <rguenther@suse.de> * tree-ssa.c (useless_type_conversion_p): Document diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae9175355c90dd2c87677ffb32635ae04b8dead3..fee89cf8df61607414631a41629de2b1c4ffea44 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-07-02 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/opt/nrv12.C: New test. + * gcc.target/i386/nrv1.c: New test. + 2007-07-02 Ira Rosen <irar@il.ibm.com> PR tree-optimization/32230 diff --git a/gcc/testsuite/g++.dg/opt/nrv12.C b/gcc/testsuite/g++.dg/opt/nrv12.C new file mode 100644 index 0000000000000000000000000000000000000000..944dddd7b704b6e4a75a0702c981aa413eac71f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv12.C @@ -0,0 +1,25 @@ +/* Verify that gimple-level NRV is occurring even for RESULT_DECLs. *./ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O -fdump-tree-optimized" } */ +/* { dg-require-effective-target ilp32 } */ + +struct P +{ + long long l; + int a; + unsigned int b; + P(long long x) : l(x) {} +}; + +P foo (P); +P bar (P); + +P foo (P x) +{ + P y = P (-1LL); + y = bar (x); + return y; +} + +/* { dg-final { scan-tree-dump-times "return slot optimization" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/nrv1.c b/gcc/testsuite/gcc.target/i386/nrv1.c new file mode 100644 index 0000000000000000000000000000000000000000..5cd8b066d72528743fbbf3350b0acc83a4e60cad --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/nrv1.c @@ -0,0 +1,12 @@ +/* Verify that gimple-level NRV is occurring even for SSA_NAMEs. *./ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ +/* { dg-require-effective-target ilp32 } */ + +_Complex double foo (_Complex double x) +{ + return __builtin_cexp (x); +} + +/* { dg-final { scan-tree-dump-times "return slot optimization" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 5a0db8972522f7552cbdd664b1d88d8f2e84aab3..fe812a92ab6b201c202ad63ab68cb0ff11212d9f 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -250,26 +250,23 @@ struct tree_opt_pass pass_nrv = static bool dest_safe_for_nrv_p (tree dest) { - switch (TREE_CODE (dest)) - { - case VAR_DECL: - { - subvar_t subvar; - if (is_call_clobbered (dest)) - return false; - for (subvar = get_subvars_for_var (dest); - subvar; - subvar = subvar->next) - if (is_call_clobbered (subvar->var)) - return false; - return true; - } - case ARRAY_REF: - case COMPONENT_REF: - return dest_safe_for_nrv_p (TREE_OPERAND (dest, 0)); - default: - return false; - } + subvar_t subvar; + + while (handled_component_p (dest)) + dest = TREE_OPERAND (dest, 0); + + if (! SSA_VAR_P (dest)) + return false; + + if (TREE_CODE (dest) == SSA_NAME) + dest = SSA_NAME_VAR (dest); + + if (is_call_clobbered (dest)) + return false; + for (subvar = get_subvars_for_var (dest); subvar; subvar = subvar->next) + if (is_call_clobbered (subvar->var)) + return false; + return true; } /* Walk through the function looking for GIMPLE_MODIFY_STMTs with calls that