This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] verify_stmts
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, dnovillo at redhat dot com, rth at redhat dot com
- Date: Tue, 25 Nov 2003 17:17:06 +0100
- Subject: [tree-ssa] verify_stmts
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 */