OSDN Git Service

2011-05-27 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfg.c
index bffa679..f6b1710 100644 (file)
@@ -1,6 +1,6 @@
 /* Control flow functions for trees.
    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010  Free Software Foundation, Inc.
+   2010, 2011  Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dump.h"
 #include "tree-pass.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "except.h"
 #include "cfgloop.h"
 #include "cfglayout.h"
@@ -758,7 +757,7 @@ same_line_p (location_t locus1, location_t locus2)
     return true;
   return (from.file != NULL
           && to.file != NULL
-          && strcmp (from.file, to.file) == 0);
+          && filename_cmp (from.file, to.file) == 0);
 }
 
 /* Assign a unique discriminator value to block BB if it begins at the same
@@ -839,12 +838,12 @@ edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
 
   for (t = (tree) *value; t; t = next)
     {
-      next = TREE_CHAIN (t);
-      TREE_CHAIN (t) = NULL;
+      next = CASE_CHAIN (t);
+      CASE_CHAIN (t) = NULL;
     }
 
   *value = NULL;
-  return false;
+  return true;
 }
 
 /* Start recording information mapping edges to case labels.  */
@@ -923,7 +922,7 @@ get_cases_for_edge (edge e, gimple t)
       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
         a new chain.  */
       slot = pointer_map_insert (edge_to_cases, this_edge);
-      TREE_CHAIN (elt) = (tree) *slot;
+      CASE_CHAIN (elt) = (tree) *slot;
       *slot = elt;
     }
 
@@ -1359,13 +1358,14 @@ group_case_labels_stmt (gimple stmt)
        {
          tree merge_case = gimple_switch_label (stmt, i);
          tree merge_label = CASE_LABEL (merge_case);
-         tree t = int_const_binop (PLUS_EXPR, base_high,
-                                   integer_one_node, 1);
+         double_int bhp1 = double_int_add (tree_to_double_int (base_high),
+                                           double_int_one);
 
          /* Merge the cases if they jump to the same place,
             and their ranges are consecutive.  */
          if (merge_label == base_label
-             && tree_int_cst_equal (CASE_LOW (merge_case), t))
+             && double_int_equal_p (tree_to_double_int (CASE_LOW (merge_case)),
+                                    bhp1))
            {
              base_high = CASE_HIGH (merge_case) ?
                  CASE_HIGH (merge_case) : CASE_LOW (merge_case);
@@ -1570,7 +1570,7 @@ replace_uses_by (tree name, tree val)
          size_t i;
 
          fold_stmt_inplace (stmt);
-         if (cfgcleanup_altered_bbs)
+         if (cfgcleanup_altered_bbs && !is_gimple_debug (stmt))
            bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
 
          /* FIXME.  This should go in update_stmt.  */
@@ -2611,13 +2611,13 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       if (!POINTER_TYPE_P (TREE_TYPE (x))
          || !is_gimple_mem_ref_addr (x))
        {
-         error ("Invalid first operand of MEM_REF.");
+         error ("invalid first operand of MEM_REF");
          return x;
        }
       if (TREE_CODE (TREE_OPERAND (t, 1)) != INTEGER_CST
          || !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 1))))
        {
-         error ("Invalid offset operand of MEM_REF.");
+         error ("invalid offset operand of MEM_REF");
          return TREE_OPERAND (t, 1);
        }
       if (TREE_CODE (x) == ADDR_EXPR
@@ -2636,7 +2636,7 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       break;
 
     case MODIFY_EXPR:
-      error ("MODIFY_EXPR not expected while having tuples.");
+      error ("MODIFY_EXPR not expected while having tuples");
       return *tp;
 
     case ADDR_EXPR:
@@ -2783,7 +2783,7 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
                                     TREE_TYPE (TREE_OPERAND (t, 1))))
        {
          error ("invalid operand to pointer plus, second operand is not an "
-                "integer with type of sizetype.");
+                "integer with type of sizetype");
          return t;
        }
       /* FALLTHROUGH */
@@ -2830,6 +2830,14 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
        *walk_subtrees = 0;
       break;
 
+    case CASE_LABEL_EXPR:
+      if (CASE_CHAIN (t))
+       {
+         error ("invalid CASE_CHAIN");
+         return t;
+       }
+      break;
+
     default:
       break;
     }
@@ -2951,14 +2959,14 @@ verify_types_in_gimple_reference (tree expr, bool require_lvalue)
              && (TREE_CODE (op) == SSA_NAME
                  || is_gimple_min_invariant (op)))
            {
-             error ("Conversion of an SSA_NAME on the left hand side.");
+             error ("conversion of an SSA_NAME on the left hand side");
              debug_generic_stmt (expr);
              return true;
            }
          else if (TREE_CODE (op) == SSA_NAME
                   && TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE (op)))
            {
-             error ("Conversion of register to a different size.");
+             error ("conversion of register to a different size");
              debug_generic_stmt (expr);
              return true;
            }
@@ -2973,14 +2981,14 @@ verify_types_in_gimple_reference (tree expr, bool require_lvalue)
     {
       if (!is_gimple_mem_ref_addr (TREE_OPERAND (expr, 0)))
        {
-         error ("Invalid address operand in MEM_REF.");
+         error ("invalid address operand in MEM_REF");
          debug_generic_stmt (expr);
          return true;
        }
       if (TREE_CODE (TREE_OPERAND (expr, 1)) != INTEGER_CST
          || !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1))))
        {
-         error ("Invalid offset operand in MEM_REF.");
+         error ("invalid offset operand in MEM_REF");
          debug_generic_stmt (expr);
          return true;
        }
@@ -2990,14 +2998,14 @@ verify_types_in_gimple_reference (tree expr, bool require_lvalue)
       if (!TMR_BASE (expr)
          || !is_gimple_mem_ref_addr (TMR_BASE (expr)))
        {
-         error ("Invalid address operand in in TARGET_MEM_REF.");
+         error ("invalid address operand in TARGET_MEM_REF");
          return true;
        }
       if (!TMR_OFFSET (expr)
          || TREE_CODE (TMR_OFFSET (expr)) != INTEGER_CST
          || !POINTER_TYPE_P (TREE_TYPE (TMR_OFFSET (expr))))
        {
-         error ("Invalid offset operand in TARGET_MEM_REF.");
+         error ("invalid offset operand in TARGET_MEM_REF");
          debug_generic_stmt (expr);
          return true;
        }
@@ -3044,25 +3052,54 @@ static bool
 verify_gimple_call (gimple stmt)
 {
   tree fn = gimple_call_fn (stmt);
-  tree fntype;
+  tree fntype, fndecl;
   unsigned i;
 
-  if (TREE_CODE (fn) != OBJ_TYPE_REF
-      && !is_gimple_val (fn))
+  if (gimple_call_internal_p (stmt))
+    {
+      if (fn)
+       {
+         error ("gimple call has two targets");
+         debug_generic_stmt (fn);
+         return true;
+       }
+    }
+  else
+    {
+      if (!fn)
+       {
+         error ("gimple call has no target");
+         return true;
+       }
+    }
+
+  if (fn && !is_gimple_call_addr (fn))
     {
       error ("invalid function in gimple call");
       debug_generic_stmt (fn);
       return true;
     }
 
-  if (!POINTER_TYPE_P (TREE_TYPE  (fn))
-      || (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE))
+  if (fn
+      && (!POINTER_TYPE_P (TREE_TYPE (fn))
+         || (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
+             && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE)))
     {
       error ("non-function in gimple call");
       return true;
     }
 
+   fndecl = gimple_call_fndecl (stmt);
+   if (fndecl
+       && TREE_CODE (fndecl) == FUNCTION_DECL
+       && DECL_LOOPING_CONST_OR_PURE_P (fndecl)
+       && !DECL_PURE_P (fndecl)
+       && !TREE_READONLY (fndecl))
+     {
+       error ("invalid pure const state for function");
+       return true;
+     }
+
   if (gimple_call_lhs (stmt)
       && (!is_gimple_lvalue (gimple_call_lhs (stmt))
          || verify_types_in_gimple_reference (gimple_call_lhs (stmt), true)))
@@ -3077,8 +3114,9 @@ verify_gimple_call (gimple stmt)
       return true;
     }
 
