diff options
Diffstat (limited to 'gcc-4.9/gcc/sel-sched-ir.c')
-rw-r--r-- | gcc-4.9/gcc/sel-sched-ir.c | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/gcc-4.9/gcc/sel-sched-ir.c b/gcc-4.9/gcc/sel-sched-ir.c index f5a4ee035..e1408b488 100644 --- a/gcc-4.9/gcc/sel-sched-ir.c +++ b/gcc-4.9/gcc/sel-sched-ir.c @@ -162,7 +162,7 @@ static void create_initial_data_sets (basic_block); 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); /* Various list functions. */ @@ -4007,9 +4007,10 @@ get_seqno_by_succs (rtx insn) 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; @@ -4065,8 +4066,16 @@ get_seqno_for_a_jump (insn_t insn) 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; } @@ -4246,22 +4255,24 @@ init_insn_data (insn_t insn) } /* 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) @@ -4288,7 +4299,7 @@ sel_init_new_insn (insn_t insn, int flags) 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)) @@ -5575,14 +5586,14 @@ sel_merge_blocks (basic_block a, basic_block b) } /* 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 @@ -5591,8 +5602,13 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to) && !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); @@ -5604,7 +5620,8 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to) 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, @@ -5623,6 +5640,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to) 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 @@ -5631,6 +5649,12 @@ sel_redirect_edge_and_branch (edge e, basic_block to) 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 ()); @@ -5651,7 +5675,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to) 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. */ |