OSDN Git Service

2009-02-20 Mark Mitchell <mark@codesourcery.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-stdarg.c
index 4a67bc8..00fce82 100644 (file)
@@ -1,12 +1,12 @@
 /* Pass computing data for optimizing stdarg functions.
 /* Pass computing data for optimizing stdarg functions.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
    Contributed by Jakub Jelinek <jakub@redhat.com>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
@@ -47,9 +46,9 @@ Boston, MA 02110-1301, USA.  */
 static bool
 reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
 {
 static bool
 reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
 {
-  edge *stack, e;
+  VEC (edge, heap) *stack = NULL;
+  edge e;
   edge_iterator ei;
   edge_iterator ei;
-  int sp;
   sbitmap visited;
   bool ret;
 
   sbitmap visited;
   bool ret;
 
@@ -59,22 +58,18 @@ reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
   if (! dominated_by_p (CDI_DOMINATORS, va_arg_bb, va_start_bb))
     return false;
 
   if (! dominated_by_p (CDI_DOMINATORS, va_arg_bb, va_start_bb))
     return false;
 
-  stack = XNEWVEC (edge, n_basic_blocks + 1);
-  sp = 0;
-
   visited = sbitmap_alloc (last_basic_block);
   sbitmap_zero (visited);
   ret = true;
 
   FOR_EACH_EDGE (e, ei, va_arg_bb->preds)
   visited = sbitmap_alloc (last_basic_block);
   sbitmap_zero (visited);
   ret = true;
 
   FOR_EACH_EDGE (e, ei, va_arg_bb->preds)
-    stack[sp++] = e;
+    VEC_safe_push (edge, heap, stack, e);
 
 
-  while (sp)
+  while (! VEC_empty (edge, stack))
     {
       basic_block src;
 
     {
       basic_block src;
 
-      --sp;
-      e = stack[sp];
+      e = VEC_pop (edge, stack);
       src = e->src;
 
       if (e->flags & EDGE_COMPLEX)
       src = e->src;
 
       if (e->flags & EDGE_COMPLEX)
@@ -99,11 +94,11 @@ reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
        {
          SET_BIT (visited, src->index);
          FOR_EACH_EDGE (e, ei, src->preds)
        {
          SET_BIT (visited, src->index);
          FOR_EACH_EDGE (e, ei, src->preds)
-           stack[sp++] = e;
+           VEC_safe_push (edge, heap, stack, e);
        }
     }
 
        }
     }
 
-  free (stack);
+  VEC_free (edge, heap, stack);
   sbitmap_free (visited);
   return ret;
 }
   sbitmap_free (visited);
   return ret;
 }
