aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r--gcc/tree-cfg.c101
1 files changed, 63 insertions, 38 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 48fbe52..ae5335b 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -636,6 +636,67 @@ make_blocks_1 (gimple_seq seq, basic_block bb)
static void
make_blocks (gimple_seq seq)
{
+ /* Look for debug markers right before labels, and move the debug
+ stmts after the labels. Accepting labels among debug markers
+ adds no value, just complexity; if we wanted to annotate labels
+ with view numbers (so sequencing among markers would matter) or
+ somesuch, we're probably better off still moving the labels, but
+ adding other debug annotations in their original positions or
+ emitting nonbind or bind markers associated with the labels in
+ the original position of the labels.
+
+ Moving labels would probably be simpler, but we can't do that:
+ moving labels assigns label ids to them, and doing so because of
+ debug markers makes for -fcompare-debug and possibly even codegen
+ differences. So, we have to move the debug stmts instead. To
+ that end, we scan SEQ backwards, marking the position of the
+ latest (earliest we find) label, and moving debug stmts that are
+ not separated from it by nondebug nonlabel stmts after the
+ label. */
+ if (MAY_HAVE_DEBUG_MARKER_STMTS)
+ {
+ gimple_stmt_iterator label = gsi_none ();
+
+ for (gimple_stmt_iterator i = gsi_last (seq); !gsi_end_p (i); gsi_prev (&i))
+ {
+ gimple *stmt = gsi_stmt (i);
+
+ /* If this is the first label we encounter (latest in SEQ)
+ before nondebug stmts, record its position. */
+ if (is_a <glabel *> (stmt))
+ {
+ if (gsi_end_p (label))
+ label = i;
+ continue;
+ }
+
+ /* Without a recorded label position to move debug stmts to,
+ there's nothing to do. */
+ if (gsi_end_p (label))
+ continue;
+
+ /* Move the debug stmt at I after LABEL. */
+ if (is_gimple_debug (stmt))
+ {
+ gcc_assert (gimple_debug_nonbind_marker_p (stmt));
+ /* As STMT is removed, I advances to the stmt after
+ STMT, so the gsi_prev in the for "increment"
+ expression gets us to the stmt we're to visit after
+ STMT. LABEL, however, would advance to the moved
+ stmt if we passed it to gsi_move_after, so pass it a
+ copy instead, so as to keep LABEL pointing to the
+ LABEL. */
+ gimple_stmt_iterator copy = label;
+ gsi_move_after (&i, &copy);
+ continue;
+ }
+
+ /* There aren't any (more?) debug stmts before label, so
+ there isn't anything else to move after it. */
+ label = gsi_none ();
+ }
+ }
+
make_blocks_1 (seq, ENTRY_BLOCK_PTR_FOR_FN (cfun));
}
@@ -1005,11 +1066,7 @@ make_edges (void)
tree target;
if (!label_stmt)
- {
- if (is_gimple_debug (gsi_stmt (gsi)))
- continue;
- break;
- }
+ break;
target = gimple_label_label (label_stmt);
@@ -1519,9 +1576,6 @@ cleanup_dead_labels (void)
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- if (is_gimple_debug (gsi_stmt (i)))
- continue;
-
tree label;
glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));
@@ -1682,12 +1736,6 @@ cleanup_dead_labels (void)
for (i = gsi_start_bb (bb); !gsi_end_p (i); )
{
- if (is_gimple_debug (gsi_stmt (i)))
- {
- gsi_next (&i);
- continue;
- }
-
tree label;
glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));
@@ -1863,8 +1911,6 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
gsi_next (&gsi))
{
tree lab;
- if (is_gimple_debug (gsi_stmt (gsi)))
- continue;
glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
if (!label_stmt)
break;
@@ -5431,7 +5477,6 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
err |= err2;
}
- bool label_allowed = true;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple *stmt = gsi_stmt (gsi);
@@ -5448,19 +5493,6 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
err2 = true;
}
- /* Labels may be preceded only by debug markers, not debug bind
- or source bind or any other statements. */
- if (gimple_code (stmt) == GIMPLE_LABEL)
- {
- if (!label_allowed)
- {
- error ("gimple label in the middle of a basic block");
- err2 = true;
- }
- }
- else if (!gimple_debug_begin_stmt_p (stmt))
- label_allowed = false;
-
err2 |= verify_gimple_stmt (stmt);
err2 |= verify_location (&blocks, gimple_location (stmt));
@@ -5584,10 +5616,6 @@ gimple_verify_flow_info (void)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree label;
-
- if (is_gimple_debug (gsi_stmt (gsi)))
- continue;
-
gimple *prev_stmt = stmt;
stmt = gsi_stmt (gsi);
@@ -5912,10 +5940,8 @@ gimple_block_label (basic_block bb)
tree label;
glabel *stmt;
- for (i = s; !gsi_end_p (i); gsi_next (&i))
+ for (i = s; !gsi_end_p (i); first = false, gsi_next (&i))
{
- if (is_gimple_debug (gsi_stmt (i)))
- continue;
stmt = dyn_cast <glabel *> (gsi_stmt (i));
if (!stmt)
break;
@@ -5926,7 +5952,6 @@ gimple_block_label (basic_block bb)
gsi_move_before (&i, &s);
return label;
}
- first = false;
}
label = create_artificial_label (UNKNOWN_LOCATION);