-  fntype = TREE_TYPE (TREE_TYPE (fn));
-  if (gimple_call_lhs (stmt)
+  fntype = gimple_call_fntype (stmt);
+  if (fntype
+      && gimple_call_lhs (stmt)
       && !useless_type_conversion_p (TREE_TYPE (gimple_call_lhs (stmt)),
                                     TREE_TYPE (fntype))
       /* ???  At least C++ misses conversions at assignments from
@@ -3116,7 +3154,7 @@ verify_gimple_call (gimple stmt)
 
       if (!DECL_STATIC_CHAIN (fn))
        {
-         error ("static chain with function that doesn't use one");
+         error ("static chain with function that doesn%'t use one");
          return true;
        }
     }
@@ -3136,6 +3174,7 @@ verify_gimple_call (gimple stmt)
        {
          error ("invalid argument to gimple call");
          debug_generic_expr (arg);
+         return true;
        }
     }
 
@@ -3193,9 +3232,7 @@ verify_gimple_assign_unary (gimple stmt)
   tree rhs1 = gimple_assign_rhs1 (stmt);
   tree rhs1_type = TREE_TYPE (rhs1);
 
-  if (!is_gimple_reg (lhs)
-      && !(optimize == 0
-          && TREE_CODE (lhs_type) == COMPLEX_TYPE))
+  if (!is_gimple_reg (lhs))
     {
       error ("non-register as LHS of unary operation");
       return true;
@@ -3313,6 +3350,18 @@ verify_gimple_assign_unary (gimple stmt)
       return false;
 
     case TRUTH_NOT_EXPR:
+      /* We require two-valued operand types.  */
+      if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE
+           || (INTEGRAL_TYPE_P (rhs1_type)
+               && TYPE_PRECISION (rhs1_type) == 1)))
+        {
+         error ("invalid types in truth not");
+         debug_generic_expr (lhs_type);
+         debug_generic_expr (rhs1_type);
+         return true;
+        }
+      break;
+
     case NEGATE_EXPR:
     case ABS_EXPR:
     case BIT_NOT_EXPR:
@@ -3351,9 +3400,7 @@ verify_gimple_assign_binary (gimple stmt)
   tree rhs2 = gimple_assign_rhs2 (stmt);
   tree rhs2_type = TREE_TYPE (rhs2);
 
-  if (!is_gimple_reg (lhs)
-      && !(optimize == 0
-          && TREE_CODE (lhs_type) == COMPLEX_TYPE))
+  if (!is_gimple_reg (lhs))
     {
       error ("non-register as LHS of binary operation");
       return true;
@@ -3508,26 +3555,11 @@ do_pointer_plus_expr_check:
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
-      gcc_unreachable ();
-
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
-      {
-       /* We allow any kind of integral typed argument and result.  */
-       if (!INTEGRAL_TYPE_P (rhs1_type)
-           || !INTEGRAL_TYPE_P (rhs2_type)
-           || !INTEGRAL_TYPE_P (lhs_type))
-         {
-           error ("type mismatch in binary truth expression");
-           debug_generic_expr (lhs_type);
-           debug_generic_expr (rhs1_type);
-           debug_generic_expr (rhs2_type);
-           return true;
-         }
 
-       return false;
-      }
+      gcc_unreachable ();
 
     case LT_EXPR:
     case LE_EXPR:
@@ -3618,9 +3650,7 @@ verify_gimple_assign_ternary (gimple stmt)
   tree rhs3 = gimple_assign_rhs3 (stmt);
   tree rhs3_type = TREE_TYPE (rhs3);
 
-  if (!is_gimple_reg (lhs)
-      && !(optimize == 0
-          && TREE_CODE (lhs_type) == COMPLEX_TYPE))
+  if (!is_gimple_reg (lhs))
     {
       error ("non-register as LHS of ternary operation");
       return true;
@@ -3655,6 +3685,25 @@ verify_gimple_assign_ternary (gimple stmt)
        }
       break;
 
+    case FMA_EXPR:
+      if (!useless_type_conversion_p (lhs_type, rhs1_type)
+         || !useless_type_conversion_p (lhs_type, rhs2_type)
+         || !useless_type_conversion_p (lhs_type, rhs3_type))
+       {
+         error ("type mismatch in fused multiply-add expression");
+         debug_generic_expr (lhs_type);
+         debug_generic_expr (rhs1_type);
+         debug_generic_expr (rhs2_type);
+         debug_generic_expr (rhs3_type);
+         return true;
+       }
+      break;
+
+    case DOT_PROD_EXPR:
+    case REALIGN_LOAD_EXPR:
+      /* FIXME.  */
+      return false;
+
     default:
       gcc_unreachable ();
     }
@@ -3785,10 +3834,7 @@ verify_gimple_assign_single (gimple stmt)
     case OBJ_TYPE_REF:
     case ASSERT_EXPR:
     case WITH_SIZE_EXPR:
-    case POLYNOMIAL_CHREC:
-    case DOT_PROD_EXPR:
     case VEC_COND_EXPR:
-    case REALIGN_LOAD_EXPR:
       /* FIXME.  */
       return res;
 
@@ -3902,46 +3948,6 @@ verify_gimple_switch (gimple stmt)
 }
 
 
-/* Verify the contents of a GIMPLE_PHI.  Returns true if there is a problem,
-   and false otherwise.  */
-
-static bool
-verify_gimple_phi (gimple stmt)
-{
-  tree type = TREE_TYPE (gimple_phi_result (stmt));
-  unsigned i;
-
-  if (TREE_CODE (gimple_phi_result (stmt)) != SSA_NAME)
-    {
-      error ("Invalid PHI result");
-      return true;
-    }
-
-  for (i = 0; i < gimple_phi_num_args (stmt); i++)
-    {
-      tree arg = gimple_phi_arg_def (stmt, i);
-      if ((is_gimple_reg (gimple_phi_result (stmt))
-          && !is_gimple_val (arg))
-         || (!is_gimple_reg (gimple_phi_result (stmt))
-             && !is_gimple_addressable (arg)))
-       {
-         error ("Invalid PHI argument");
-         debug_generic_stmt (arg);
-         return true;
-       }
-      if (!useless_type_conversion_p (type, TREE_TYPE (arg)))
-       {
-         error ("Incompatible types in PHI argument %u", i);
-         debug_generic_stmt (type);
-         debug_generic_stmt (TREE_TYPE (arg));
-         return true;
-       }
-    }
-
-  return false;
-}
-
-
 /* Verify a gimple debug statement STMT.
    Returns true if anything is wrong.  */
 
@@ -3957,12 +3963,48 @@ verify_gimple_debug (gimple stmt ATTRIBUTE_UNUSED)
   return false;
 }
 
+/* Verify a gimple label statement STMT.
+   Returns true if anything is wrong.  */
+
+static bool
+verify_gimple_label (gimple stmt)
+{
+  tree decl = gimple_label_label (stmt);
+  int uid;
+  bool err = false;
+
+  if (TREE_CODE (decl) != LABEL_DECL)
+    return true;
+
+  uid = LABEL_DECL_UID (decl);
+  if (cfun->cfg
+      && (uid == -1
+         || VEC_index (basic_block,
+                       label_to_block_map, uid) != gimple_bb (stmt)))
+    {
+      error ("incorrect entry in label_to_block_map");
+      err |= true;
+    }
+
+  uid = EH_LANDING_PAD_NR (decl);
+  if (uid)
+    {
+      eh_landing_pad lp = get_eh_landing_pad_from_number (uid);
+      if (decl != lp->post_landing_pad)
+       {
+         error ("incorrect setting of landing pad number");
+         err |= true;
+       }
+    }
+
+  return err;
+}
 
 /* Verify the GIMPLE statement STMT.  Returns true if there is an
    error, otherwise false.  */
 
 static bool
-verify_types_in_gimple_stmt (gimple stmt)
+verify_gimple_stmt (gimple stmt)
 {
   switch (gimple_code (stmt))
     {
@@ -3970,7 +4012,7 @@ verify_types_in_gimple_stmt (gimple stmt)
       return verify_gimple_assign (stmt);
 
     case GIMPLE_LABEL:
-      return TREE_CODE (gimple_label_label (stmt)) != LABEL_DECL;
+      return verify_gimple_label (stmt);
 
     case GIMPLE_CALL:
       return verify_gimple_call (stmt);
@@ -4006,9 +4048,6 @@ verify_types_in_gimple_stmt (gimple stmt)
     case GIMPLE_ASM:
       return false;
 
-    case GIMPLE_PHI:
-      return verify_gimple_phi (stmt);
-
     /* Tuples that do not have tree operands.  */
     case GIMPLE_NOP:
     case GIMPLE_PREDICT:
@@ -4034,10 +4073,74 @@ verify_types_in_gimple_stmt (gimple stmt)
     }
 }
 
+/* Verify the contents of a GIMPLE_PHI.  Returns true if there is a problem,
+   and false otherwise.  */
+
+static bool
+verify_gimple_phi (gimple phi)
+{
+  bool err = false;
+  unsigned i;
+  tree phi_result = gimple_phi_result (phi);
+  bool virtual_p;
+
+  if (!phi_result)
+    {
+      error ("invalid PHI result");
+      return true;
+    }
+
+  virtual_p = !is_gimple_reg (phi_result);
+  if (TREE_CODE (phi_result) != SSA_NAME
+      || (virtual_p
+         && SSA_NAME_VAR (phi_result) != gimple_vop (cfun)))
+    {
+      error ("invalid PHI result");
+      err = true;
+    }
+
+  for (i = 0; i < gimple_phi_num_args (phi); i++)
+    {
+      tree t = gimple_phi_arg_def (phi, i);
+
+      if (!t)
+       {
+         error ("missing PHI def");
+         err |= true;
+         continue;
+       }
+      /* Addressable variables do have SSA_NAMEs but they
+        are not considered gimple values.  */
+      else if ((TREE_CODE (t) == SSA_NAME
+               && virtual_p != !is_gimple_reg (t))
+              || (virtual_p
+                  && (TREE_CODE (t) != SSA_NAME
+                      || SSA_NAME_VAR (t) != gimple_vop (cfun)))
+              || (!virtual_p
+                  && !is_gimple_val (t)))
+       {
+         error ("invalid PHI argument");
+         debug_generic_expr (t);
+         err |= true;
+       }
+#ifdef ENABLE_TYPES_CHECKING
+      if (!useless_type_conversion_p (TREE_TYPE (phi_result), TREE_TYPE (t)))
+       {
+         error ("incompatible types in PHI argument %u", i);
+         debug_generic_stmt (TREE_TYPE (phi_result));
+         debug_generic_stmt (TREE_TYPE (t));
+         err |= true;
+       }
+#endif
+    }
+
+  return err;
+}
+
 /* Verify the GIMPLE statements inside the sequence STMTS.  */
 
 static bool
-verify_types_in_gimple_seq_2 (gimple_seq stmts)
+verify_gimple_in_seq_2 (gimple_seq stmts)
 {
   gimple_stmt_iterator ittr;
   bool err = false;
@@ -4049,25 +4152,25 @@ verify_types_in_gimple_seq_2 (gimple_seq stmts)
       switch (gimple_code (stmt))
         {
        case GIMPLE_BIND:
-         err |= verify_types_in_gimple_seq_2 (gimple_bind_body (stmt));
+         err |= verify_gimple_in_seq_2 (gimple_bind_body (stmt));
          break;
 
        case GIMPLE_TRY:
-         err |= verify_types_in_gimple_seq_2 (gimple_try_eval (stmt));
-         err |= verify_types_in_gimple_seq_2 (gimple_try_cleanup (stmt));
+         err |= verify_gimple_in_seq_2 (gimple_try_eval (stmt));
+         err |= verify_gimple_in_seq_2 (gimple_try_cleanup (stmt));
          break;
 
        case GIMPLE_EH_FILTER:
-         err |= verify_types_in_gimple_seq_2 (gimple_eh_filter_failure (stmt));
+         err |= verify_gimple_in_seq_2 (gimple_eh_filter_failure (stmt));
          break;
 
        case GIMPLE_CATCH:
-         err |= verify_types_in_gimple_seq_2 (gimple_catch_handler (stmt));
+         err |= verify_gimple_in_seq_2 (gimple_catch_handler (stmt));
          break;
 
        default:
          {
-           bool err2 = verify_types_in_gimple_stmt (stmt);
+           bool err2 = verify_gimple_stmt (stmt);
            if (err2)
              debug_gimple_stmt (stmt);
            err |= err2;
@@ -4081,102 +4184,15 @@ verify_types_in_gimple_seq_2 (gimple_seq stmts)
 
 /* Verify the GIMPLE statements inside the statement list STMTS.  */
 
-void
-verify_types_in_gimple_seq (gimple_seq stmts)
+DEBUG_FUNCTION void
+verify_gimple_in_seq (gimple_seq stmts)
 {
-  if (verify_types_in_gimple_seq_2 (stmts))
+  timevar_push (TV_TREE_STMT_VERIFY);
+  if (verify_gimple_in_seq_2 (stmts))
     internal_error ("verify_gimple failed");
+  timevar_pop (TV_TREE_STMT_VERIFY);
 }
 
-
-/* Verify STMT, return true if STMT is not in GIMPLE form.
-   TODO: Implement type checking.  */
-
-static bool
-verify_stmt (gimple_stmt_iterator *gsi)
-{
-  tree addr;
-  struct walk_stmt_info wi;
-  bool last_in_block = gsi_one_before_end_p (*gsi);
-  gimple stmt = gsi_stmt (*gsi);
-  int lp_nr;
-
-  if (is_gimple_omp (stmt))
-    {
-      /* OpenMP directives are validated by the FE and never operated
-        on by the optimizers.  Furthermore, GIMPLE_OMP_FOR may contain
-        non-gimple expressions when the main index variable has had
-        its address taken.  This does not affect the loop itself
-        because the header of an GIMPLE_OMP_FOR is merely used to determine
-        how to setup the parallel iteration.  */
-      return false;
-    }
-
-  /* FIXME.  The C frontend passes unpromoted arguments in case it
-     didn't see a function declaration before the call.  */
-  if (is_gimple_call (stmt))
-    {
-      tree decl;
-
-      if (!is_gimple_call_addr (gimple_call_fn (stmt)))
-       {
-         error ("invalid function in call statement");
-         return true;
-       }
-
-      decl = gimple_call_fndecl (stmt);
-      if (decl
-         && TREE_CODE (decl) == FUNCTION_DECL
-         && DECL_LOOPING_CONST_OR_PURE_P (decl)
-         && (!DECL_PURE_P (decl))
-         && (!TREE_READONLY (decl)))
-       {
-         error ("invalid pure const state for function");
-         return true;
-       }
-    }
-
-  if (is_gimple_debug (stmt))
-    return false;
-
-  memset (&wi, 0, sizeof (wi));
-  addr = walk_gimple_op (gsi_stmt (*gsi), verify_expr, &wi);
-  if (addr)
-    {
-      debug_generic_expr (addr);
-      inform (gimple_location (gsi_stmt (*gsi)), "in statement");
-      debug_gimple_stmt (stmt);
-      return true;
-    }
-
-  /* If the statement is marked as part of an EH region, then it is
-     expected that the statement could throw.  Verify that when we
-     have optimizations that simplify statements such that we prove
-     that they cannot throw, that we update other data structures
-     to match.  */
-  lp_nr = lookup_stmt_eh_lp (stmt);
-  if (lp_nr != 0)
-    {
-      if (!stmt_could_throw_p (stmt))
-       {
-         error ("statement marked for throw, but doesn%'t");
-         goto fail;
-       }
-      else if (lp_nr > 0 && !last_in_block && stmt_can_throw_internal (stmt))
-       {
-         error ("statement marked for throw in middle of block");
-         goto fail;
-       }
-    }
-
-  return false;
-
- fail:
-  debug_gimple_stmt (stmt);
-  return true;
-}
-
-
 /* Return true when the T can be shared.  */
 
 bool
@@ -4205,7 +4221,6 @@ tree_node_can_be_shared (tree t)
   return false;
 }
 
-
 /* Called via walk_gimple_stmt.  Verify tree sharing.  */
 
 static tree
@@ -4226,7 +4241,6 @@ verify_node_sharing (tree *tp, int *walk_subtrees, void *data)
   return NULL;
 }
 
-
 static bool eh_error_found;
 static int
 verify_eh_throw_stmt_node (void **slot, void *data)
@@ -4236,154 +4250,131 @@ verify_eh_throw_stmt_node (void **slot, void *data)
 
   if (!pointer_set_contains (visited, node->stmt))
     {
-      error ("Dead STMT in EH table");
+      error ("dead STMT in EH table");
       debug_gimple_stmt (node->stmt);
       eh_error_found = true;
     }
   return 1;
 }
 
-
-/* Verify the GIMPLE statements in every basic block.  */
+/* Verify the GIMPLE statements in the CFG of FN.  */
 
 DEBUG_FUNCTION void
-verify_stmts (void)
+verify_gimple_in_cfg (struct function *fn)
 {
   basic_block bb;
-  gimple_stmt_iterator gsi;
   bool err = false;
   struct pointer_set_t *visited, *visited_stmts;
-  tree addr;
-  struct walk_stmt_info wi;
 
   timevar_push (TV_TREE_STMT_VERIFY);
   visited = pointer_set_create ();
   visited_stmts = pointer_set_create ();
 
-  memset (&wi, 0, sizeof (wi));
-  wi.info = (void *) visited;
-
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, fn)
     {
-      gimple phi;
-      size_t i;
+      gimple_stmt_iterator gsi;
 
       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         phi = gsi_stmt (gsi);
+         gimple phi = gsi_stmt (gsi);
+         bool err2 = false;
+         unsigned i;
+
          pointer_set_insert (visited_stmts, phi);
+
          if (gimple_bb (phi) != bb)
            {
              error ("gimple_bb (phi) is set to a wrong basic block");
-             err |= true;
+             err= true;
            }
 
+         err2 |= verify_gimple_phi (phi);
+
          for (i = 0; i < gimple_phi_num_args (phi); i++)
            {
-             tree t = gimple_phi_arg_def (phi, i);
-             tree addr;
-
-             if (!t)
-               {
-                 error ("missing PHI def");
-                 debug_gimple_stmt (phi);
-                 err |= true;
-                 continue;
-               }
-             /* Addressable variables do have SSA_NAMEs but they
-                are not considered gimple values.  */
-             else if (TREE_CODE (t) != SSA_NAME
-                      && TREE_CODE (t) != FUNCTION_DECL
-                      && !is_gimple_min_invariant (t))
-               {
-                 error ("PHI argument is not a GIMPLE value");
-                 debug_gimple_stmt (phi);
-                 debug_generic_expr (t);
-                 err |= true;
-               }
-
-             addr = walk_tree (&t, verify_node_sharing, visited, NULL);
+             tree arg = gimple_phi_arg_def (phi, i);
+             tree addr = walk_tree (&arg, verify_node_sharing, visited, NULL);
              if (addr)
                {
                  error ("incorrect sharing of tree nodes");
-                 debug_gimple_stmt (phi);
                  debug_generic_expr (addr);
-                 err |= true;
+                 err2 |= true;
                }
            }
 
-#ifdef ENABLE_TYPES_CHECKING
-         if (verify_gimple_phi (phi))
-           {
-             debug_gimple_stmt (phi);
-             err |= true;
-           }
-#endif
+         if (err2)
+           debug_gimple_stmt (phi);
+         err |= err2;
        }
 
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
          gimple stmt = gsi_stmt (gsi);
