Commit 92e265ac by Andrey Belevantsev Committed by Andrey Belevantsev

re PR rtl-optimization/60866 (ICE: in get_seqno_for_a_jump, at…

re PR rtl-optimization/60866 (ICE: in get_seqno_for_a_jump, at sel-sched-ir.c:4068 with -fselective-scheduling -fno-if-conversion)

        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: r210420
parent fa96aa45
2014-05-14 Andrey Belevantsev <abel@ispras.ru>
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-05-14 Georg-Johann Lay <avr@gjlay.de> 2014-05-14 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.h (REG_CLASS_CONTENTS): Use unsigned suffix for * config/avr/avr.h (REG_CLASS_CONTENTS): Use unsigned suffix for
......
...@@ -162,7 +162,7 @@ static void create_initial_data_sets (basic_block); ...@@ -162,7 +162,7 @@ static void create_initial_data_sets (basic_block);
static void free_av_set (basic_block); static void free_av_set (basic_block);
static void invalidate_av_set (basic_block); static void invalidate_av_set (basic_block);
static void extend_insn_data (void); 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); static void finish_insns (void);
/* Various list functions. */ /* Various list functions. */
...@@ -4007,9 +4007,10 @@ get_seqno_by_succs (rtx insn) ...@@ -4007,9 +4007,10 @@ get_seqno_by_succs (rtx insn)
return seqno; 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 static int
get_seqno_for_a_jump (insn_t insn) get_seqno_for_a_jump (insn_t insn, int old_seqno)
{ {
int seqno; int seqno;
...@@ -4065,8 +4066,16 @@ get_seqno_for_a_jump (insn_t insn) ...@@ -4065,8 +4066,16 @@ get_seqno_for_a_jump (insn_t insn)
if (seqno < 0) if (seqno < 0)
seqno = get_seqno_by_succs (insn); 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; return seqno;
} }
...@@ -4246,22 +4255,24 @@ init_insn_data (insn_t insn) ...@@ -4246,22 +4255,24 @@ init_insn_data (insn_t insn)
} }
/* This is used to initialize spurious jumps generated by /* 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 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, init_expr (INSN_EXPR (insn), vinsn_create (insn, false), 0,
REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0, REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0,
vNULL, true, false, false, vNULL, true, false, false,
false, true); 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); init_first_time_insn_data (insn);
} }
/* Perform deferred initialization of insns. This is used to process /* Perform deferred initialization of insns. This is used to process
a new jump that may be created by redirect_edge. */ a new jump that may be created by redirect_edge. OLD_SEQNO is used
void for initializing simplejumps in init_simplejump_data. */
sel_init_new_insn (insn_t insn, int flags) 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. */ /* We create data structures for bb when the first insn is emitted in it. */
if (INSN_P (insn) if (INSN_P (insn)
...@@ -4288,7 +4299,7 @@ sel_init_new_insn (insn_t insn, int flags) ...@@ -4288,7 +4299,7 @@ sel_init_new_insn (insn_t insn, int flags)
if (flags & INSN_INIT_TODO_SIMPLEJUMP) if (flags & INSN_INIT_TODO_SIMPLEJUMP)
{ {
extend_insn_data (); extend_insn_data ();
init_simplejump_data (insn); init_simplejump_data (insn, old_seqno);
} }
gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn)) gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn))
...@@ -5575,14 +5586,14 @@ sel_merge_blocks (basic_block a, basic_block b) ...@@ -5575,14 +5586,14 @@ sel_merge_blocks (basic_block a, basic_block b)
} }
/* A wrapper for redirect_edge_and_branch_force, which also initializes /* A wrapper for redirect_edge_and_branch_force, which also initializes
data structures for possibly created bb and insns. Returns the newly data structures for possibly created bb and insns. */
added bb or NULL, when a bb was not needed. */
void void
sel_redirect_edge_and_branch_force (edge e, basic_block to) sel_redirect_edge_and_branch_force (edge e, basic_block to)
{ {
basic_block jump_bb, src, orig_dest = e->dest; basic_block jump_bb, src, orig_dest = e->dest;
int prev_max_uid; int prev_max_uid;
rtx jump; rtx jump;
int old_seqno = -1;
/* This function is now used only for bookkeeping code creation, where /* 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 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) ...@@ -5591,8 +5602,13 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to)
&& !single_pred_p (orig_dest)); && !single_pred_p (orig_dest));
src = e->src; src = e->src;
prev_max_uid = get_max_uid (); 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) if (jump_bb != NULL)
sel_add_bb (jump_bb); sel_add_bb (jump_bb);
...@@ -5604,7 +5620,8 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to) ...@@ -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); jump = find_new_jump (src, jump_bb, prev_max_uid);
if (jump) 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, set_immediate_dominator (CDI_DOMINATORS, to,
recompute_dominator (CDI_DOMINATORS, to)); recompute_dominator (CDI_DOMINATORS, to));
set_immediate_dominator (CDI_DOMINATORS, orig_dest, set_immediate_dominator (CDI_DOMINATORS, orig_dest,
...@@ -5623,6 +5640,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to) ...@@ -5623,6 +5640,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
edge redirected; edge redirected;
bool recompute_toporder_p = false; bool recompute_toporder_p = false;
bool maybe_unreachable = single_pred_p (orig_dest); bool maybe_unreachable = single_pred_p (orig_dest);
int old_seqno = -1;
latch_edge_p = (pipelining_p latch_edge_p = (pipelining_p
&& current_loop_nest && current_loop_nest
...@@ -5631,6 +5649,12 @@ sel_redirect_edge_and_branch (edge e, basic_block to) ...@@ -5631,6 +5649,12 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
src = e->src; src = e->src;
prev_max_uid = get_max_uid (); 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); redirected = redirect_edge_and_branch (e, to);
gcc_assert (redirected && !last_added_blocks.exists ()); gcc_assert (redirected && !last_added_blocks.exists ());
...@@ -5651,7 +5675,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to) ...@@ -5651,7 +5675,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
jump = find_new_jump (src, NULL, prev_max_uid); jump = find_new_jump (src, NULL, prev_max_uid);
if (jump) 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. /* Only update dominator info when we don't have unreachable blocks.
Otherwise we'll update in maybe_tidy_empty_bb. */ Otherwise we'll update in maybe_tidy_empty_bb. */
......
2014-05-14 Andrey Belevantsev <abel@ispras.ru> 2014-05-14 Andrey Belevantsev <abel@ispras.ru>
PR rtl-optimization/60866
* gcc.dg/pr60866.c: New test.
2014-05-14 Andrey Belevantsev <abel@ispras.ru>
PR rtl-optimization/60901 PR rtl-optimization/60901
* gcc.target/i386/pr60901.c: New test. * gcc.target/i386/pr60901.c: New test.
......
/* { 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)
;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment