Commit 324d3f45 by Alexander Monakov

re PR rtl-optimization/44919 (ICE on ia64 with -O3 at sel-sched.c:4672)

	PR rtl-optimization/44919
	* sel-sched.c (move_cond_jump): Remove assert, check that
	the several blocks case can only happen with mutually exclusive
	insns instead.  Rewrite the movement code to support moving through
	several basic blocks. 

	* g++.dg/opt/pr44919.C: New.

From-SVN: r163904
parent 7b74bb63
2010-09-06 Andrey Belevantsev <abel@ispras.ru>
PR rtl-optimization/44919
* sel-sched.c (move_cond_jump): Remove assert, check that
the several blocks case can only happen with mutually exclusive
insns instead. Rewrite the movement code to support moving through
several basic blocks.
2010-09-06 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (iptrsize): New mode attribute.
......
......@@ -4875,18 +4875,35 @@ static void
move_cond_jump (rtx insn, bnd_t bnd)
{
edge ft_edge;
basic_block block_from, block_next, block_new;
rtx next, prev, link;
basic_block block_from, block_next, block_new, block_bnd, bb;
rtx next, prev, link, head;
/* BLOCK_FROM holds basic block of the jump. */
block_from = BLOCK_FOR_INSN (insn);
block_bnd = BLOCK_FOR_INSN (BND_TO (bnd));
prev = BND_TO (bnd);
/* Moving of jump should not cross any other jumps or
beginnings of new basic blocks. */
gcc_assert (block_from == BLOCK_FOR_INSN (BND_TO (bnd)));
#ifdef ENABLE_CHECKING
/* Moving of jump should not cross any other jumps or beginnings of new
basic blocks. The only exception is when we move a jump through
mutually exclusive insns along fallthru edges. */
if (block_from != block_bnd)
{
bb = block_from;
for (link = PREV_INSN (insn); link != PREV_INSN (prev);
link = PREV_INSN (link))
{
if (INSN_P (link))
gcc_assert (sched_insns_conditions_mutex_p (insn, link));
if (BLOCK_FOR_INSN (link) && BLOCK_FOR_INSN (link) != bb)
{
gcc_assert (single_pred (bb) == BLOCK_FOR_INSN (link));
bb = BLOCK_FOR_INSN (link);
}
}
}
#endif
/* Jump is moved to the boundary. */
prev = BND_TO (bnd);
next = PREV_INSN (insn);
BND_TO (bnd) = insn;
......@@ -4901,28 +4918,35 @@ move_cond_jump (rtx insn, bnd_t bnd)
gcc_assert (block_new->next_bb == block_next
&& block_from->next_bb == block_new);
gcc_assert (BB_END (block_from) == insn);
/* Move all instructions except INSN to BLOCK_NEW. */
bb = block_bnd;
head = BB_HEAD (block_new);
while (bb != block_from->next_bb)
{
rtx from, to;
from = bb == block_bnd ? prev : sel_bb_head (bb);
to = bb == block_from ? next : sel_bb_end (bb);
/* Move all instructions except INSN from BLOCK_FROM to
BLOCK_NEW. */
for (link = prev; link != insn; link = NEXT_INSN (link))
/* The jump being moved can be the first insn in the block.
In this case we don't have to move anything in this block. */
if (NEXT_INSN (to) != from)
{
reorder_insns (from, to, head);
for (link = to; link != head; link = PREV_INSN (link))
EXPR_ORIG_BB_INDEX (INSN_EXPR (link)) = block_new->index;
df_insn_change_bb (link, block_new);
head = to;
}
/* Set correct basic block and instructions properties. */
BB_END (block_new) = PREV_INSN (insn);
NEXT_INSN (PREV_INSN (prev)) = insn;
PREV_INSN (insn) = PREV_INSN (prev);
/* Cleanup possibly empty blocks left. */
block_next = bb->next_bb;
if (bb != block_from)
maybe_tidy_empty_bb (bb);
bb = block_next;
}
/* Assert there is no jump to BLOCK_NEW, only fallthrough edge. */
gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (block_new)));
PREV_INSN (prev) = BB_HEAD (block_new);
NEXT_INSN (next) = NEXT_INSN (BB_HEAD (block_new));
NEXT_INSN (BB_HEAD (block_new)) = prev;
PREV_INSN (NEXT_INSN (next)) = next;
gcc_assert (!sel_bb_empty_p (block_from)
&& !sel_bb_empty_p (block_new));
......
2010-09-06 Alexander Monakov <amonakov@ispras.ru>
PR rtl-optimization/44919
* g++.dg/opt/pr44919.C: New.
2010-09-06 Tobias Burnus <burnus@net-b.de>
PR fortran/38282
......
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