-
-         if (gimple_code (stmt) == GIMPLE_WITH_CLEANUP_EXPR
-             || gimple_code (stmt) == GIMPLE_BIND)
-           {
-             error ("invalid GIMPLE statement");
-             debug_gimple_stmt (stmt);
-             err |= true;
-           }
+         bool err2 = false;
+         struct walk_stmt_info wi;
+         tree addr;
+         int lp_nr;
 
          pointer_set_insert (visited_stmts, stmt);
 
          if (gimple_bb (stmt) != bb)
            {
              error ("gimple_bb (stmt) is set to a wrong basic block");
-             debug_gimple_stmt (stmt);
-             err |= true;
+             err2 = true;
            }
 
-         if (gimple_code (stmt) == GIMPLE_LABEL)
+         err2 |= verify_gimple_stmt (stmt);
+
+         memset (&wi, 0, sizeof (wi));
+         wi.info = (void *) visited;
+         addr = walk_gimple_op (stmt, verify_node_sharing, &wi);
+         if (addr)
            {
-             tree decl = gimple_label_label (stmt);
-             int uid = LABEL_DECL_UID (decl);
+             error ("incorrect sharing of tree nodes");
+             debug_generic_expr (addr);
+             err2 |= true;
+           }
 
-             if (uid == -1
-                 || VEC_index (basic_block, label_to_block_map, uid) != bb)
+         /* ???  Instead of not checking these stmts at all the walker
+            should know its context via wi.  */
+         if (!is_gimple_debug (stmt)
+             && !is_gimple_omp (stmt))
+           {
+             memset (&wi, 0, sizeof (wi));
+             addr = walk_gimple_op (stmt, verify_expr, &wi);
+             if (addr)
                {
-                 error ("incorrect entry in label_to_block_map");
-                 err |= true;
+                 debug_generic_expr (addr);
+                 inform (gimple_location (stmt), "in statement");
+                 err2 |= true;
                }
+           }
 
-             uid = EH_LANDING_PAD_NR (decl);
-             if (uid)
+         /* If the statement is marked as part of an EH region, then it is
+            expected that the statement could throw.  Verify that when we
+            have optimizations that simplify statements such that we prove
+            that they cannot throw, that we update other data structures
+            to match.  */
+         lp_nr = lookup_stmt_eh_lp (stmt);
+         if (lp_nr != 0)
+           {
+             if (!stmt_could_throw_p (stmt))
                {
-                 eh_landing_pad lp = get_eh_landing_pad_from_number (uid);
-                 if (decl != lp->post_landing_pad)
-                   {
-                     error ("incorrect setting of landing pad number");
-                     err |= true;
-                   }
+                 error ("statement marked for throw, but doesn%'t");
+                 err2 |= true;
+               }
+             else if (lp_nr > 0
+                      && !gsi_one_before_end_p (gsi)
+                      && stmt_can_throw_internal (stmt))
+               {
+                 error ("statement marked for throw in middle of block");
+                 err2 |= true;
                }
            }
 
-         err |= verify_stmt (&gsi);
-
-#ifdef ENABLE_TYPES_CHECKING
-         if (verify_types_in_gimple_stmt (gsi_stmt (gsi)))
-           {
-             debug_gimple_stmt (stmt);
-             err |= true;
-           }
-#endif
-         addr = walk_gimple_op (gsi_stmt (gsi), verify_node_sharing, &wi);
-         if (addr)
-           {
-             error ("incorrect sharing of tree nodes");
-             debug_gimple_stmt (stmt);
-             debug_generic_expr (addr);
-             err |= true;
-           }
-         gsi_next (&gsi);
+         if (err2)
+           debug_gimple_stmt (stmt);
+         err |= err2;
        }
     }
 
