This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp] Fix some CFG verification
- From: Diego Novillo <dnovillo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 11 Jan 2006 18:41:26 -0500
- Subject: [gomp] Fix some CFG verification
When emitting error messages in the verifier about invalid labels, we would
sometimes ICE if the label happened to be NULL. This patch steps around
the NULL label.
The patch adds a new debugging helper, debug_function, which just calls
dump_function_to_file. Inside dump_function_to_file, we now correctly
switch to the function's CFUN to emit the local variables.
There is a third fix in the patch, which I think I will have to undo. I
used to get an ICE inside set_bb_for_stmt, because for some reason we were
calling it during RTL expansion. Since the label-to-block map doesn't
exist at that point, we'd ICE. So, the patch just ignores the
label-to-block mapping during RTL expansion.
Unfortunately, I cannot reproduce this ICE anymore, so I'm thinking that
this may have been a side-effect of another bug I was having in my code.
Since I cannot reproduce this, I will undo this part (serves me right for
trying to reproduce the problem after committing the patch).
Tested on x86.
2006-01-11 Diego Novillo <dnovillo@redhat.com>
* tree-dump.h (debug_function): Declare.
* tree-cfg.c (set_bb_for_stmt): Do not update the
block-to-labels map if we are currently expanding to RTL.
(tree_node_can_be_shared): Remove unnecessary CONSTANT_CLASS_P
checks.
Handle IDENTIFIER_NODE.
(tree_verify_flow_info): Do not ICE when emitting error
messages about invalid labels.
(dump_function_to_file): Reset CFUN before emitting the body
of the function.
(debug_function): New.
Index: tree-dump.h
===================================================================
--- tree-dump.h (revision 109596)
+++ tree-dump.h (working copy)
@@ -91,6 +91,7 @@ extern void queue_and_dump_index (dump_i
extern void queue_and_dump_type (dump_info_p, tree);
extern void dump_function (enum tree_dump_index, tree);
extern void dump_function_to_file (tree, FILE *, int);
+extern void debug_function (tree, int);
extern int dump_flag (dump_info_p, int, tree);
extern unsigned int dump_register (const char *, const char *, const char *,
Index: tree-cfg.c
===================================================================
--- tree-cfg.c (revision 109596)
+++ tree-cfg.c (working copy)
@@ -2707,9 +2707,12 @@ set_bb_for_stmt (tree t, basic_block bb)
stmt_ann_t ann = get_stmt_ann (t);
ann->bb = bb;
- /* If the statement is a label, add the label to block-to-labels map
- so that we can speed up edge creation for GOTO_EXPRs. */
- if (TREE_CODE (t) == LABEL_EXPR)
+ /* If the statement is a label, add the label to block-to-labels
+ map so that we can speed up edge creation for GOTO_EXPRs.
+ Note that LABEL_TO_BLOCK_MAP may not exist if we are
+ currently expanding into RTL (in which case, this mapping is
+ unnecessary, anyway). */
+ if (TREE_CODE (t) == LABEL_EXPR && !currently_expanding_to_rtl)
{
int uid;
@@ -3426,25 +3429,20 @@ static bool
tree_node_can_be_shared (tree t)
{
if (IS_TYPE_OR_DECL_P (t)
- /* We check for constants explicitly since they are not considered
- gimple invariants if they overflowed. */
- || CONSTANT_CLASS_P (t)
|| is_gimple_min_invariant (t)
|| TREE_CODE (t) == SSA_NAME
- || t == error_mark_node)
+ || t == error_mark_node
+ || TREE_CODE (t) == IDENTIFIER_NODE)
return true;
if (TREE_CODE (t) == CASE_LABEL_EXPR)
return true;
while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
- /* We check for constants explicitly since they are not considered
- gimple invariants if they overflowed. */
- && (CONSTANT_CLASS_P (TREE_OPERAND (t, 1))
- || is_gimple_min_invariant (TREE_OPERAND (t, 1))))
- || (TREE_CODE (t) == COMPONENT_REF
- || TREE_CODE (t) == REALPART_EXPR
- || TREE_CODE (t) == IMAGPART_EXPR))
+ && 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))
@@ -3621,27 +3619,29 @@ tree_verify_flow_info (void)
if (prev_stmt && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
{
- error ("nonlocal label %s is not first "
- "in a sequence of labels in bb %d",
- IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
- bb->index);
+ error ("nonlocal label ");
+ print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ fprintf (stderr, " is not first in a sequence of labels in bb %d",
+ bb->index);
err = 1;
}
if (label_to_block (LABEL_EXPR_LABEL (stmt)) != bb)
{
- error ("label %s to block does not match in bb %d",
- IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
- bb->index);
+ error ("label ");
+ print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ fprintf (stderr, " to block does not match in bb %d",
+ bb->index);
err = 1;
}
if (decl_function_context (LABEL_EXPR_LABEL (stmt))
!= current_function_decl)
{
- error ("label %s has incorrect context in bb %d",
- IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
- bb->index);
+ error ("label ");
+ print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ fprintf (stderr, " has incorrect context in bb %d",
+ bb->index);
err = 1;
}
}
@@ -3663,12 +3663,13 @@ tree_verify_flow_info (void)
if (TREE_CODE (stmt) == LABEL_EXPR)
{
- error ("label %s in the middle of basic block %d",
- IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
- bb->index);
+ error ("label ");
+ print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ fprintf (stderr, " in the middle of basic block %d", bb->index);
err = 1;
}
}
+
bsi = bsi_last (bb);
if (bsi_end_p (bsi))
continue;
@@ -3805,7 +3806,7 @@ tree_verify_flow_info (void)
}
if (! tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
{
- error ("case labels not sorted:");
+ error ("case labels not sorted: ");
print_generic_expr (stderr, prev, 0);
fprintf (stderr," is greater than ");
print_generic_expr (stderr, c, 0);
@@ -4454,7 +4455,8 @@ dump_function_to_file (tree fn, FILE *fi
bool ignore_topmost_bind = false, any_var = false;
basic_block bb;
tree chain;
-
+ struct function *saved_cfun;
+
fprintf (file, "%s (", lang_hooks.decl_printable_name (fn, 2));
arg = DECL_ARGUMENTS (fn);
@@ -4475,6 +4477,10 @@ dump_function_to_file (tree fn, FILE *fi
return;
}
+ /* Switch CFUN to point to FN. */
+ saved_cfun = cfun;
+ cfun = DECL_STRUCT_FUNCTION (fn);
+
/* When GIMPLE is lowered, the variables are no longer available in
BIND_EXPRs, so display them separately. */
if (cfun && cfun->decl == fn && cfun->unexpanded_var_list)
@@ -4516,7 +4522,7 @@ dump_function_to_file (tree fn, FILE *fi
/* Make a tree based dump. */
chain = DECL_SAVED_TREE (fn);
- if (TREE_CODE (chain) == BIND_EXPR)
+ if (chain && TREE_CODE (chain) == BIND_EXPR)
{
if (ignore_topmost_bind)
{
@@ -4542,6 +4548,18 @@ dump_function_to_file (tree fn, FILE *fi
}
fprintf (file, "\n\n");
+
+ /* Restore CFUN. */
+ cfun = saved_cfun;
+}
+
+
+/* Dump FUNCTION_DECL FN to stderr using FLAGS (see TDF_* in tree.h) */
+
+void
+debug_function (tree fn, int flags)
+{
+ dump_function_to_file (fn, stderr, flags);
}