Commit 7bb01996 by Richard Biener Committed by Richard Biener

tree-cfg.c (verify_expr_location, [...]): New functions.

2013-01-14  Richard Biener  <rguenther@suse.de>

	* tree-cfg.c (verify_expr_location, verify_expr_location_1,
	verify_location, collect_subblocks): New functions.
	(verify_gimple_in_cfg): Verify that locations only reference
	BLOCKs in the functions BLOCK tree.

From-SVN: r195147
parent 30b2fc65
2013-01-14 Richard Biener <rguenther@suse.de> 2013-01-14 Richard Biener <rguenther@suse.de>
* tree-cfg.c (verify_expr_location, verify_expr_location_1,
verify_location, collect_subblocks): New functions.
(verify_gimple_in_cfg): Verify that locations only reference
BLOCKs in the functions BLOCK tree.
2013-01-14 Richard Biener <rguenther@suse.de>
* tree-cfgcleanup.c (remove_forwarder_block): Unshare propagated * tree-cfgcleanup.c (remove_forwarder_block): Unshare propagated
PHI argument. PHI argument.
* graphite-sese-to-poly.c (insert_out_of_ssa_copy): Properly * graphite-sese-to-poly.c (insert_out_of_ssa_copy): Properly
......
...@@ -4499,6 +4499,63 @@ verify_eh_throw_stmt_node (void **slot, void *data) ...@@ -4499,6 +4499,63 @@ verify_eh_throw_stmt_node (void **slot, void *data)
return 1; return 1;
} }
/* Verify if the location LOCs block is in BLOCKS. */
static bool
verify_location (pointer_set_t *blocks, location_t loc)
{
tree block = LOCATION_BLOCK (loc);
if (block != NULL_TREE
&& !pointer_set_contains (blocks, block))
{
error ("location references block not in block tree");
return true;
}
return false;
}
/* Called via walk_tree. Verify locations of expressions. */
static tree
verify_expr_location_1 (tree *tp, int *walk_subtrees, void *data)
{
struct pointer_set_t *blocks = (struct pointer_set_t *) data;
if (!EXPR_P (*tp))
{
*walk_subtrees = false;
return NULL;
}
location_t loc = EXPR_LOCATION (*tp);
if (verify_location (blocks, loc))
return *tp;
return NULL;
}
/* Called via walk_gimple_op. Verify locations of expressions. */
static tree
verify_expr_location (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
return verify_expr_location_1 (tp, walk_subtrees, wi->info);
}
/* Insert all subblocks of BLOCK into BLOCKS and recurse. */
static void
collect_subblocks (pointer_set_t *blocks, tree block)
{
tree t;
for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
{
pointer_set_insert (blocks, t);
collect_subblocks (blocks, t);
}
}
/* Verify the GIMPLE statements in the CFG of FN. */ /* Verify the GIMPLE statements in the CFG of FN. */
DEBUG_FUNCTION void DEBUG_FUNCTION void
...@@ -4506,12 +4563,20 @@ verify_gimple_in_cfg (struct function *fn) ...@@ -4506,12 +4563,20 @@ verify_gimple_in_cfg (struct function *fn)
{ {
basic_block bb; basic_block bb;
bool err = false; bool err = false;
struct pointer_set_t *visited, *visited_stmts; struct pointer_set_t *visited, *visited_stmts, *blocks;
timevar_push (TV_TREE_STMT_VERIFY); timevar_push (TV_TREE_STMT_VERIFY);
visited = pointer_set_create (); visited = pointer_set_create ();
visited_stmts = pointer_set_create (); visited_stmts = pointer_set_create ();
/* Collect all BLOCKs referenced by the BLOCK tree of FN. */
blocks = pointer_set_create ();
if (DECL_INITIAL (fn->decl))
{
pointer_set_insert (blocks, DECL_INITIAL (fn->decl));
collect_subblocks (blocks, DECL_INITIAL (fn->decl));
}
FOR_EACH_BB_FN (bb, fn) FOR_EACH_BB_FN (bb, fn)
{ {
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
...@@ -4532,6 +4597,13 @@ verify_gimple_in_cfg (struct function *fn) ...@@ -4532,6 +4597,13 @@ verify_gimple_in_cfg (struct function *fn)
err2 |= verify_gimple_phi (phi); err2 |= verify_gimple_phi (phi);
/* Only PHI arguments have locations. */
if (gimple_location (phi) != UNKNOWN_LOCATION)
{
error ("PHI node with location");
err2 = true;
}
for (i = 0; i < gimple_phi_num_args (phi); i++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
tree arg = gimple_phi_arg_def (phi, i); tree arg = gimple_phi_arg_def (phi, i);
...@@ -4543,6 +4615,20 @@ verify_gimple_in_cfg (struct function *fn) ...@@ -4543,6 +4615,20 @@ verify_gimple_in_cfg (struct function *fn)
debug_generic_expr (addr); debug_generic_expr (addr);
err2 |= true; err2 |= true;
} }
location_t loc = gimple_phi_arg_location (phi, i);
if (virtual_operand_p (gimple_phi_result (phi))
&& loc != UNKNOWN_LOCATION)
{
error ("virtual PHI with argument locations");
err2 = true;
}
addr = walk_tree (&arg, verify_expr_location_1, blocks, NULL);
if (addr)
{
debug_generic_expr (addr);
err2 = true;
}
err2 |= verify_location (blocks, loc);
} }
if (err2) if (err2)
...@@ -4567,6 +4653,7 @@ verify_gimple_in_cfg (struct function *fn) ...@@ -4567,6 +4653,7 @@ verify_gimple_in_cfg (struct function *fn)
} }
err2 |= verify_gimple_stmt (stmt); err2 |= verify_gimple_stmt (stmt);
err2 |= verify_location (blocks, gimple_location (stmt));
memset (&wi, 0, sizeof (wi)); memset (&wi, 0, sizeof (wi));
wi.info = (void *) visited; wi.info = (void *) visited;
...@@ -4578,6 +4665,15 @@ verify_gimple_in_cfg (struct function *fn) ...@@ -4578,6 +4665,15 @@ verify_gimple_in_cfg (struct function *fn)
err2 |= true; err2 |= true;
} }
memset (&wi, 0, sizeof (wi));
wi.info = (void *) blocks;
addr = walk_gimple_op (stmt, verify_expr_location, &wi);
if (addr)
{
debug_generic_expr (addr);
err2 |= true;
}
/* ??? Instead of not checking these stmts at all the walker /* ??? Instead of not checking these stmts at all the walker
should know its context via wi. */ should know its context via wi. */
if (!is_gimple_debug (stmt) if (!is_gimple_debug (stmt)
...@@ -4632,6 +4728,7 @@ verify_gimple_in_cfg (struct function *fn) ...@@ -4632,6 +4728,7 @@ verify_gimple_in_cfg (struct function *fn)
pointer_set_destroy (visited); pointer_set_destroy (visited);
pointer_set_destroy (visited_stmts); pointer_set_destroy (visited_stmts);
pointer_set_destroy (blocks);
verify_histograms (); verify_histograms ();
timevar_pop (TV_TREE_STMT_VERIFY); timevar_pop (TV_TREE_STMT_VERIFY);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment