| Index: gcc/gcc/cfgrtl.c
|
| diff --git a/gcc/gcc/cfgrtl.c b/gcc/gcc/cfgrtl.c
|
| index 7af4215a8452d401357aee98d28ab1e37b8f2f7b..5ad07f4d449ff9099889bed9d084547a0652eb10 100644
|
| --- a/gcc/gcc/cfgrtl.c
|
| +++ b/gcc/gcc/cfgrtl.c
|
| @@ -1,6 +1,6 @@
|
| /* Control flow graph manipulation code for GNU compiler.
|
| Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
| - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
| + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
| Free Software Foundation, Inc.
|
|
|
| This file is part of GCC.
|
| @@ -65,7 +65,6 @@ along with GCC; see the file COPYING3. If not see
|
|
|
| static int can_delete_note_p (const_rtx);
|
| static int can_delete_label_p (const_rtx);
|
| -static void commit_one_edge_insertion (edge);
|
| static basic_block rtl_split_edge (edge);
|
| static bool rtl_move_block_after (basic_block, basic_block);
|
| static int rtl_verify_flow_info (void);
|
| @@ -87,8 +86,16 @@ static void rtl_make_forwarder_block (edge);
|
| static int
|
| can_delete_note_p (const_rtx note)
|
| {
|
| - return (NOTE_KIND (note) == NOTE_INSN_DELETED
|
| - || NOTE_KIND (note) == NOTE_INSN_BASIC_BLOCK);
|
| + switch (NOTE_KIND (note))
|
| + {
|
| + case NOTE_INSN_DELETED:
|
| + case NOTE_INSN_BASIC_BLOCK:
|
| + case NOTE_INSN_EPILOGUE_BEG:
|
| + return true;
|
| +
|
| + default:
|
| + return false;
|
| + }
|
| }
|
|
|
| /* True if a given label can be deleted. */
|
| @@ -163,9 +170,7 @@ delete_insn (rtx insn)
|
| remove_note (insn, note);
|
| }
|
|
|
| - if (JUMP_P (insn)
|
| - && (GET_CODE (PATTERN (insn)) == ADDR_VEC
|
| - || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
|
| + if (JUMP_TABLE_DATA_P (insn))
|
| {
|
| rtx pat = PATTERN (insn);
|
| int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC;
|
| @@ -233,22 +238,6 @@ delete_insn_chain (rtx start, rtx finish, bool clear_bb)
|
| start = next;
|
| }
|
| }
|
| -
|
| -/* Like delete_insn_chain but also purge dead edges from BB. */
|
| -
|
| -void
|
| -delete_insn_chain_and_edges (rtx first, rtx last)
|
| -{
|
| - bool purge = false;
|
| -
|
| - if (INSN_P (last)
|
| - && BLOCK_FOR_INSN (last)
|
| - && BB_END (BLOCK_FOR_INSN (last)) == last)
|
| - purge = true;
|
| - delete_insn_chain (first, last, false);
|
| - if (purge)
|
| - purge_dead_edges (BLOCK_FOR_INSN (last));
|
| -}
|
|
|
| /* Create a new basic block consisting of the instructions between HEAD and END
|
| inclusive. This function is designed to allow fast BB construction - reuses
|
| @@ -380,8 +369,6 @@ rtl_delete_block (basic_block b)
|
| label for an exception handler which can't be reached. We need
|
| to remove the label from the exception_handler_label list. */
|
| insn = BB_HEAD (b);
|
| - if (LABEL_P (insn))
|
| - maybe_remove_eh_handler (insn);
|
|
|
| end = get_last_bb_insn (b);
|
|
|
| @@ -446,13 +433,13 @@ struct rtl_opt_pass pass_free_cfg =
|
| {
|
| {
|
| RTL_PASS,
|
| - NULL, /* name */
|
| + "*free_cfg", /* name */
|
| NULL, /* gate */
|
| rest_of_pass_free_cfg, /* execute */
|
| NULL, /* sub */
|
| NULL, /* next */
|
| 0, /* static_pass_number */
|
| - 0, /* tv_id */
|
| + TV_NONE, /* tv_id */
|
| 0, /* properties_required */
|
| 0, /* properties_provided */
|
| PROP_cfg, /* properties_destroyed */
|
| @@ -483,7 +470,7 @@ emit_insn_at_entry (rtx insn)
|
| }
|
|
|
| /* Update BLOCK_FOR_INSN of insns between BEGIN and END
|
| - (or BARRIER if found) and notify df of the bb change.
|
| + (or BARRIER if found) and notify df of the bb change.
|
| The insn chain range is inclusive
|
| (i.e. both BEGIN and END will be updated. */
|
|
|
| @@ -544,7 +531,26 @@ rtl_split_block (basic_block bb, void *insnp)
|
| insn = first_insn_after_basic_block_note (bb);
|
|
|
| if (insn)
|
| - insn = PREV_INSN (insn);
|
| + {
|
| + rtx next = insn;
|
| +
|
| + insn = PREV_INSN (insn);
|
| +
|
| + /* If the block contains only debug insns, insn would have
|
| + been NULL in a non-debug compilation, and then we'd end
|
| + up emitting a DELETED note. For -fcompare-debug
|
| + stability, emit the note too. */
|
| + if (insn != BB_END (bb)
|
| + && DEBUG_INSN_P (next)
|
| + && DEBUG_INSN_P (BB_END (bb)))
|
| + {
|
| + while (next != BB_END (bb) && DEBUG_INSN_P (next))
|
| + next = NEXT_INSN (next);
|
| +
|
| + if (next == BB_END (bb))
|
| + emit_note_after (NOTE_INSN_DELETED, next);
|
| + }
|
| + }
|
| else
|
| insn = get_last_insn ();
|
| }
|
| @@ -579,18 +585,18 @@ rtl_merge_blocks (basic_block a, basic_block b)
|
| {
|
| rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a);
|
| rtx del_first = NULL_RTX, del_last = NULL_RTX;
|
| + rtx b_debug_start = b_end, b_debug_end = b_end;
|
| int b_empty = 0;
|
|
|
| if (dump_file)
|
| fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index);
|
|
|
| + while (DEBUG_INSN_P (b_end))
|
| + b_end = PREV_INSN (b_debug_start = b_end);
|
| +
|
| /* If there was a CODE_LABEL beginning B, delete it. */
|
| if (LABEL_P (b_head))
|
| {
|
| - /* This might have been an EH label that no longer has incoming
|
| - EH edges. Update data structures to match. */
|
| - maybe_remove_eh_handler (b_head);
|
| -
|
| /* Detect basic blocks with nothing but a label. This can happen
|
| in particular at the end of a function. */
|
| if (b_head == b_end)
|
| @@ -653,9 +659,21 @@ rtl_merge_blocks (basic_block a, basic_block b)
|
| /* Reassociate the insns of B with A. */
|
| if (!b_empty)
|
| {
|
| - update_bb_for_insn_chain (a_end, b_end, a);
|
| + update_bb_for_insn_chain (a_end, b_debug_end, a);
|
|
|
| - a_end = b_end;
|
| + a_end = b_debug_end;
|
| + }
|
| + else if (b_end != b_debug_end)
|
| + {
|
| + /* Move any deleted labels and other notes between the end of A
|
| + and the debug insns that make up B after the debug insns,
|
| + bringing the debug insns into A while keeping the notes after
|
| + the end of A. */
|
| + if (NEXT_INSN (a_end) != b_debug_start)
|
| + reorder_insns_nobb (NEXT_INSN (a_end), PREV_INSN (b_debug_start),
|
| + b_debug_end);
|
| + update_bb_for_insn_chain (b_debug_start, b_debug_end, a);
|
| + a_end = b_debug_end;
|
| }
|
|
|
| df_bb_delete (b->index);
|
| @@ -893,31 +911,25 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
|
| return e;
|
| }
|
|
|
| -/* Redirect edge representing branch of (un)conditional jump or tablejump,
|
| - NULL on failure */
|
| -static edge
|
| -redirect_branch_edge (edge e, basic_block target)
|
| +/* Subroutine of redirect_branch_edge that tries to patch the jump
|
| + instruction INSN so that it reaches block NEW. Do this
|
| + only when it originally reached block OLD. Return true if this
|
| + worked or the original target wasn't OLD, return false if redirection
|
| + doesn't work. */
|
| +
|
| +static bool
|
| +patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
|
| {
|
| rtx tmp;
|
| - rtx old_label = BB_HEAD (e->dest);
|
| - basic_block src = e->src;
|
| - rtx insn = BB_END (src);
|
| -
|
| - /* We can only redirect non-fallthru edges of jump insn. */
|
| - if (e->flags & EDGE_FALLTHRU)
|
| - return NULL;
|
| - else if (!JUMP_P (insn))
|
| - return NULL;
|
| -
|
| /* Recognize a tablejump and adjust all matching cases. */
|
| if (tablejump_p (insn, NULL, &tmp))
|
| {
|
| rtvec vec;
|
| int j;
|
| - rtx new_label = block_label (target);
|
| + rtx new_label = block_label (new_bb);
|
|
|
| - if (target == EXIT_BLOCK_PTR)
|
| - return NULL;
|
| + if (new_bb == EXIT_BLOCK_PTR)
|
| + return false;
|
| if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
|
| vec = XVEC (PATTERN (tmp), 0);
|
| else
|
| @@ -944,6 +956,48 @@ redirect_branch_edge (edge e, basic_block target)
|
| ++LABEL_NUSES (new_label);
|
| }
|
| }
|
| + else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL)
|
| + {
|
| + int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp);
|
| + rtx new_label, note;
|
| +
|
| + if (new_bb == EXIT_BLOCK_PTR)
|
| + return false;
|
| + new_label = block_label (new_bb);
|
| +
|
| + for (i = 0; i < n; ++i)
|
| + {
|
| + rtx old_ref = ASM_OPERANDS_LABEL (tmp, i);
|
| + gcc_assert (GET_CODE (old_ref) == LABEL_REF);
|
| + if (XEXP (old_ref, 0) == old_label)
|
| + {
|
| + ASM_OPERANDS_LABEL (tmp, i)
|
| + = gen_rtx_LABEL_REF (Pmode, new_label);
|
| + --LABEL_NUSES (old_label);
|
| + ++LABEL_NUSES (new_label);
|
| + }
|
| + }
|
| +
|
| + if (JUMP_LABEL (insn) == old_label)
|
| + {
|
| + JUMP_LABEL (insn) = new_label;
|
| + note = find_reg_note (insn, REG_LABEL_TARGET, new_label);
|
| + if (note)
|
| + remove_note (insn, note);
|
| + }
|
| + else
|
| + {
|
| + note = find_reg_note (insn, REG_LABEL_TARGET, old_label);
|
| + if (note)
|
| + remove_note (insn, note);
|
| + if (JUMP_LABEL (insn) != new_label
|
| + && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
|
| + add_reg_note (insn, REG_LABEL_TARGET, new_label);
|
| + }
|
| + while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
|
| + != NULL_RTX)
|
| + XEXP (note, 0) = new_label;
|
| + }
|
| else
|
| {
|
| /* ?? We may play the games with moving the named labels from
|
| @@ -952,20 +1006,55 @@ redirect_branch_edge (edge e, basic_block target)
|
| if (computed_jump_p (insn)
|
| /* A return instruction can't be redirected. */
|
| || returnjump_p (insn))
|
| - return NULL;
|
| + return false;
|
|
|
| - /* If the insn doesn't go where we think, we're confused. */
|
| - gcc_assert (JUMP_LABEL (insn) == old_label);
|
| -
|
| - /* If the substitution doesn't succeed, die. This can happen
|
| - if the back end emitted unrecognizable instructions or if
|
| - target is exit block on some arches. */
|
| - if (!redirect_jump (insn, block_label (target), 0))
|
| + if (!currently_expanding_to_rtl || JUMP_LABEL (insn) == old_label)
|
| {
|
| - gcc_assert (target == EXIT_BLOCK_PTR);
|
| - return NULL;
|
| + /* If the insn doesn't go where we think, we're confused. */
|
| + gcc_assert (JUMP_LABEL (insn) == old_label);
|
| +
|
| + /* If the substitution doesn't succeed, die. This can happen
|
| + if the back end emitted unrecognizable instructions or if
|
| + target is exit block on some arches. */
|
| + if (!redirect_jump (insn, block_label (new_bb), 0))
|
| + {
|
| + gcc_assert (new_bb == EXIT_BLOCK_PTR);
|
| + return false;
|
| + }
|
| }
|
| }
|
| + return true;
|
| +}
|
| +
|
| +
|
| +/* Redirect edge representing branch of (un)conditional jump or tablejump,
|
| + NULL on failure */
|
| +static edge
|
| +redirect_branch_edge (edge e, basic_block target)
|
| +{
|
| + rtx old_label = BB_HEAD (e->dest);
|
| + basic_block src = e->src;
|
| + rtx insn = BB_END (src);
|
| +
|
| + /* We can only redirect non-fallthru edges of jump insn. */
|
| + if (e->flags & EDGE_FALLTHRU)
|
| + return NULL;
|
| + else if (!JUMP_P (insn) && !currently_expanding_to_rtl)
|
| + return NULL;
|
| +
|
| + if (!currently_expanding_to_rtl)
|
| + {
|
| + if (!patch_jump_insn (insn, old_label, target))
|
| + return NULL;
|
| + }
|
| + else
|
| + /* When expanding this BB might actually contain multiple
|
| + jumps (i.e. not yet split by find_many_sub_basic_blocks).
|
| + Redirect all of those that match our label. */
|
| + for (insn = BB_HEAD (src); insn != NEXT_INSN (BB_END (src));
|
| + insn = NEXT_INSN (insn))
|
| + if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target))
|
| + return NULL;
|
|
|
| if (dump_file)
|
| fprintf (dump_file, "Edge %i->%i redirected to %i\n",
|
| @@ -1170,7 +1259,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
|
| if (abnormal_edge_flags)
|
| make_edge (src, target, abnormal_edge_flags);
|
|
|
| - df_mark_solutions_dirty ();
|
| + df_mark_solutions_dirty ();
|
| return new_bb;
|
| }
|
|
|
| @@ -1321,7 +1410,22 @@ rtl_split_edge (edge edge_in)
|
| gcc_assert (redirected);
|
| }
|
| else
|
| - redirect_edge_succ (edge_in, bb);
|
| + {
|
| + if (edge_in->src != ENTRY_BLOCK_PTR)
|
| + {
|
| + /* For asm goto even splitting of fallthru edge might
|
| + need insn patching, as other labels might point to the
|
| + old label. */
|
| + rtx last = BB_END (edge_in->src);
|
| + if (last
|
| + && JUMP_P (last)
|
| + && edge_in->dest != EXIT_BLOCK_PTR
|
| + && extract_asm_operands (PATTERN (last)) != NULL_RTX
|
| + && patch_jump_insn (last, before, bb))
|
| + df_set_bb_dirty (edge_in->src);
|
| + }
|
| + redirect_edge_succ (edge_in, bb);
|
| + }
|
|
|
| return bb;
|
| }
|
| @@ -1350,7 +1454,7 @@ insert_insn_on_edge (rtx pattern, edge e)
|
|
|
| /* Update the CFG for the instructions queued on edge E. */
|
|
|
| -static void
|
| +void
|
| commit_one_edge_insertion (edge e)
|
| {
|
| rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last;
|
| @@ -1418,24 +1522,11 @@ commit_one_edge_insertion (edge e)
|
| && targetm.have_named_sections
|
| && e->src != ENTRY_BLOCK_PTR
|
| && BB_PARTITION (e->src) == BB_COLD_PARTITION
|
| - && !(e->flags & EDGE_CROSSING))
|
| - {
|
| - rtx bb_note, cur_insn;
|
| -
|
| - bb_note = NULL_RTX;
|
| - for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb));
|
| - cur_insn = NEXT_INSN (cur_insn))
|
| - if (NOTE_INSN_BASIC_BLOCK_P (cur_insn))
|
| - {
|
| - bb_note = cur_insn;
|
| - break;
|
| - }
|
| -
|
| - if (JUMP_P (BB_END (bb))
|
| - && !any_condjump_p (BB_END (bb))
|
| - && (single_succ_edge (bb)->flags & EDGE_CROSSING))
|
| - add_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX);
|
| - }
|
| + && !(e->flags & EDGE_CROSSING)
|
| + && JUMP_P (after)
|
| + && !any_condjump_p (after)
|
| + && (single_succ_edge (bb)->flags & EDGE_CROSSING))
|
| + add_reg_note (after, REG_CROSSING_JUMP, NULL_RTX);
|
| }
|
| }
|
|
|
| @@ -1539,7 +1630,7 @@ rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED)
|
| s_indent = (char *) alloca ((size_t) indent + 1);
|
| memset (s_indent, ' ', (size_t) indent);
|
| s_indent[indent] = '\0';
|
| -
|
| +
|
| if (df)
|
| {
|
| df_dump_top (bb, outf);
|
| @@ -1606,7 +1697,7 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first)
|
| {
|
| edge e;
|
| edge_iterator ei;
|
| -
|
| +
|
| fprintf (outf, ";; Start of basic block (");
|
| FOR_EACH_EDGE (e, ei, bb->preds)
|
| fprintf (outf, " %d", e->src->index);
|
| @@ -1700,11 +1791,11 @@ get_last_bb_insn (basic_block bb)
|
| end = tmp;
|
|
|
| /* Include any barriers that may follow the basic block. */
|
| - tmp = next_nonnote_insn (end);
|
| + tmp = next_nonnote_insn_bb (end);
|
| while (tmp && BARRIER_P (tmp))
|
| {
|
| end = tmp;
|
| - tmp = next_nonnote_insn (end);
|
| + tmp = next_nonnote_insn_bb (end);
|
| }
|
|
|
| return end;
|
| @@ -1826,12 +1917,16 @@ rtl_verify_flow_info_1 (void)
|
| n_abnormal++;
|
| }
|
|
|
| - if (n_eh && GET_CODE (PATTERN (BB_END (bb))) != RESX
|
| - && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX))
|
| + if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX))
|
| {
|
| error ("missing REG_EH_REGION note in the end of bb %i", bb->index);
|
| err = 1;
|
| }
|
| + if (n_eh > 1)
|
| + {
|
| + error ("too many eh edges %i", bb->index);
|
| + err = 1;
|
| + }
|
| if (n_branch
|
| && (!JUMP_P (BB_END (bb))
|
| || (n_branch > 1 && (any_uncondjump_p (BB_END (bb))
|
| @@ -1847,7 +1942,8 @@ rtl_verify_flow_info_1 (void)
|
| }
|
| if (n_branch != 1 && any_uncondjump_p (BB_END (bb)))
|
| {
|
| - error ("wrong amount of branch edges after unconditional jump %i", bb->index);
|
| + error ("wrong number of branch edges after unconditional jump %i",
|
| + bb->index);
|
| err = 1;
|
| }
|
| if (n_branch != 1 && any_condjump_p (BB_END (bb))
|
| @@ -2032,15 +2128,17 @@ rtl_verify_flow_info (void)
|
| rtx insn;
|
|
|
| /* Ensure existence of barrier in BB with no fallthru edges. */
|
| - for (insn = BB_END (bb); !insn || !BARRIER_P (insn);
|
| - insn = NEXT_INSN (insn))
|
| - if (!insn
|
| - || NOTE_INSN_BASIC_BLOCK_P (insn))
|
| + for (insn = NEXT_INSN (BB_END (bb)); ; insn = NEXT_INSN (insn))
|
| + {
|
| + if (!insn || NOTE_INSN_BASIC_BLOCK_P (insn))
|
| {
|
| error ("missing barrier after block %i", bb->index);
|
| err = 1;
|
| break;
|
| }
|
| + if (BARRIER_P (insn))
|
| + break;
|
| + }
|
| }
|
| else if (e->src != ENTRY_BLOCK_PTR
|
| && e->dest != EXIT_BLOCK_PTR)
|
| @@ -2108,9 +2206,7 @@ rtl_verify_flow_info (void)
|
| case CODE_LABEL:
|
| /* An addr_vec is placed outside any basic block. */
|
| if (NEXT_INSN (x)
|
| - && JUMP_P (NEXT_INSN (x))
|
| - && (GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_DIFF_VEC
|
| - || GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_VEC))
|
| + && JUMP_TABLE_DATA_P (NEXT_INSN (x)))
|
| x = NEXT_INSN (x);
|
|
|
| /* But in any case, non-deletable labels can appear anywhere. */
|
| @@ -2150,6 +2246,11 @@ purge_dead_edges (basic_block bb)
|
| bool found;
|
| edge_iterator ei;
|
|
|
| + if (DEBUG_INSN_P (insn) && insn != BB_HEAD (bb))
|
| + do
|
| + insn = PREV_INSN (insn);
|
| + while ((DEBUG_INSN_P (insn) || NOTE_P (insn)) && insn != BB_HEAD (bb));
|
| +
|
| /* If this instruction cannot trap, remove REG_EH_REGION notes. */
|
| if (NONJUMP_INSN_P (insn)
|
| && (note = find_reg_note (insn, REG_EH_REGION, NULL)))
|
| @@ -2165,39 +2266,33 @@ purge_dead_edges (basic_block bb)
|
| /* Cleanup abnormal edges caused by exceptions or non-local gotos. */
|
| for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
|
| {
|
| + bool remove = false;
|
| +
|
| /* There are three types of edges we need to handle correctly here: EH
|
| edges, abnormal call EH edges, and abnormal call non-EH edges. The
|
| latter can appear when nonlocal gotos are used. */
|
| - if (e->flags & EDGE_EH)
|
| + if (e->flags & EDGE_ABNORMAL_CALL)
|
| {
|
| - if (can_throw_internal (BB_END (bb))
|
| - /* If this is a call edge, verify that this is a call insn. */
|
| - && (! (e->flags & EDGE_ABNORMAL_CALL)
|
| - || CALL_P (BB_END (bb))))
|
| - {
|
| - ei_next (&ei);
|
| - continue;
|
| - }
|
| + if (!CALL_P (insn))
|
| + remove = true;
|
| + else if (can_nonlocal_goto (insn))
|
| + ;
|
| + else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
|
| + ;
|
| + else
|
| + remove = true;
|
| }
|
| - else if (e->flags & EDGE_ABNORMAL_CALL)
|
| + else if (e->flags & EDGE_EH)
|
| + remove = !can_throw_internal (insn);
|
| +
|
| + if (remove)
|
| {
|
| - if (CALL_P (BB_END (bb))
|
| - && (! (note = find_reg_note (insn, REG_EH_REGION, NULL))
|
| - || INTVAL (XEXP (note, 0)) >= 0))
|
| - {
|
| - ei_next (&ei);
|
| - continue;
|
| - }
|
| + remove_edge (e);
|
| + df_set_bb_dirty (bb);
|
| + purged = true;
|
| }
|
| else
|
| - {
|
| - ei_next (&ei);
|
| - continue;
|
| - }
|
| -
|
| - remove_edge (e);
|
| - df_set_bb_dirty (bb);
|
| - purged = true;
|
| + ei_next (&ei);
|
| }
|
|
|
| if (JUMP_P (insn))
|
| @@ -2613,10 +2708,6 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
|
| /* If there was a CODE_LABEL beginning B, delete it. */
|
| if (LABEL_P (BB_HEAD (b)))
|
| {
|
| - /* This might have been an EH label that no longer has incoming
|
| - EH edges. Update data structures to match. */
|
| - maybe_remove_eh_handler (BB_HEAD (b));
|
| -
|
| delete_insn (BB_HEAD (b));
|
| }
|
|
|
| @@ -2763,7 +2854,8 @@ rtl_block_ends_with_call_p (basic_block bb)
|
| while (!CALL_P (insn)
|
| && insn != BB_HEAD (bb)
|
| && (keep_with_call_p (insn)
|
| - || NOTE_P (insn)))
|
| + || NOTE_P (insn)
|
| + || DEBUG_INSN_P (insn)))
|
| insn = PREV_INSN (insn);
|
| return (CALL_P (insn));
|
| }
|
| @@ -2951,7 +3043,7 @@ rtl_lv_add_condition_to_bb (basic_block first_head ,
|
| op0 = force_operand (op0, NULL_RTX);
|
| op1 = force_operand (op1, NULL_RTX);
|
| do_compare_rtx_and_jump (op0, op1, comp, 0,
|
| - mode, NULL_RTX, NULL_RTX, label);
|
| + mode, NULL_RTX, NULL_RTX, label, -1);
|
| jump = get_last_insn ();
|
| JUMP_LABEL (jump) = label;
|
| LABEL_NUSES (label)++;
|
|
|