summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-02 09:05:45 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-02 09:05:45 +0000
commit35bf4ce878114c32be014e7c8c062a2b658e70bf (patch)
tree86f300dd419cffeeb646b4417b1ddf2fd0d638f5
parentf7445449807cd7f98f39d844624ac915146155ef (diff)
downloadgcc-35bf4ce878114c32be014e7c8c062a2b658e70bf.tar.gz
* tree-stdarg.c (execute_optimize_stdarg): Process PHI nodes too.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104865 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/tree-stdarg.c45
2 files changed, 49 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2065da77b63..b431efa2ee5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2005-10-01 Richard Henderson <rth@redhat.com>
+
+ * tree-stdarg.c (execute_optimize_stdarg): Process PHI nodes too.
+
2005-10-01 Mark Mitchell <mark@codesourcery.com>
* config/arm/unknown-elf.h (LINK_GCC_C_SEQUENCE_SPEC): Define
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index c68e7b58c2c..287e3bbc771 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -624,6 +624,7 @@ execute_optimize_stdarg (void)
va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
&& (TREE_TYPE (va_list_type_node) == void_type_node
|| TREE_TYPE (va_list_type_node) == char_type_node);
+ gcc_assert (is_gimple_reg_type (va_list_type_node) == va_list_simple_ptr);
FOR_EACH_BB (bb)
{
@@ -742,6 +743,50 @@ execute_optimize_stdarg (void)
si.compute_sizes = -1;
si.bb = bb;
+
+ /* 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 phi, lhs, rhs;
+ use_operand_p uop;
+ ssa_op_iter soi;
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ lhs = PHI_RESULT (phi);
+
+ if (!is_gimple_reg (lhs))
+ continue;
+
+ FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE)
+ {
+ rhs = USE_FROM_PTR (uop);
+ if (va_list_ptr_read (&si, rhs, lhs))
+ continue;
+ else if (va_list_ptr_write (&si, lhs, rhs))
+ continue;
+ else
+ check_va_list_escapes (&si, lhs, rhs);
+
+ if (si.va_list_escapes
+ || walk_tree (&phi, find_va_list_reference,
+ si.va_list_vars, NULL))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fputs ("va_list escapes in ", dump_file);
+ print_generic_expr (dump_file, phi, dump_flags);
+ fputc ('\n', dump_file);
+ }
+ va_list_escapes = true;
+ }
+ }
+ }
+ }
+
for (i = bsi_start (bb);
!bsi_end_p (i) && !va_list_escapes;
bsi_next (&i))