From: Andrey Belevantsev Date: Tue, 3 Jun 2014 09:25:39 +0000 (+0400) Subject: backport: re PR rtl-optimization/60866 (ICE: in get_seqno_for_a_jump, at sel-sched... X-Git-Tag: releases/gcc-4.8.4~434 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d7c456c6421a0d25d41691b22658c444f097eb7;p=thirdparty%2Fgcc.git backport: re PR rtl-optimization/60866 (ICE: in get_seqno_for_a_jump, at sel-sched-ir.c:4068 with -fselective-scheduling -fno-if-conversion) Backport from mainline 2014-05-14 Andrey Belevantsev PR rtl-optimization/60866 * sel-sched-ir (sel_init_new_insn): New parameter old_seqno. Default it to -1. Pass it down to init_simplejump_data. (init_simplejump_data): New parameter old_seqno. Pass it down to get_seqno_for_a_jump. (get_seqno_for_a_jump): New parameter old_seqno. Use it for initializing new jump seqno as a last resort. Add comment. (sel_redirect_edge_and_branch): Save old seqno of the conditional jump and pass it down to sel_init_new_insn. (sel_redirect_edge_and_branch_force): Likewise. * gcc.dg/pr60866.c: New test. From-SVN: r211165 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 278e13316cd9..343050c0d0a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2014-06-03 Andrey Belevantsev + + Backport from mainline + 2014-05-14 Andrey Belevantsev + + PR rtl-optimization/60866 + * sel-sched-ir (sel_init_new_insn): New parameter old_seqno. + Default it to -1. Pass it down to init_simplejump_data. + (init_simplejump_data): New parameter old_seqno. Pass it down + to get_seqno_for_a_jump. + (get_seqno_for_a_jump): New parameter old_seqno. Use it for + initializing new jump seqno as a last resort. Add comment. + (sel_redirect_edge_and_branch): Save old seqno of the conditional + jump and pass it down to sel_init_new_insn. + (sel_redirect_edge_and_branch_force): Likewise. + 2014-06-03 Andrey Belevantsev Backport from mainline diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 91e91ec37fd6..6aa1904f4280 100644 --- a/gcc/sel-sched-ir.c +++ b/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. */ @@ -4011,9 +4011,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; @@ -4069,8 +4070,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; } @@ -4250,22 +4259,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) @@ -4292,7 +4303,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)) @@ -5578,14 +5589,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 @@ -5594,8 +5605,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); @@ -5607,7 +5623,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, @@ -5626,6 +5643,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 @@ -5634,6 +5652,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 ()); @@ -5654,7 +5678,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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a165e84e458a..0bba1d568019 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2014-06-03 Andrey Belevantsev + + Backport from mainline + 2014-05-14 Andrey Belevantsev + + PR rtl-optimization/60866 + * gcc.dg/pr60866.c: New test. + 2014-06-03 Andrey Belevantsev Backport from mainline diff --git a/gcc/testsuite/gcc.dg/pr60866.c b/gcc/testsuite/gcc.dg/pr60866.c new file mode 100644 index 000000000000..020878d41de0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr60866.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */ +/* { dg-options "-O -fselective-scheduling -fno-if-conversion -fschedule-insns" } */ + +int n; + +void +foo (int w, int **dnroot, int **dn) +{ + int *child; + int *xchild = xchild; + for (; w < n; w++) + if (!dnroot) + { + dnroot = dn; + for (child = *dn; child; child = xchild) + ; + } +}