This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Baby-step for cleaning up the gimple verifier(s)


This merges the machinery for verify_stmts and verify_types_in_gimple_*.
A step in the direction to merge the various verifications we do
on gimple.  A further step would move the calls to verify_expr to
appropriate places when verifying stmts instead of walking all ops.

The goal is still that the core verifiers work on all forms of gimple,
properly guarding/extending parts with IL properties is also on the
list of things to do.  So is dropping conditionalizing/separating
type checking.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-03-25  Richard Guenther  <rguenther@suse.de>

	* tree-flow.h (verify_stmts): Rename to verify_gimple_in_cfg.
	(verify_types_in_gimple_seq): Rename to verify_gimple_in_seq.
	(verify_gimple): Remove.
	* tree-cfg.c (verify_gimple_call): Merge verification
	from verify_stmts.
	(verify_gimple_phi): Merge verification from verify_stmts.
	(verify_gimple_label): New function.
	(verify_types_in_gimple_seq_2): Rename to verify_gimple_in_seq_2.
	(verify_types_in_gimple_seq): Rename to verify_gimple_in_seq.
	(verify_stmt): Merge into verify_gimple_in_cfg and callees.
	(verify_stmts): Rename to verify_gimple_in_cfg.
	(verify_gimple_in_cfg): New function.
	* passes.c (execute_function_todo): Call verify_gimple_in_cfg.
	* tree-ssa.c (verify_ssa): Likewise.
	* gimplify.c (gimplify_body): Call verify_gimple_in_seq.

Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h.orig	2011-03-25 13:02:20.000000000 +0100
--- gcc/tree-flow.h	2011-03-25 13:07:55.000000000 +0100
*************** extern basic_block label_to_block_fn (st
*** 426,434 ****
  #define label_to_block(t) (label_to_block_fn (cfun, t))
  extern void notice_special_calls (gimple);
  extern void clear_special_calls (void);
! extern void verify_stmts (void);
! extern void verify_gimple (void);
! extern void verify_types_in_gimple_seq (gimple_seq);
  extern tree gimple_block_label (basic_block);
  extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
  extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
--- 426,433 ----
  #define label_to_block(t) (label_to_block_fn (cfun, t))
  extern void notice_special_calls (gimple);
  extern void clear_special_calls (void);
! extern void verify_gimple_in_seq (gimple_seq);
! extern void verify_gimple_in_cfg (struct function *);
  extern tree gimple_block_label (basic_block);
  extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
  extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2011-03-25 13:02:20.000000000 +0100
--- gcc/tree-cfg.c	2011-03-25 14:39:27.000000000 +0100
*************** static bool
*** 3116,3126 ****
  verify_gimple_call (gimple stmt)
  {
    tree fn = gimple_call_fn (stmt);
!   tree fntype;
    unsigned i;
  
!   if (TREE_CODE (fn) != OBJ_TYPE_REF
!       && !is_gimple_val (fn))
      {
        error ("invalid function in gimple call");
        debug_generic_stmt (fn);
--- 3116,3125 ----
  verify_gimple_call (gimple stmt)
  {
    tree fn = gimple_call_fn (stmt);
!   tree fntype, fndecl;
    unsigned i;
  
!   if (!is_gimple_call_addr (fn))
      {
        error ("invalid function in gimple call");
        debug_generic_stmt (fn);
*************** verify_gimple_call (gimple stmt)
*** 3135,3140 ****
--- 3134,3150 ----
        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)))
*************** verify_gimple_switch (gimple stmt)
*** 3985,4030 ****
  }
  
  
- /* 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.  */
  
--- 3995,4000 ----
*************** verify_gimple_debug (gimple stmt ATTRIBU
*** 4040,4051 ****
    return false;
  }
  
  
  /* Verify the GIMPLE statement STMT.  Returns true if there is an
     error, otherwise false.  */
  
  static bool
! verify_types_in_gimple_stmt (gimple stmt)
  {
    switch (gimple_code (stmt))
      {
--- 4010,4057 ----
    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_gimple_stmt (gimple stmt)
  {
    switch (gimple_code (stmt))
      {
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4053,4059 ****
        return verify_gimple_assign (stmt);
  
      case GIMPLE_LABEL:
!       return TREE_CODE (gimple_label_label (stmt)) != LABEL_DECL;
  
      case GIMPLE_CALL:
        return verify_gimple_call (stmt);
--- 4059,4065 ----
        return verify_gimple_assign (stmt);
  
      case GIMPLE_LABEL:
!       return verify_gimple_label (stmt);
  
      case GIMPLE_CALL:
        return verify_gimple_call (stmt);
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4089,4097 ****
      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:
--- 4095,4100 ----
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4117,4126 ****
      }
  }
  
  /* Verify the GIMPLE statements inside the sequence STMTS.  */
  
  static bool
! verify_types_in_gimple_seq_2 (gimple_seq stmts)
  {
    gimple_stmt_iterator ittr;
    bool err = false;
--- 4120,4193 ----
      }
  }
  
+ /* 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_gimple_in_seq_2 (gimple_seq stmts)
  {
    gimple_stmt_iterator ittr;
    bool err = false;
*************** verify_types_in_gimple_seq_2 (gimple_seq
*** 4132,4156 ****
        switch (gimple_code (stmt))
          {
  	case GIMPLE_BIND:
! 	  err |= verify_types_in_gimple_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));
  	  break;
  
  	case GIMPLE_EH_FILTER:
! 	  err |= verify_types_in_gimple_seq_2 (gimple_eh_filter_failure (stmt));
  	  break;
  
  	case GIMPLE_CATCH:
! 	  err |= verify_types_in_gimple_seq_2 (gimple_catch_handler (stmt));
  	  break;
  
  	default:
  	  {
! 	    bool err2 = verify_types_in_gimple_stmt (stmt);
  	    if (err2)
  	      debug_gimple_stmt (stmt);
  	    err |= err2;
--- 4199,4223 ----
        switch (gimple_code (stmt))
          {
  	case GIMPLE_BIND:
! 	  err |= verify_gimple_in_seq_2 (gimple_bind_body (stmt));
  	  break;
  
  	case GIMPLE_TRY:
! 	  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_gimple_in_seq_2 (gimple_eh_filter_failure (stmt));
  	  break;
  
  	case GIMPLE_CATCH:
! 	  err |= verify_gimple_in_seq_2 (gimple_catch_handler (stmt));
  	  break;
  
  	default:
  	  {
! 	    bool err2 = verify_gimple_stmt (stmt);
  	    if (err2)
  	      debug_gimple_stmt (stmt);
  	    err |= err2;
*************** verify_types_in_gimple_seq_2 (gimple_seq
*** 4164,4265 ****
  
  /* Verify the GIMPLE statements inside the statement list STMTS.  */
  
! void
! verify_types_in_gimple_seq (gimple_seq stmts)
  {
!   if (verify_types_in_gimple_seq_2 (stmts))
      internal_error ("verify_gimple failed");
  }
  
- 
- /* 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
--- 4231,4245 ----
  
  /* Verify the GIMPLE statements inside the statement list STMTS.  */
  
! DEBUG_FUNCTION void
! verify_gimple_in_seq (gimple_seq 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);
  }
  
  /* Return true when the T can be shared.  */
  
  bool
*************** tree_node_can_be_shared (tree t)
*** 4288,4294 ****
    return false;
  }
  
- 
  /* Called via walk_gimple_stmt.  Verify tree sharing.  */
  
  static tree
--- 4268,4273 ----
*************** verify_node_sharing (tree *tp, int *walk
*** 4309,4315 ****
    return NULL;
  }
  
- 
  static bool eh_error_found;
  static int
  verify_eh_throw_stmt_node (void **slot, void *data)
--- 4288,4293 ----
*************** verify_eh_throw_stmt_node (void **slot,
*** 4326,4472 ****
    return 1;
  }
  
! 
! /* Verify the GIMPLE statements in every basic block.  */
  
  DEBUG_FUNCTION void
! verify_stmts (void)
  {
    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)
      {
!       gimple phi;
!       size_t i;
  
        for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
  	{
! 	  phi = gsi_stmt (gsi);
  	  pointer_set_insert (visited_stmts, phi);
  	  if (gimple_bb (phi) != bb)
  	    {
  	      error ("gimple_bb (phi) is set to a wrong basic block");
! 	      err |= true;
  	    }
  
  	  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);
  	      if (addr)
  		{
  		  error ("incorrect sharing of tree nodes");
- 		  debug_gimple_stmt (phi);
  		  debug_generic_expr (addr);
! 		  err |= true;
  		}
  	    }
  
! #ifdef ENABLE_TYPES_CHECKING
! 	  if (verify_gimple_phi (phi))
! 	    {
! 	      debug_gimple_stmt (phi);
! 	      err |= true;
! 	    }
! #endif
  	}
  
!       for (gsi = gsi_start_bb (bb); !gsi_end_p (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;
! 	    }
  
  	  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;
  	    }
  
! 	  if (gimple_code (stmt) == GIMPLE_LABEL)
  	    {
! 	      tree decl = gimple_label_label (stmt);
! 	      int uid = LABEL_DECL_UID (decl);
  
! 	      if (uid == -1
! 		  || VEC_index (basic_block, label_to_block_map, uid) != bb)
  		{
! 		  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;
! 		    }
  		}
  	    }
  
! 	  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);
  	}
      }
  
--- 4304,4427 ----
    return 1;
  }
  
! /* Verify the GIMPLE statements in the CFG of FN.  */
  
  DEBUG_FUNCTION void
! verify_gimple_in_cfg (struct function *fn)
  {
    basic_block bb;
    bool err = false;
    struct pointer_set_t *visited, *visited_stmts;
  
    timevar_push (TV_TREE_STMT_VERIFY);
    visited = pointer_set_create ();
    visited_stmts = pointer_set_create ();
  
!   FOR_EACH_BB_FN (bb, fn)
      {
!       gimple_stmt_iterator gsi;
  
        for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&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");
! 	      err2 = true;
  	    }
  
+ 	  err2 |= verify_gimple_phi (phi);
+ 
  	  for (i = 0; i < gimple_phi_num_args (phi); i++)
  	    {
! 	      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_generic_expr (addr);
! 		  err2 |= true;
  		}
  	    }
  
! 	  if (err2)
! 	    debug_gimple_stmt (phi);
! 	  err |= err2;
  	}
  
!       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
  	{
  	  gimple stmt = gsi_stmt (gsi);
! 	  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");
! 	      err2 = true;
  	    }
  
! 	  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)
  	    {
! 	      error ("incorrect sharing of tree nodes");
! 	      debug_generic_expr (addr);
! 	      err2 |= true;
! 	    }
  
! 	  /* ???  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)
  		{
! 		  debug_generic_expr (addr);
! 		  inform (gimple_location (stmt), "in statement");
! 		  err2 |= 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");
! 		  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;
  		}
  	    }
  
! 	  if (err2)
! 	    debug_gimple_stmt (stmt);
! 	  err |= err2;
  	}
      }
  
*************** verify_stmts (void)
*** 4476,4483 ****
  		   verify_eh_throw_stmt_node,
  		   visited_stmts);
  
!   if (err | eh_error_found)
!     internal_error ("verify_stmts failed");
  
    pointer_set_destroy (visited);
    pointer_set_destroy (visited_stmts);
--- 4431,4438 ----
  		   verify_eh_throw_stmt_node,
  		   visited_stmts);
  
!   if (err || eh_error_found)
!     internal_error ("verify_gimple failed");
  
    pointer_set_destroy (visited);
    pointer_set_destroy (visited_stmts);
*************** verify_stmts (void)
*** 4486,4491 ****
--- 4441,4447 ----
  }
  
  
+ 
  /* Verifies that the flow information is OK.  */
  
  static int
Index: gcc/passes.c
===================================================================
*** gcc/passes.c.orig	2011-03-25 13:02:36.000000000 +0100
--- gcc/passes.c	2011-03-25 13:07:55.000000000 +0100
*************** execute_function_todo (void *data)
*** 1240,1246 ****
    if (flags & TODO_verify_flow)
      verify_flow_info ();
    if (flags & TODO_verify_stmts)
!     verify_stmts ();
    if (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA))
      verify_loop_closed_ssa (false);
    if (flags & TODO_verify_rtl_sharing)
--- 1240,1246 ----
    if (flags & TODO_verify_flow)
      verify_flow_info ();
    if (flags & TODO_verify_stmts)
!     verify_gimple_in_cfg (cfun);
    if (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA))
      verify_loop_closed_ssa (false);
    if (flags & TODO_verify_rtl_sharing)
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c.orig	2011-03-25 13:02:20.000000000 +0100
--- gcc/tree-ssa.c	2011-03-25 13:07:55.000000000 +0100
*************** verify_ssa (bool check_modified_stmt)
*** 881,887 ****
  
    gcc_assert (!need_ssa_update_p (cfun));
  
!   verify_stmts ();
  
    timevar_push (TV_TREE_SSA_VERIFY);
  
--- 881,887 ----
  
    gcc_assert (!need_ssa_update_p (cfun));
  
!   verify_gimple_in_cfg (cfun);
  
    timevar_push (TV_TREE_SSA_VERIFY);
  
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2011-03-25 13:02:20.000000000 +0100
--- gcc/gimplify.c	2011-03-25 13:07:55.000000000 +0100
*************** gimplify_body (tree *body_p, tree fndecl
*** 7769,7778 ****
    pop_gimplify_context (outer_bind);
    gcc_assert (gimplify_ctxp == NULL);
  
- #ifdef ENABLE_TYPES_CHECKING
    if (!seen_error ())
!     verify_types_in_gimple_seq (gimple_bind_body (outer_bind));
! #endif
  
    timevar_pop (TV_TREE_GIMPLIFY);
    input_location = saved_location;
--- 7769,7776 ----
    pop_gimplify_context (outer_bind);
    gcc_assert (gimplify_ctxp == NULL);
  
    if (!seen_error ())
!     verify_gimple_in_seq (gimple_bind_body (outer_bind));
  
    timevar_pop (TV_TREE_GIMPLIFY);
    input_location = saved_location;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]