Commit 21c0137a by Jakub Jelinek

re PR target/64979 (stdarg optimization not able to find escape sites in phi nodes)

	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: r220543
parent 468963de
2015-02-09 Jakub Jelinek <jakub@redhat.com>
PR target/64979
* tree-stdarg.c (pass_stdarg::execute): Scan phi node args for
va_list escapes.
2015-02-09 Richard Biener <rguenther@suse.de> 2015-02-09 Richard Biener <rguenther@suse.de>
* genmatch.c (replace_id): Copy expr_type. * genmatch.c (replace_id): Copy expr_type.
......
2015-02-29 Alan Lawrence <alan.lawrence@arm.com> 2015-02-09 Jakub Jelinek <jakub@redhat.com>
PR target/64979
* gcc.dg/tree-ssa/stdarg-7.c: New test.
* gcc.c-torture/execute/pr64979.c: New test.
2015-02-09 Alan Lawrence <alan.lawrence@arm.com>
* gcc.target/arm/macro_defs0.c: Remove extraneous "target" * gcc.target/arm/macro_defs0.c: Remove extraneous "target"
......
/* PR target/64979 */
#include <stdarg.h>
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;
}
/* PR target/64979 */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-stdarg" } */
#include <stdarg.h>
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" } } */
...@@ -856,22 +856,23 @@ pass_stdarg::execute (function *fun) ...@@ -856,22 +856,23 @@ pass_stdarg::execute (function *fun)
/* For va_list_simple_ptr, we have to check PHI nodes too. We treat /* 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 them as assignments for the purpose of escape analysis. This is
not needed for non-simple va_list because virtual phis don't perform not needed for non-simple va_list because virtual phis don't perform
any real data movement. */ any real data movement. Also, check PHI nodes for taking address of
if (va_list_simple_ptr) the va_list vars. */
{ tree lhs, rhs;
tree lhs, rhs; use_operand_p uop;
use_operand_p uop; ssa_op_iter soi;
ssa_op_iter soi;
for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i); for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i);
gsi_next (&i)) gsi_next (&i))
{ {
gphi *phi = i.phi (); gphi *phi = i.phi ();
lhs = PHI_RESULT (phi); lhs = PHI_RESULT (phi);
if (virtual_operand_p (lhs)) if (virtual_operand_p (lhs))
continue; continue;
if (va_list_simple_ptr)
{
FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE) FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE)
{ {
rhs = USE_FROM_PTR (uop); rhs = USE_FROM_PTR (uop);
...@@ -894,6 +895,22 @@ pass_stdarg::execute (function *fun) ...@@ -894,6 +895,22 @@ pass_stdarg::execute (function *fun)
} }
} }
} }
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 (gimple_stmt_iterator i = gsi_start_bb (bb); for (gimple_stmt_iterator i = gsi_start_bb (bb);
...@@ -916,8 +933,8 @@ pass_stdarg::execute (function *fun) ...@@ -916,8 +933,8 @@ pass_stdarg::execute (function *fun)
if (is_gimple_assign (stmt)) if (is_gimple_assign (stmt))
{ {
tree lhs = gimple_assign_lhs (stmt); lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt); rhs = gimple_assign_rhs1 (stmt);
if (va_list_simple_ptr) if (va_list_simple_ptr)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment