[tree-ssa] verify_stmts

Jan Hubicka jh@suse.cz
Tue Nov 25 16:56:00 GMT 2003


Hi,
here is updated verify_stmts patch.  Now with the duplication code in it
passes until mustalias is executed and I hope we agree on fixing the
mustalias wrt non-trivial ADDR_EXPRs problem soon, so I will be able to
enable at the end of compilation too.

verify_stmts seems to be relatively cheap, but for consistency I am
enabling it at two places right now only.  I guess we will work out how
many times it should be called sooner or later.

Bootstrapped/regtested i686-pc-gnu-linux. OK?

Honza

2003-11-25  Jan Hubicka  <jh@suse.cz>
	* tree-cfg.c (verify_addr_expr, verify_stmt, tree_node_shared_p, verify_stmts):  New functions.
	* tree-flow.h (verify_stmt, verify_stmts): Declare.
	* tree-inline.h (walk_tree, walk_tree_without_duplicates): Move prototypes ...
	* tree.h (walk_tree, walk_tree_without_duplicates): ... here.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.225
diff -c -3 -p -r1.1.4.225 tree-cfg.c
*** tree-cfg.c	25 Nov 2003 05:09:07 -0000	1.1.4.225
--- tree-cfg.c	25 Nov 2003 16:03:38 -0000
*************** has_label_p (basic_block bb, tree label)
*** 2881,2886 ****
--- 2881,3048 ----
    return false;
  }
  
+ /* Callback for walk_tree, check that all elements with address taken are
+    properly noticed as such.  */
+ 
+ static tree
+ verify_addr_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ 		  void *data ATTRIBUTE_UNUSED)
+ {
+   if (TREE_CODE (*tp) == ADDR_EXPR)
+     {
+       tree x = TREE_OPERAND (*tp, 0);
+       while (TREE_CODE (x) == ARRAY_REF
+ 	     || TREE_CODE (x) == COMPONENT_REF
+ 	     || TREE_CODE (x) == REALPART_EXPR
+ 	     || TREE_CODE (x) == IMAGPART_EXPR)
+ 	x = TREE_OPERAND (x, 0);
+       if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+ 	return NULL;
+       if (!TREE_ADDRESSABLE (x))
+         return x;
+     }
+   return NULL;
+ }
+ 
+ /* Verify the STMT, return true if STMT is missformed.
+    Always keep global so it can be called via GDB. 
+ 
+    TODO: Implement type checking.  */
+ bool
+ verify_stmt (tree stmt)
+ {
+   tree addr;
+ 
+   if (!is_gimple_stmt (stmt))
+     {
+       error ("Is not valid gimple statement.");
+       debug_generic_stmt (stmt);
+       return true;
+     }
+   addr = walk_tree (&stmt, verify_addr_expr, NULL, NULL);
+   if (addr)
+     {
+       error ("Address taken, but ADDRESABLE bit not set");
+       debug_generic_stmt (addr);
+       return true;
+     }
+   return false;
+ }
+ 
+ /* Return true when the T can be shared.  */
+ static bool
+ tree_node_shared_p (tree t)
+ {
+   if (TYPE_P (t) || DECL_P (t)
+       || is_gimple_min_invariant (t)
+       || TREE_CODE (t) == SSA_NAME)
+     return true;
+   while ((TREE_CODE (t) == ARRAY_REF
+           && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+ 	 || (TREE_CODE (t) == COMPONENT_REF
+ 	     || TREE_CODE (t) == REALPART_EXPR
+ 	     || TREE_CODE (t) == IMAGPART_EXPR))
+     t = TREE_OPERAND (t, 0);
+   if (DECL_P (t))
+     return true;
+   return false;
+ }
+ 
+ /* Called via walk_trees.  Verify tree sharing.  */
+ static tree
+ verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
+ {
+   htab_t htab = (htab_t) data;
+   void **slot;
+ 
+   if (tree_node_shared_p (*tp))
+     {
+       *walk_subtrees = false;
+       return NULL;
+     }
+   slot = htab_find_slot (htab, *tp, INSERT);
+   if (*slot)
+     return *slot;
+   *slot = *tp;
+   return NULL;
+ }
+ 
+ 
+ /* Verify GIMPLE stmt chain.  */
+ void
+ verify_stmts (void)
+ {
+   basic_block bb;
+   block_stmt_iterator bsi;
+   bool err = false;
+   htab_t htab;
+   tree addr;
+ 
+   htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+ 
+   FOR_EACH_BB (bb)
+     {
+       tree phi;
+       int i;
+ 
+       phi = phi_nodes (bb);
+       for (; phi; phi = TREE_CHAIN (phi))
+ 	{
+ 	  int phi_num_args = PHI_NUM_ARGS (phi);
+ 
+ 	  for (i = 0; i < phi_num_args; i++)
+ 	    {
+ 	      tree t = PHI_ARG_DEF (phi, i);
+ 	      tree addr;
+ 
+ 	      /* Addressable variables do have SSA_NAMEs but they
+ 	         are not considered gimple values.  */
+ 	      if (TREE_CODE (t) != SSA_NAME
+ 		  && TREE_CODE (t) != FUNCTION_DECL
+ 		  && !is_gimple_val (t))
+ 		{
+ 		  error ("PHI def is not GIMPLE value");
+ 		  debug_generic_stmt (phi);
+ 		  debug_generic_stmt (t);
+ 		  err |= true;
+ 		}
+ 	      addr = walk_tree (&t, verify_addr_expr, NULL, NULL);
+ 	      if (addr)
+ 		{
+ 		  error ("Address taken, but ADDRESABLE bit not set");
+ 		  debug_generic_stmt (addr);
+ 		  err |= true;
+ 		}
+ 	      addr = walk_tree (&t, verify_node_sharing, htab, NULL);
+ 	      if (addr)
+ 		{
+ 		  error ("Wrong sharing of tree nodes");
+ 		  debug_generic_stmt (phi);
+ 		  debug_generic_stmt (addr);
+ 		  err |= true;
+ 		}
+ 	    }
+ 	}
+       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ 	{
+ 	  tree stmt = bsi_stmt (bsi);
+ 	  err |= verify_stmt (stmt);
+ 	  addr = walk_tree (&stmt, verify_node_sharing, htab, NULL);
+ 	  if (addr)
+ 	    {
+ 	      error ("Wrong sharing of tree nodes");
+ 	      debug_generic_stmt (stmt);
+ 	      debug_generic_stmt (addr);
+ 	      err |= true;
+ 	    }
+ 	}
+     }
+   if (err)
+     internal_error ("verify_stmts failed.");
+   htab_delete (htab);
+ }
+ 
+ 
  /* Verifies that the flow information is OK.  */
  
  static int
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.160
diff -c -3 -p -r1.1.4.160 tree-flow.h
*** tree-flow.h	25 Nov 2003 05:09:08 -0000	1.1.4.160
--- tree-flow.h	25 Nov 2003 16:03:38 -0000
*************** extern void bsi_insert_on_edge_immediate
*** 446,451 ****
--- 446,453 ----
  extern void notice_special_calls (tree);
  extern void clear_special_calls (void);
  extern void compute_dominance_frontiers (bitmap *, dominance_info);
+ extern bool verify_stmt (tree);
+ extern void verify_stmts (void);
  
  /* In tree-pretty-print.c.  */
  extern void dump_generic_bb (FILE *, basic_block, int, int);
Index: tree-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.h,v
retrieving revision 1.4.2.5
diff -c -3 -p -r1.4.2.5 tree-inline.h
*** tree-inline.h	25 Nov 2003 14:18:43 -0000	1.4.2.5
--- tree-inline.h	25 Nov 2003 16:03:38 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 26,33 ****
  
  void optimize_inline_calls (tree);
  bool tree_inlinable_function_p (tree);
- tree walk_tree (tree*, walk_tree_fn, void*, void*);
- tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
  tree copy_tree_r (tree*, int*, void*);
  void clone_body (tree, tree, void*);
  tree save_body (tree, tree *);
--- 26,31 ----
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.79
diff -c -3 -p -r1.1.4.79 tree-optimize.c
*** tree-optimize.c	25 Nov 2003 14:18:43 -0000	1.1.4.79
--- tree-optimize.c	25 Nov 2003 16:03:39 -0000
*************** optimize_function_tree (tree fndecl, tre
*** 72,77 ****
--- 72,81 ----
      {
        sbitmap vars_to_rename;
  
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+ #endif
+ 
        /* Initialize common SSA structures.  */
        init_tree_ssa ();
  
*************** optimize_function_tree (tree fndecl, tre
*** 120,125 ****
--- 124,132 ----
  #if 0
        /* Eliminate tail recursion calls.  */
        tree_optimize_tail_calls (false, TDI_tail1);
+ #endif
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
  #endif
  
        /* The must-alias pass removes the aliasing and addressability bits
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.139
diff -c -3 -p -r1.342.2.139 tree.h
*** tree.h	25 Nov 2003 02:09:56 -0000	1.342.2.139
--- tree.h	25 Nov 2003 16:03:39 -0000
*************** extern void dwarf2out_return_reg (const 
*** 3549,3554 ****
--- 3549,3556 ----
  /* The type of a callback function for walking over tree structure.  */
  
  typedef tree (*walk_tree_fn) (tree *, int *, void *);
+ tree walk_tree (tree*, walk_tree_fn, void*, void*);
+ tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
  
  /* In tree-dump.c */
  



More information about the Gcc-patches mailing list