basic_block jump_block, jump_dest_block, cbranch_dest_block;
edge cbranch_jump_edge, cbranch_fallthru_edge;
rtx cbranch_insn;
- rtx insn, next;
- rtx end;
/* Verify that there are exactly two successors. */
if (!cbranch_block->succ
unconditional branch. */
cbranch_dest_block = cbranch_jump_edge->dest;
- if (!can_fallthru (jump_block, cbranch_dest_block))
+ if (cbranch_dest_block == EXIT_BLOCK_PTR
+ || !can_fallthru (jump_block, cbranch_dest_block))
return false;
/* Invert the conditional branch. */
cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
update_br_prob_note (cbranch_block);
- end = BB_END (jump_block);
- /* Deleting a block may produce unreachable code warning even when we are
- not deleting anything live. Suppress it by moving all the line number
- notes out of the block. */
- for (insn = BB_HEAD (jump_block); insn != NEXT_INSN (BB_END (jump_block));
- insn = next)
- {
- next = NEXT_INSN (insn);
- if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
- {
- if (insn == BB_END (jump_block))
- {
- BB_END (jump_block) = PREV_INSN (insn);
- if (insn == end)
- break;
- }
- reorder_insns_nobb (insn, insn, end);
- end = insn;
- }
- }
/* Delete the block with the unconditional jump, and clean up the mess. */
delete_basic_block (jump_block);
tidy_fallthru_edge (cbranch_jump_edge);
+ update_forwarder_flag (cbranch_block);
return true;
}
rtx insn = (target->succ->flags & EDGE_FALLTHRU
? BB_HEAD (target) : prev_nonnote_insn (BB_END (target)));
- if (GET_CODE (insn) != NOTE)
+ if (!NOTE_P (insn))
insn = NEXT_INSN (insn);
- for (; insn && GET_CODE (insn) != CODE_LABEL && !INSN_P (insn);
+ for (; insn && !LABEL_P (insn) && !INSN_P (insn);
insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == NOTE
+ if (NOTE_P (insn)
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
break;
- if (GET_CODE (insn) == NOTE)
+ if (NOTE_P (insn))
break;
/* Do not clean up branches to just past the end of a loop
recognition of some patterns. */
insn = PREV_INSN (BB_HEAD (target));
- if (insn && GET_CODE (insn) == NOTE
+ if (insn && NOTE_P (insn)
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
}
return;
barrier = next_nonnote_insn (BB_END (a));
- if (GET_CODE (barrier) != BARRIER)
+ if (!BARRIER_P (barrier))
abort ();
delete_insn (barrier);
/* There had better have been a barrier there. Delete it. */
barrier = NEXT_INSN (BB_END (b));
- if (barrier && GET_CODE (barrier) == BARRIER)
+ if (barrier && BARRIER_P (barrier))
delete_insn (barrier);
/* Move block and loop notes out of the chain so that we do not
??? We take the simple route for now and assume that if they're
equal, they were constructed identically. */
- if (GET_CODE (i1) == CALL_INSN
+ if (CALL_P (i1)
&& (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
CALL_INSN_FUNCTION_USAGE (i2))
|| SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)))
while (last1 != BB_HEAD (bb1) && !INSN_P (PREV_INSN (last1)))
last1 = PREV_INSN (last1);
- if (last1 != BB_HEAD (bb1) && GET_CODE (PREV_INSN (last1)) == CODE_LABEL)
+ if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1)))
last1 = PREV_INSN (last1);
while (last2 != BB_HEAD (bb2) && !INSN_P (PREV_INSN (last2)))
last2 = PREV_INSN (last2);
- if (last2 != BB_HEAD (bb2) && GET_CODE (PREV_INSN (last2)) == CODE_LABEL)
+ if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2)))
last2 = PREV_INSN (last2);
*f1 = last1;
unconditional jump, or a fake edge to exit. */
if (bb1->succ && !bb1->succ->succ_next
&& (bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
- && (GET_CODE (BB_END (bb1)) != JUMP_INSN || simplejump_p (BB_END (bb1))))
+ && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1))))
return (bb2->succ && !bb2->succ->succ_next
&& (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
- && (GET_CODE (BB_END (bb2)) != JUMP_INSN || simplejump_p (BB_END (bb2))));
+ && (!JUMP_P (BB_END (bb2)) || simplejump_p (BB_END (bb2))));
/* Match conditional jumps - this may get tricky when fallthru and branch
edges are crossed. */
/* ... and part the second. */
nmatch = flow_find_cross_jump (mode, src1, src2, &newpos1, &newpos2);
- if (!nmatch)
+
+ /* Don't proceed with the crossjump unless we found a sufficient number
+ of matching instructions or the 'from' block was totally matched
+ (such that its predecessors will hopefully be redirected and the
+ block removed). */
+ if ((nmatch < PARAM_VALUE (PARAM_MIN_CROSSJUMP_INSNS))
+ && (newpos1 != BB_HEAD (src1)))
return false;
#ifndef CASE_DROPS_THROUGH
/* Edit SRC1 to go to REDIRECT_TO at NEWPOS1. */
/* Skip possible basic block header. */
- if (GET_CODE (newpos1) == CODE_LABEL)
+ if (LABEL_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
- if (GET_CODE (newpos1) == NOTE)
+ if (NOTE_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& !(b->pred->flags & EDGE_COMPLEX)
- && GET_CODE (BB_HEAD (b)) == CODE_LABEL
+ && LABEL_P (BB_HEAD (b))
/* If the previous block ends with a branch to this
block, we can't delete the label. Normally this
is a condjump that is yet to be simplified, but
some element going to the same place as the
default (fallthru). */
&& (b->pred->src == ENTRY_BLOCK_PTR
- || GET_CODE (BB_END (b->pred->src)) != JUMP_INSN
+ || !JUMP_P (BB_END (b->pred->src))
|| ! label_is_jump_target_p (BB_HEAD (b),
BB_END (b->pred->src))))
{
if (!(mode & CLEANUP_CFGLAYOUT)
&& b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
- && GET_CODE (BB_HEAD (b)) != CODE_LABEL
+ && !LABEL_P (BB_HEAD (b))
&& FORWARDER_BLOCK_P (b)
/* Note that forwarder_block_p true ensures that
there is a successor for this block. */
else if (!(mode & CLEANUP_CFGLAYOUT)
/* If the jump insn has side effects,
we can't kill the edge. */
- && (GET_CODE (BB_END (b)) != JUMP_INSN
+ && (!JUMP_P (BB_END (b))
|| (reload_completed
? simplejump_p (BB_END (b))
: (onlyjump_p (BB_END (b))
}
if (mode & CLEANUP_CROSSJUMP)
- remove_fake_edges ();
+ remove_fake_exit_edges ();
clear_aux_for_blocks ();