* tree-stdarg.c (execute_optimize_stdarg): Process PHI nodes too.
authorRichard Henderson <rth@redhat.com>
Sun, 2 Oct 2005 09:05:45 +0000 (02:05 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 2 Oct 2005 09:05:45 +0000 (02:05 -0700)
From-SVN: r104865

gcc/ChangeLog
gcc/tree-stdarg.c

index 2065da77b636c0fc12ee153263f67e3bca06d359..b431efa2ee5921d1b9f18b0f1c0c49fe0411a8b2 100644 (file)
@@ -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
index c68e7b58c2cd7b731ee4ebfdf71506c7bd95a0ea..287e3bbc7714a12c69f783fdcc71d472dd61c978 100644 (file)
@@ -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))