@@ -117,7 +112,8 @@ static unsigned HOST_WIDE_INT
 va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
                      bool gpr_p)
 {
 va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
                      bool gpr_p)
 {
-  tree stmt, lhs, orig_lhs;
+  tree lhs, orig_lhs;
+  gimple stmt;
   unsigned HOST_WIDE_INT ret = 0, val, counter_val;
   unsigned int max_size;
 
   unsigned HOST_WIDE_INT ret = 0, val, counter_val;
   unsigned int max_size;
 
@@ -135,6 +131,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
   orig_lhs = lhs = rhs;
   while (lhs)
     {
   orig_lhs = lhs = rhs;
   while (lhs)
     {
+      enum tree_code rhs_code;
+
       if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
        {
          if (counter_val >= max_size)
       if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
        {
          if (counter_val >= max_size)
@@ -149,38 +147,32 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
 
       stmt = SSA_NAME_DEF_STMT (lhs);
 
 
       stmt = SSA_NAME_DEF_STMT (lhs);
 
-      if (TREE_CODE (stmt) != MODIFY_EXPR
-         || TREE_OPERAND (stmt, 0) != lhs)
+      if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs)
        return (unsigned HOST_WIDE_INT) -1;
 
        return (unsigned HOST_WIDE_INT) -1;
 
-      rhs = TREE_OPERAND (stmt, 1);
-      if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-       rhs = TREE_OPERAND (rhs, 0);
-
-      if (TREE_CODE (rhs) == SSA_NAME)
+      rhs_code = gimple_assign_rhs_code (stmt);
+      if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
+          || gimple_assign_cast_p (stmt))
+         && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
        {
        {
-         lhs = rhs;
+         lhs = gimple_assign_rhs1 (stmt);
          continue;
        }
 
          continue;
        }
 
-      if ((TREE_CODE (rhs) == NOP_EXPR
-          || TREE_CODE (rhs) == CONVERT_EXPR)
-         && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+      if ((rhs_code == POINTER_PLUS_EXPR
+          || rhs_code == PLUS_EXPR)
+         && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+         && host_integerp (gimple_assign_rhs2 (stmt), 1))
        {
        {
-         lhs = TREE_OPERAND (rhs, 0);
+         ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+         lhs = gimple_assign_rhs1 (stmt);
          continue;
        }
 
          continue;
        }
 
-      if (TREE_CODE (rhs) == PLUS_EXPR
-         && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
-         && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
-         && host_integerp (TREE_OPERAND (rhs, 1), 1))
-       {
-         ret += tree_low_cst (TREE_OPERAND (rhs, 1), 1);
-         lhs = TREE_OPERAND (rhs, 0);
-         continue;
-       }
+      if (get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS)
+       return (unsigned HOST_WIDE_INT) -1;
 
 
+      rhs = gimple_assign_rhs1 (stmt);
       if (TREE_CODE (counter) != TREE_CODE (rhs))
        return (unsigned HOST_WIDE_INT) -1;
 
       if (TREE_CODE (counter) != TREE_CODE (rhs))
        return (unsigned HOST_WIDE_INT) -1;
 
@@ -201,6 +193,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
   val = ret + counter_val;
   while (lhs)
     {
   val = ret + counter_val;
   while (lhs)
     {
+      enum tree_code rhs_code;
+
       if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
        break;
 
       if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
        break;
 
@@ -211,31 +205,22 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
 
       stmt = SSA_NAME_DEF_STMT (lhs);
 
 
       stmt = SSA_NAME_DEF_STMT (lhs);
 
-      rhs = TREE_OPERAND (stmt, 1);
-      if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-       rhs = TREE_OPERAND (rhs, 0);
-
-      if (TREE_CODE (rhs) == SSA_NAME)
+      rhs_code = gimple_assign_rhs_code (stmt);
+      if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
+          || gimple_assign_cast_p (stmt))
+         && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
        {
        {
-         lhs = rhs;
+         lhs = gimple_assign_rhs1 (stmt);
          continue;
        }
 
          continue;
        }
 
-      if ((TREE_CODE (rhs) == NOP_EXPR
-          || TREE_CODE (rhs) == CONVERT_EXPR)
-         && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+      if ((rhs_code == POINTER_PLUS_EXPR
+          || rhs_code == PLUS_EXPR)
+         && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+         && host_integerp (gimple_assign_rhs2 (stmt), 1))
        {
        {
-         lhs = TREE_OPERAND (rhs, 0);
-         continue;
-       }
-
-      if (TREE_CODE (rhs) == PLUS_EXPR
-         && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
-         && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
-         && host_integerp (TREE_OPERAND (rhs, 1), 1))
-       {
-         val -= tree_low_cst (TREE_OPERAND (rhs, 1), 1);
-         lhs = TREE_OPERAND (rhs, 0);
+         val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+         lhs = gimple_assign_rhs1 (stmt);
          continue;
        }
 
          continue;
        }
 
@@ -252,7 +237,7 @@ static tree
 find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
                        void *data)
 {
 find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
                        void *data)
 {
-  bitmap va_list_vars = (bitmap) data;
+  bitmap va_list_vars = (bitmap) ((struct walk_stmt_info *) data)->info;
   tree var = *tp;
 
   if (TREE_CODE (var) == SSA_NAME)
   tree var = *tp;
 
   if (TREE_CODE (var) == SSA_NAME)
@@ -447,12 +432,6 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs)
   if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
     return;
 
   if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
     return;
 
-  if ((TREE_CODE (rhs) == PLUS_EXPR
-       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
-      || TREE_CODE (rhs) == NOP_EXPR
-      || TREE_CODE (rhs) == CONVERT_EXPR)
-    rhs = TREE_OPERAND (rhs, 0);
-
   if (TREE_CODE (rhs) != SSA_NAME
       || ! bitmap_bit_p (si->va_list_escape_vars,
                         DECL_UID (SSA_NAME_VAR (rhs))))
   if (TREE_CODE (rhs) != SSA_NAME
       || ! bitmap_bit_p (si->va_list_escape_vars,
                         DECL_UID (SSA_NAME_VAR (rhs))))
@@ -509,11 +488,12 @@ check_all_va_list_escapes (struct stdarg_info *si)
 
   FOR_EACH_BB (bb)
     {
 
   FOR_EACH_BB (bb)
     {
-      block_stmt_iterator i;
+      gimple_stmt_iterator i;
 
 
-      for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
        {
        {
-         tree stmt = bsi_stmt (i), use;
+         gimple stmt = gsi_stmt (i);
+         tree use;
          ssa_op_iter iter;
 
          FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
          ssa_op_iter iter;
 
          FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
@@ -522,16 +502,13 @@ check_all_va_list_escapes (struct stdarg_info *si)
                                  DECL_UID (SSA_NAME_VAR (use))))
                continue;
 
                                  DECL_UID (SSA_NAME_VAR (use))))
                continue;
 
-             if (TREE_CODE (stmt) == MODIFY_EXPR)
+             if (is_gimple_assign (stmt))
                {
                {
-                 tree lhs = TREE_OPERAND (stmt, 0);
-                 tree rhs = TREE_OPERAND (stmt, 1);
-
-                 if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-                   rhs = TREE_OPERAND (rhs, 0);
+                 tree rhs = gimple_assign_rhs1 (stmt);
+                 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
 
                  /* x = *ap_temp;  */
 
                  /* x = *ap_temp;  */
-                 if (TREE_CODE (rhs) == INDIRECT_REF
+                 if (gimple_assign_rhs_code (stmt) == INDIRECT_REF
                      && TREE_OPERAND (rhs, 0) == use
                      && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
                      && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
                      && TREE_OPERAND (rhs, 0) == use
                      && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
                      && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
@@ -555,14 +532,16 @@ check_all_va_list_escapes (struct stdarg_info *si)
                     other_ap_temp = (some_type *) ap_temp;
                     ap = ap_temp;
                     statements.  */
                     other_ap_temp = (some_type *) ap_temp;
                     ap = ap_temp;
                     statements.  */
-                 if ((TREE_CODE (rhs) == PLUS_EXPR
-                      && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
-                     || TREE_CODE (rhs) == NOP_EXPR
-                     || TREE_CODE (rhs) == CONVERT_EXPR)
-                   rhs = TREE_OPERAND (rhs, 0);
-
-                 if (rhs == use)
+                 if (rhs == use
+                     && ((rhs_code == POINTER_PLUS_EXPR
+                          && (TREE_CODE (gimple_assign_rhs2 (stmt))
+                              == INTEGER_CST))
+                         || gimple_assign_cast_p (stmt)
+                         || (get_gimple_rhs_class (rhs_code)
+                             == GIMPLE_SINGLE_RHS)))
                    {
                    {
+                     tree lhs = gimple_assign_lhs (stmt);
+
                      if (TREE_CODE (lhs) == SSA_NAME
                          && bitmap_bit_p (si->va_list_escape_vars,
                                           DECL_UID (SSA_NAME_VAR (lhs))))
                      if (TREE_CODE (lhs) == SSA_NAME
                          && bitmap_bit_p (si->va_list_escape_vars,
                                           DECL_UID (SSA_NAME_VAR (lhs))))
@@ -578,7 +557,7 @@ check_all_va_list_escapes (struct stdarg_info *si)
              if (dump_file && (dump_flags & TDF_DETAILS))
                {
                  fputs ("va_list escapes in ", dump_file);
              if (dump_file && (dump_flags & TDF_DETAILS))
                {
                  fputs ("va_list escapes in ", dump_file);
-                 print_generic_expr (dump_file, stmt, dump_flags);
+                 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
                  fputc ('\n', dump_file);
                }
              return true;
                  fputc ('\n', dump_file);
                }
              return true;
@@ -597,7 +576,7 @@ static bool
 gate_optimize_stdarg (void)
 {
   /* This optimization is only for stdarg functions.  */
 gate_optimize_stdarg (void)
 {
   /* This optimization is only for stdarg functions.  */
-  return current_function_stdarg != 0;
+  return cfun->stdarg != 0;
 }
 
 
 }
 
 
@@ -610,7 +589,9 @@ execute_optimize_stdarg (void)
   bool va_list_escapes = false;
   bool va_list_simple_ptr;
   struct stdarg_info si;
   bool va_list_escapes = false;
   bool va_list_simple_ptr;
   struct stdarg_info si;
+  struct walk_stmt_info wi;
   const char *funcname = NULL;
   const char *funcname = NULL;
+  tree cfun_va_list;
 
   cfun->va_list_gpr_size = 0;
   cfun->va_list_fpr_size = 0;
 
   cfun->va_list_gpr_size = 0;
   cfun->va_list_fpr_size = 0;
@@ -621,25 +602,25 @@ execute_optimize_stdarg (void)
   if (dump_file)
     funcname = lang_hooks.decl_printable_name (current_function_decl, 2);
 
   if (dump_file)
     funcname = lang_hooks.decl_printable_name (current_function_decl, 2);
 
-  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);
+  cfun_va_list = targetm.fn_abi_va_list (cfun->decl);
+  va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
+                      && (TREE_TYPE (cfun_va_list) == void_type_node
+                          || TREE_TYPE (cfun_va_list) == char_type_node);
+  gcc_assert (is_gimple_reg_type (cfun_va_list) == va_list_simple_ptr);
 
   FOR_EACH_BB (bb)
     {
 
   FOR_EACH_BB (bb)
     {
-      block_stmt_iterator i;
+      gimple_stmt_iterator i;
 
 
-      for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
        {
        {
-         tree stmt = bsi_stmt (i);
-         tree call = get_call_expr_in (stmt), callee;
-         tree ap;
+         gimple stmt = gsi_stmt (i);
+         tree callee, ap;
 
 
-         if (!call)
+         if (!is_gimple_call (stmt))
            continue;
 
            continue;
 
-         callee = get_callee_fndecl (call);
+         callee = gimple_call_fndecl (stmt);
          if (!callee
              || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
            continue;
          if (!callee
              || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
            continue;
@@ -650,7 +631,6 @@ execute_optimize_stdarg (void)
              break;
              /* If old style builtins are used, don't optimize anything.  */
            case BUILT_IN_SAVEREGS:
              break;
              /* If old style builtins are used, don't optimize anything.  */
            case BUILT_IN_SAVEREGS:
-           case BUILT_IN_STDARG_START:
            case BUILT_IN_ARGS_INFO:
            case BUILT_IN_NEXT_ARG:
              va_list_escapes = true;
            case BUILT_IN_ARGS_INFO:
            case BUILT_IN_NEXT_ARG:
              va_list_escapes = true;
@@ -660,7 +640,7 @@ execute_optimize_stdarg (void)
            }
 
          si.va_start_count++;
            }
 
          si.va_start_count++;
-         ap = TREE_VALUE (TREE_OPERAND (call, 1));
+         ap = gimple_call_arg (stmt, 0);
 
          if (TREE_CODE (ap) != ADDR_EXPR)
            {
 
          if (TREE_CODE (ap) != ADDR_EXPR)
            {
@@ -678,7 +658,7 @@ execute_optimize_stdarg (void)
              ap = TREE_OPERAND (ap, 0);
            }
          if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
              ap = TREE_OPERAND (ap, 0);
            }
          if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
-             != TYPE_MAIN_VARIANT (va_list_type_node)
+             != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (cfun->decl))
              || TREE_CODE (ap) != VAR_DECL)
            {
              va_list_escapes = true;
              || TREE_CODE (ap) != VAR_DECL)
            {
              va_list_escapes = true;
@@ -736,10 +716,12 @@ execute_optimize_stdarg (void)
     cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
 
   calculate_dominance_info (CDI_DOMINATORS);
     cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
 
   calculate_dominance_info (CDI_DOMINATORS);
+  memset (&wi, 0, sizeof (wi));
+  wi.info = si.va_list_vars;
 
   FOR_EACH_BB (bb)
     {
 
   FOR_EACH_BB (bb)
     {
-      block_stmt_iterator i;
+      gimple_stmt_iterator i;
 
       si.compute_sizes = -1;
       si.bb = bb;
 
       si.compute_sizes = -1;
       si.bb = bb;
@@ -750,12 +732,13 @@ execute_optimize_stdarg (void)
         any real data movement.  */
       if (va_list_simple_ptr)
        {
         any real data movement.  */
       if (va_list_simple_ptr)
        {
-         tree phi, lhs, rhs;
+         tree lhs, rhs;
          use_operand_p uop;
          ssa_op_iter soi;
 
          use_operand_p uop;
          ssa_op_iter soi;
 
-         for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+         for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
            {
            {
+             gimple phi = gsi_stmt (i);
              lhs = PHI_RESULT (phi);
 
              if (!is_gimple_reg (lhs))
              lhs = PHI_RESULT (phi);
 
              if (!is_gimple_reg (lhs))
@@ -771,14 +754,12 @@ execute_optimize_stdarg (void)
                  else
                    check_va_list_escapes (&si, lhs, rhs);
 
                  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 (si.va_list_escapes)
                    {
                      if (dump_file && (dump_flags & TDF_DETAILS))
                        {
                          fputs ("va_list escapes in ", dump_file);
                    {
                      if (dump_file && (dump_flags & TDF_DETAILS))
                        {
                          fputs ("va_list escapes in ", dump_file);
-                         print_generic_expr (dump_file, phi, dump_flags);
+                         print_gimple_stmt (dump_file, phi, 0, dump_flags);
                          fputc ('\n', dump_file);
                        }
                      va_list_escapes = true;
                          fputc ('\n', dump_file);
                        }
                      va_list_escapes = true;
@@ -787,18 +768,16 @@ execute_optimize_stdarg (void)
            }
        }
 
            }
        }
 
-      for (i = bsi_start (bb);
-          !bsi_end_p (i) && !va_list_escapes;
-          bsi_next (&i))
+      for (i = gsi_start_bb (bb);
+          !gsi_end_p (i) && !va_list_escapes;
+          gsi_next (&i))
        {
        {
-         tree stmt = bsi_stmt (i);
-         tree call;
+         gimple stmt = gsi_stmt (i);
 
          /* Don't look at __builtin_va_{start,end}, they are ok.  */
 
          /* Don't look at __builtin_va_{start,end}, they are ok.  */
-         call = get_call_expr_in (stmt);
-         if (call)
+         if (is_gimple_call (stmt))
            {
            {
-             tree callee = get_callee_fndecl (call);
+             tree callee = gimple_call_fndecl (stmt);
 
              if (callee
                  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
 
              if (callee
                  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
@@ -807,44 +786,54 @@ execute_optimize_stdarg (void)
                continue;
            }
 
                continue;
            }
 
-         if (TREE_CODE (stmt) == MODIFY_EXPR)
+         if (is_gimple_assign (stmt))
            {
            {
-             tree lhs = TREE_OPERAND (stmt, 0);
-             tree rhs = TREE_OPERAND (stmt, 1);
-
-             if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
-               rhs = TREE_OPERAND (rhs, 0);
+             tree lhs = gimple_assign_lhs (stmt);
+             tree rhs = gimple_assign_rhs1 (stmt);
 
              if (va_list_simple_ptr)
                {
 
              if (va_list_simple_ptr)
                {
-                 /* Check for tem = ap.  */
-                 if (va_list_ptr_read (&si, rhs, lhs))
-                   continue;
+                 if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+                     == GIMPLE_SINGLE_RHS)
+                   {
+                     /* Check for tem = ap.  */
+                     if (va_list_ptr_read (&si, rhs, lhs))
+                       continue;
 
 
-                 /* Check for the last insn in:
-                    tem1 = ap;
-                    tem2 = tem1 + CST;
-                    ap = tem2;
-                    sequence.  */
-                 else if (va_list_ptr_write (&si, lhs, rhs))
-                   continue;
+                     /* Check for the last insn in:
+                        tem1 = ap;
+                        tem2 = tem1 + CST;
+                        ap = tem2;
+                        sequence.  */
+                     else if (va_list_ptr_write (&si, lhs, rhs))
+                       continue;
+                   }
 
 
-                 else
+                 if ((gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
+                      && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
+                     || CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+                     || (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+                         == GIMPLE_SINGLE_RHS))
                    check_va_list_escapes (&si, lhs, rhs);
                }
              else
                {
                    check_va_list_escapes (&si, lhs, rhs);
                }
              else
                {
-                 /* Check for ap[0].field = temp.  */
-                 if (va_list_counter_struct_op (&si, lhs, rhs, true))
-                   continue;
+                 if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+                     == GIMPLE_SINGLE_RHS)
+                   {
+                     /* Check for ap[0].field = temp.  */
+                     if (va_list_counter_struct_op (&si, lhs, rhs, true))
+                       continue;
 
 
-                 /* Check for temp = ap[0].field.  */
-                 else if (va_list_counter_struct_op (&si, rhs, lhs, false))
-                   continue;
+                     /* Check for temp = ap[0].field.  */
+                     else if (va_list_counter_struct_op (&si, rhs, lhs,
+                                                         false))
+                       continue;
+                   }
 
                  /* Do any architecture specific checking.  */
 
                  /* Do any architecture specific checking.  */
-                 else if (targetm.stdarg_optimize_hook
-                          && targetm.stdarg_optimize_hook (&si, lhs, rhs))
+                 if (targetm.stdarg_optimize_hook
+                     && targetm.stdarg_optimize_hook (&si, stmt))
                    continue;
                }
            }
                    continue;
                }
            }
@@ -856,13 +845,12 @@ execute_optimize_stdarg (void)
             fully), or some unexpected use of va_list.  None of these should
             happen in a gimplified VA_ARG_EXPR.  */
          if (si.va_list_escapes
             fully), or some unexpected use of va_list.  None of these should
             happen in a gimplified VA_ARG_EXPR.  */
          if (si.va_list_escapes
-             || walk_tree (&stmt, find_va_list_reference,
-                           si.va_list_vars, NULL))
+             || walk_gimple_op (stmt, find_va_list_reference, &wi))
            {
              if (dump_file && (dump_flags & TDF_DETAILS))
                {
                  fputs ("va_list escapes in ", dump_file);
            {
              if (dump_file && (dump_flags & TDF_DETAILS))
                {
                  fputs ("va_list escapes in ", dump_file);
-                 print_generic_expr (dump_file, stmt, dump_flags);
+                 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
                  fputc ('\n', dump_file);
                }
              va_list_escapes = true;
                  fputc ('\n', dump_file);
                }
              va_list_escapes = true;
@@ -907,8 +895,10 @@ finish:
 }
 
 
 }
 
 
-struct tree_opt_pass pass_stdarg =
+struct gimple_opt_pass pass_stdarg =
 {
 {
+ {
+  GIMPLE_PASS,
   "stdarg",                            /* name */
   gate_optimize_stdarg,                        /* gate */
   execute_optimize_stdarg,             /* execute */
   "stdarg",                            /* name */
   gate_optimize_stdarg,                        /* gate */
   execute_optimize_stdarg,             /* execute */
@@ -920,6 +910,6 @@ struct tree_opt_pass pass_stdarg =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func,                      /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func                       /* todo_flags_finish */
+ }
 };
 };