static void free_av_set (basic_block);
static void invalidate_av_set (basic_block);
static void extend_insn_data (void);
-static void sel_init_new_insn (insn_t, int);
+static void sel_init_new_insn (insn_t, int, int = -1);
static void finish_insns (void);
\f
/* Various list functions. */
return seqno;
}
-/* Compute seqno for INSN by its preds or succs. */
+/* Compute seqno for INSN by its preds or succs. Use OLD_SEQNO to compute
+ seqno in corner cases. */
static int
-get_seqno_for_a_jump (insn_t insn)
+get_seqno_for_a_jump (insn_t insn, int old_seqno)
{
int seqno;
if (seqno < 0)
seqno = get_seqno_by_succs (insn);
- gcc_assert (seqno >= 0);
+ if (seqno < 0)
+ {
+ /* The only case where this could be here legally is that the only
+ unscheduled insn was a conditional jump that got removed and turned
+ into this unconditional one. Initialize from the old seqno
+ of that jump passed down to here. */
+ seqno = old_seqno;
+ }
+ gcc_assert (seqno >= 0);
return seqno;
}
}
/* This is used to initialize spurious jumps generated by
- sel_redirect_edge (). */
+ sel_redirect_edge (). OLD_SEQNO is used for initializing seqnos
+ in corner cases within get_seqno_for_a_jump. */
static void
-init_simplejump_data (insn_t insn)
+init_simplejump_data (insn_t insn, int old_seqno)
{
init_expr (INSN_EXPR (insn), vinsn_create (insn, false), 0,
REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0,
vNULL, true, false, false,
false, true);
- INSN_SEQNO (insn) = get_seqno_for_a_jump (insn);
+ INSN_SEQNO (insn) = get_seqno_for_a_jump (insn, old_seqno);
init_first_time_insn_data (insn);
}
/* Perform deferred initialization of insns. This is used to process
- a new jump that may be created by redirect_edge. */
-void
-sel_init_new_insn (insn_t insn, int flags)
+ a new jump that may be created by redirect_edge. OLD_SEQNO is used
+ for initializing simplejumps in init_simplejump_data. */
+static void
+sel_init_new_insn (insn_t insn, int flags, int old_seqno)
{
/* We create data structures for bb when the first insn is emitted in it. */
if (INSN_P (insn)
if (flags & INSN_INIT_TODO_SIMPLEJUMP)
{
extend_insn_data ();
- init_simplejump_data (insn);
+ init_simplejump_data (insn, old_seqno);
}
gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn))
}
/* A wrapper for redirect_edge_and_branch_force, which also initializes
- data structures for possibly created bb and insns. Returns the newly
- added bb or NULL, when a bb was not needed. */
+ data structures for possibly created bb and insns. */
void
sel_redirect_edge_and_branch_force (edge e, basic_block to)
{
basic_block jump_bb, src, orig_dest = e->dest;
int prev_max_uid;
rtx jump;
+ int old_seqno = -1;
/* This function is now used only for bookkeeping code creation, where
we'll never get the single pred of orig_dest block and thus will not
&& !single_pred_p (orig_dest));
src = e->src;
prev_max_uid = get_max_uid ();
- jump_bb = redirect_edge_and_branch_force (e, to);
+ /* Compute and pass old_seqno down to sel_init_new_insn only for the case
+ when the conditional jump being redirected may become unconditional. */
+ if (any_condjump_p (BB_END (src))
+ && INSN_SEQNO (BB_END (src)) >= 0)
+ old_seqno = INSN_SEQNO (BB_END (src));
+ jump_bb = redirect_edge_and_branch_force (e, to);
if (jump_bb != NULL)
sel_add_bb (jump_bb);
jump = find_new_jump (src, jump_bb, prev_max_uid);
if (jump)
- sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
+ sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP,
+ old_seqno);
set_immediate_dominator (CDI_DOMINATORS, to,
recompute_dominator (CDI_DOMINATORS, to));
set_immediate_dominator (CDI_DOMINATORS, orig_dest,
edge redirected;
bool recompute_toporder_p = false;
bool maybe_unreachable = single_pred_p (orig_dest);
+ int old_seqno = -1;
latch_edge_p = (pipelining_p
&& current_loop_nest
src = e->src;
prev_max_uid = get_max_uid ();
+ /* Compute and pass old_seqno down to sel_init_new_insn only for the case
+ when the conditional jump being redirected may become unconditional. */
+ if (any_condjump_p (BB_END (src))
+ && INSN_SEQNO (BB_END (src)) >= 0)
+ old_seqno = INSN_SEQNO (BB_END (src));
+
redirected = redirect_edge_and_branch (e, to);
gcc_assert (redirected && !last_added_blocks.exists ());
jump = find_new_jump (src, NULL, prev_max_uid);
if (jump)
- sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
+ sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP, old_seqno);
/* Only update dominator info when we don't have unreachable blocks.
Otherwise we'll update in maybe_tidy_empty_bb. */