@@ -4393,8 +4384,8 @@ verify_stmts (void)
                   verify_eh_throw_stmt_node,
                   visited_stmts);
 
-  if (err | eh_error_found)
-    internal_error ("verify_stmts failed");
+  if (err || eh_error_found)
+    internal_error ("verify_gimple failed");
 
   pointer_set_destroy (visited);
   pointer_set_destroy (visited_stmts);
@@ -4886,7 +4877,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
              {
                last = cases;
                CASE_LABEL (cases) = label;
-               cases = TREE_CHAIN (cases);
+               cases = CASE_CHAIN (cases);
              }
 
            /* If there was already an edge in the CFG, then we need
@@ -4895,8 +4886,8 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
              {
                tree cases2 = get_cases_for_edge (e2, stmt);
 
-               TREE_CHAIN (last) = TREE_CHAIN (cases2);
-               TREE_CHAIN (cases2) = first;
+               CASE_CHAIN (last) = CASE_CHAIN (cases2);
+               CASE_CHAIN (cases2) = first;
              }
            bitmap_set_bit (touched_switch_bbs, gimple_bb (stmt)->index);
          }
@@ -5771,7 +5762,7 @@ move_stmt_eh_region_tree_nr (tree old_t_nr, struct move_stmt_d *p)
   old_nr = tree_low_cst (old_t_nr, 0);
   new_nr = move_stmt_eh_region_nr (old_nr, p);
 
-  return build_int_cst (NULL, new_nr);
+  return build_int_cst (integer_type_node, new_nr);
 }
 
 /* Like move_stmt_op, but for gimple statements.
@@ -6749,7 +6740,7 @@ gimple_flow_call_edges_add (sbitmap blocks)
   if (check_last_block)
     {
       basic_block bb = EXIT_BLOCK_PTR->prev_bb;
-      gimple_stmt_iterator gsi = gsi_last_bb (bb);
+      gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
       gimple t = NULL;
 
       if (!gsi_end_p (gsi))
@@ -6783,7 +6774,7 @@ gimple_flow_call_edges_add (sbitmap blocks)
       if (blocks && !TEST_BIT (blocks, i))
        continue;
 
-      gsi = gsi_last_bb (bb);
+      gsi = gsi_last_nondebug_bb (bb);
       if (!gsi_end_p (gsi))
        {
          last_stmt = gsi_stmt (gsi);
@@ -7164,15 +7155,16 @@ struct cfg_hooks gimple_cfg_hooks = {
   gimple_can_merge_blocks_p,   /* can_merge_blocks_p  */
   gimple_merge_blocks,         /* merge_blocks  */
   gimple_predict_edge,         /* predict_edge  */
-  gimple_predicted_by_p,               /* predicted_by_p  */
+  gimple_predicted_by_p,       /* predicted_by_p  */
   gimple_can_duplicate_bb_p,   /* can_duplicate_block_p  */
   gimple_duplicate_bb,         /* duplicate_block  */
   gimple_split_edge,           /* split_edge  */
   gimple_make_forwarder_block, /* make_forward_block  */
   NULL,                                /* tidy_fallthru_edge  */
+  NULL,                                /* force_nonfallthru */
   gimple_block_ends_with_call_p,/* block_ends_with_call_p */
   gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
-  gimple_flow_call_edges_add,     /* flow_call_edges_add */
+  gimple_flow_call_edges_add,   /* flow_call_edges_add */
   gimple_execute_on_growing_pred,      /* execute_on_growing_pred */
   gimple_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
   gimple_duplicate_loop_to_header_edge, /* duplicate loop for trees */
@@ -7470,12 +7462,14 @@ do_warn_unused_result (gimple_seq seq)
        case GIMPLE_CALL:
          if (gimple_call_lhs (g))
            break;
+         if (gimple_call_internal_p (g))
+           break;
 
          /* This is a naked call, as opposed to a GIMPLE_CALL with an
             LHS.  All calls whose value is ignored should be
             represented like this.  Look for the attribute.  */
          fdecl = gimple_call_fndecl (g);
-         ftype = TREE_TYPE (TREE_TYPE (gimple_call_fn (g)));
+         ftype = gimple_call_fntype (g);
 
          if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
            {