diff options
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 00f8661..b00a291 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -561,14 +561,22 @@ make_blocks_1 (gimple_seq seq, basic_block bb) { gimple_stmt_iterator i = gsi_start (seq); gimple *stmt = NULL; + gimple *prev_stmt = NULL; bool start_new_block = true; bool first_stmt_of_seq = true; while (!gsi_end_p (i)) { - gimple *prev_stmt; - - prev_stmt = stmt; + /* PREV_STMT should only be set to a debug stmt if the debug + stmt is before nondebug stmts. Once stmt reaches a nondebug + nonlabel, prev_stmt will be set to it, so that + stmt_starts_bb_p will know to start a new block if a label is + found. However, if stmt was a label after debug stmts only, + keep the label in prev_stmt even if we find further debug + stmts, for there may be other labels after them, and they + should land in the same block. */ + if (!prev_stmt || !stmt || !is_gimple_debug (stmt)) + prev_stmt = stmt; stmt = gsi_stmt (i); if (stmt && is_gimple_call (stmt)) @@ -583,6 +591,7 @@ make_blocks_1 (gimple_seq seq, basic_block bb) gsi_split_seq_before (&i, &seq); bb = create_basic_block (seq, bb); start_new_block = false; + prev_stmt = NULL; } /* Now add STMT to BB and create the subgraphs for special statement @@ -996,7 +1005,11 @@ make_edges (void) tree target; if (!label_stmt) - break; + { + if (is_gimple_debug (gsi_stmt (gsi))) + continue; + break; + } target = gimple_label_label (label_stmt); @@ -1506,6 +1519,9 @@ 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)); @@ -1666,6 +1682,12 @@ 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)); @@ -1841,6 +1863,8 @@ 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; @@ -2642,6 +2666,13 @@ stmt_starts_bb_p (gimple *stmt, gimple *prev_stmt) if (stmt == NULL) return false; + /* PREV_STMT is only set to a debug stmt if the debug stmt is before + any nondebug stmts in the block. We don't want to start another + block in this case: the debug stmt will already have started the + one STMT would start if we weren't outputting debug stmts. */ + if (prev_stmt && is_gimple_debug (prev_stmt)) + return false; + /* Labels start a new basic block only if the preceding statement wasn't a label of the same type. This prevents the creation of consecutive blocks that have nothing but a single label. */ @@ -5488,6 +5519,10 @@ 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); @@ -5557,7 +5592,7 @@ gimple_verify_flow_info (void) } } - gsi = gsi_last_bb (bb); + gsi = gsi_last_nondebug_bb (bb); if (gsi_end_p (gsi)) continue; @@ -5812,8 +5847,10 @@ gimple_block_label (basic_block bb) tree label; glabel *stmt; - for (i = s; !gsi_end_p (i); first = false, gsi_next (&i)) + for (i = s; !gsi_end_p (i); gsi_next (&i)) { + if (is_gimple_debug (gsi_stmt (i))) + continue; stmt = dyn_cast <glabel *> (gsi_stmt (i)); if (!stmt) break; @@ -5824,6 +5861,7 @@ gimple_block_label (basic_block bb) gsi_move_before (&i, &s); return label; } + first = false; } label = create_artificial_label (UNKNOWN_LOCATION); @@ -5899,7 +5937,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) return ret; } - gsi = gsi_last_bb (bb); + gsi = gsi_last_nondebug_bb (bb); stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi); switch (stmt ? gimple_code (stmt) : GIMPLE_ERROR_MARK) |