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>
* 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
PHI argument.
* graphite-sese-to-poly.c (insert_out_of_ssa_copy): Properly
......
......@@ -4499,6 +4499,63 @@ verify_eh_throw_stmt_node (void **slot, void *data)
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. */
DEBUG_FUNCTION void
......@@ -4506,12 +4563,20 @@ verify_gimple_in_cfg (struct function *fn)
{
basic_block bb;
bool err = false;
struct pointer_set_t *visited, *visited_stmts;
struct pointer_set_t *visited, *visited_stmts, *blocks;
timevar_push (TV_TREE_STMT_VERIFY);
visited = 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)
{
gimple_stmt_iterator gsi;
......@@ -4532,6 +4597,13 @@ verify_gimple_in_cfg (struct function *fn)
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++)
{
tree arg = gimple_phi_arg_def (phi, i);
......@@ -4543,6 +4615,20 @@ verify_gimple_in_cfg (struct function *fn)
debug_generic_expr (addr);
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)
......@@ -4567,6 +4653,7 @@ verify_gimple_in_cfg (struct function *fn)
}
err2 |= verify_gimple_stmt (stmt);
err2 |= verify_location (blocks, gimple_location (stmt));
memset (&wi, 0, sizeof (wi));
wi.info = (void *) visited;
......@@ -4578,6 +4665,15 @@ verify_gimple_in_cfg (struct function *fn)
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
should know its context via wi. */
if (!is_gimple_debug (stmt)
......@@ -4632,6 +4728,7 @@ verify_gimple_in_cfg (struct function *fn)
pointer_set_destroy (visited);
pointer_set_destroy (visited_stmts);
pointer_set_destroy (blocks);
verify_histograms ();
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