aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-01-14 14:59:20 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-01-14 14:59:20 +0000
commit7bb0199604cf8ba978b2fbfb751f2081faa64f87 (patch)
tree6f2ecb0a9406dd991dbe8cc74c1b0c73f7f695e7 /gcc
parent30b2fc65b93b31fd9c2c7c070a31dbba786bbec0 (diff)
downloadgcc-7bb0199604cf8ba978b2fbfb751f2081faa64f87.zip
gcc-7bb0199604cf8ba978b2fbfb751f2081faa64f87.tar.gz
gcc-7bb0199604cf8ba978b2fbfb751f2081faa64f87.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/tree-cfg.c99
2 files changed, 105 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7b31619..93947b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
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
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index e0bf7ac..83003fb 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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);
}