From: Jakub Jelinek Date: Thu, 12 Feb 2015 12:17:41 +0000 (+0100) Subject: backport: re PR target/64979 (stdarg optimization not able to find escape sites in... X-Git-Tag: releases/gcc-4.8.5~275 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf94b7cfb1d85a00872b0e6a5b6bcfcdedd38ca3;p=thirdparty%2Fgcc.git backport: re PR target/64979 (stdarg optimization not able to find escape sites in phi nodes) Backported from mainline 2015-02-09 Jakub Jelinek PR target/64979 * tree-stdarg.c (pass_stdarg::execute): Scan phi node args for va_list escapes. * gcc.dg/tree-ssa/stdarg-7.c: New test. * gcc.c-torture/execute/pr64979.c: New test. From-SVN: r220645 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42ca6f12ebb6..469ee31c9082 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-02-12 Jakub Jelinek + + Backported from mainline + 2015-02-09 Jakub Jelinek + + PR target/64979 + * tree-stdarg.c (pass_stdarg::execute): Scan phi node args for + va_list escapes. + 2015-02-11 Uros Bizjak * config/alpha/alpha.md (reload_out_aligned): Make operands 2 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f20e49897b5a..5ecad07979b6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-02-12 Jakub Jelinek + + Backported from mainline + 2015-02-09 Jakub Jelinek + + PR target/64979 + * gcc.dg/tree-ssa/stdarg-7.c: New test. + * gcc.c-torture/execute/pr64979.c: New test. + 2015-02-11 Richard Biener Backport from mainline diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64979.c b/gcc/testsuite/gcc.c-torture/execute/pr64979.c new file mode 100644 index 000000000000..ccb46087e029 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr64979.c @@ -0,0 +1,36 @@ +/* PR target/64979 */ + +#include + +void __attribute__((noinline, noclone)) +bar (int x, va_list *ap) +{ + if (ap) + { + int i; + for (i = 0; i < 10; i++) + if (i != va_arg (*ap, int)) + __builtin_abort (); + if (va_arg (*ap, double) != 0.5) + __builtin_abort (); + } +} + +void __attribute__((noinline, noclone)) +foo (int x, ...) +{ + va_list ap; + int n; + + va_start (ap, x); + n = va_arg (ap, int); + bar (x, (va_list *) ((n == 0) ? ((void *) 0) : &ap)); + va_end (ap); +} + +int +main () +{ + foo (100, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.5); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c new file mode 100644 index 000000000000..9b497c072700 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c @@ -0,0 +1,22 @@ +/* PR target/64979 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-stdarg" } */ + +#include + +void bar (int x, va_list *ap); + +void +foo (int x, ...) +{ + va_list ap; + int n; + + va_start (ap, x); + n = va_arg (ap, int); + bar (x, (va_list *) ((n == 0) ? ((void *) 0) : &ap)); + va_end (ap); +} + +/* { dg-final { scan-tree-dump "foo: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" } } */ +/* { dg-final { cleanup-tree-dump "stdarg" } } */ diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 8ad9fc2d22e4..d6f81a104eda 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -809,21 +809,22 @@ execute_optimize_stdarg (void) /* For va_list_simple_ptr, we have to check PHI nodes too. We treat them as assignments for the purpose of escape analysis. This is not needed for non-simple va_list because virtual phis don't perform - any real data movement. */ - if (va_list_simple_ptr) - { - tree lhs, rhs; - use_operand_p uop; - ssa_op_iter soi; + any real data movement. Also, check PHI nodes for taking address of + the va_list vars. */ + tree lhs, rhs; + use_operand_p uop; + ssa_op_iter soi; - for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) - { - gimple phi = gsi_stmt (i); - lhs = PHI_RESULT (phi); + for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) + { + gimple phi = gsi_stmt (i); + lhs = PHI_RESULT (phi); - if (virtual_operand_p (lhs)) - continue; + if (virtual_operand_p (lhs)) + continue; + if (va_list_simple_ptr) + { FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE) { rhs = USE_FROM_PTR (uop); @@ -846,6 +847,22 @@ execute_optimize_stdarg (void) } } } + + for (unsigned j = 0; !va_list_escapes + && j < gimple_phi_num_args (phi); ++j) + if ((!va_list_simple_ptr + || TREE_CODE (gimple_phi_arg_def (phi, j)) != SSA_NAME) + && walk_tree (gimple_phi_arg_def_ptr (phi, j), + find_va_list_reference, &wi, NULL)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fputs ("va_list escapes in ", dump_file); + print_gimple_stmt (dump_file, phi, 0, dump_flags); + fputc ('\n', dump_file); + } + va_list_escapes = true; + } } for (i = gsi_start_bb (bb); @@ -868,8 +885,8 @@ execute_optimize_stdarg (void) if (is_gimple_assign (stmt)) { - tree lhs = gimple_assign_lhs (stmt); - tree rhs = gimple_assign_rhs1 (stmt); + lhs = gimple_assign_lhs (stmt); + rhs = gimple_assign_rhs1 (stmt); if (va_list_simple_ptr) {