re PR rtl-optimization/26254 (FAIL: gcc.c-torture/compile/20011109-1.c,-O1)
PR rtl-optimization/26254 * loop-invariant.c (seq_insns_valid_p): New function. (move_invariant_reg): Only emit new code if it is valid. From-SVN: r111998
This commit is contained in:
parent
96e82e0a8a
commit
ba9462095c
@ -1,3 +1,9 @@
|
|||||||
|
2006-03-13 Zdenek Dvorak <dvorakz@suse.cz>
|
||||||
|
|
||||||
|
PR rtl-optimization/26254
|
||||||
|
* loop-invariant.c (seq_insns_valid_p): New function.
|
||||||
|
(move_invariant_reg): Only emit new code if it is valid.
|
||||||
|
|
||||||
2006-03-13 Zdenek Dvorak <dvorakz@suse.cz>
|
2006-03-13 Zdenek Dvorak <dvorakz@suse.cz>
|
||||||
|
|
||||||
* cfgrtl.c (last_loop_beg_note, back_edge_of_syntactic_loop_p):
|
* cfgrtl.c (last_loop_beg_note, back_edge_of_syntactic_loop_p):
|
||||||
|
@ -1109,22 +1109,38 @@ find_invariants_to_move (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move invariant INVNO out of the LOOP. */
|
/* Returns true if all insns in SEQ are valid. */
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
|
seq_insns_valid_p (rtx seq)
|
||||||
|
{
|
||||||
|
rtx x;
|
||||||
|
|
||||||
|
for (x = seq; x; x = NEXT_INSN (x))
|
||||||
|
if (insn_invalid_p (x))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move invariant INVNO out of the LOOP. Returns true if this succeeds, false
|
||||||
|
otherwise. */
|
||||||
|
|
||||||
|
static bool
|
||||||
move_invariant_reg (struct loop *loop, unsigned invno)
|
move_invariant_reg (struct loop *loop, unsigned invno)
|
||||||
{
|
{
|
||||||
struct invariant *inv = VEC_index (invariant_p, invariants, invno);
|
struct invariant *inv = VEC_index (invariant_p, invariants, invno);
|
||||||
struct invariant *repr = VEC_index (invariant_p, invariants, inv->eqto);
|
struct invariant *repr = VEC_index (invariant_p, invariants, inv->eqto);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
basic_block preheader = loop_preheader_edge (loop)->src;
|
basic_block preheader = loop_preheader_edge (loop)->src;
|
||||||
rtx reg, set, seq, op;
|
rtx reg, set, dest, seq, op;
|
||||||
struct use *use;
|
struct use *use;
|
||||||
bitmap_iterator bi;
|
bitmap_iterator bi;
|
||||||
|
|
||||||
if (inv->reg
|
if (inv->reg)
|
||||||
|| !repr->move)
|
return true;
|
||||||
return;
|
if (!repr->move)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* If this is a representative of the class of equivalent invariants,
|
/* If this is a representative of the class of equivalent invariants,
|
||||||
really move the invariant. Otherwise just replace its use with
|
really move the invariant. Otherwise just replace its use with
|
||||||
@ -1135,7 +1151,8 @@ move_invariant_reg (struct loop *loop, unsigned invno)
|
|||||||
{
|
{
|
||||||
EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i, bi)
|
EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i, bi)
|
||||||
{
|
{
|
||||||
move_invariant_reg (loop, i);
|
if (!move_invariant_reg (loop, i))
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,14 +1162,15 @@ move_invariant_reg (struct loop *loop, unsigned invno)
|
|||||||
would not be dominated by it, we may just move it (TODO). Otherwise we
|
would not be dominated by it, we may just move it (TODO). Otherwise we
|
||||||
need to create a temporary register. */
|
need to create a temporary register. */
|
||||||
set = single_set (inv->insn);
|
set = single_set (inv->insn);
|
||||||
reg = gen_reg_rtx (GET_MODE (SET_DEST (set)));
|
dest = SET_DEST (set);
|
||||||
emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
|
reg = gen_reg_rtx (GET_MODE (dest));
|
||||||
|
|
||||||
/* If the SET_DEST of the invariant insn is a reg, we can just move
|
/* If the SET_DEST of the invariant insn is a pseudo, we can just move
|
||||||
the insn out of the loop. Otherwise, we have to use gen_move_insn
|
the insn out of the loop. Otherwise, we have to use gen_move_insn
|
||||||
to let emit_move_insn produce a valid instruction stream. */
|
to let emit_move_insn produce a valid instruction stream. */
|
||||||
if (REG_P (SET_DEST (set)))
|
if (REG_P (dest) && !HARD_REGISTER_P (dest))
|
||||||
{
|
{
|
||||||
|
emit_insn_after (gen_move_insn (dest, reg), inv->insn);
|
||||||
SET_DEST (set) = reg;
|
SET_DEST (set) = reg;
|
||||||
reorder_insns (inv->insn, inv->insn, BB_END (preheader));
|
reorder_insns (inv->insn, inv->insn, BB_END (preheader));
|
||||||
}
|
}
|
||||||
@ -1165,13 +1183,18 @@ move_invariant_reg (struct loop *loop, unsigned invno)
|
|||||||
seq = get_insns ();
|
seq = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
|
if (!seq_insns_valid_p (seq))
|
||||||
|
goto fail;
|
||||||
emit_insn_after (seq, BB_END (preheader));
|
emit_insn_after (seq, BB_END (preheader));
|
||||||
|
|
||||||
|
emit_insn_after (gen_move_insn (dest, reg), inv->insn);
|
||||||
delete_insn (inv->insn);
|
delete_insn (inv->insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
move_invariant_reg (loop, repr->invno);
|
if (!move_invariant_reg (loop, repr->invno))
|
||||||
|
goto fail;
|
||||||
reg = repr->reg;
|
reg = repr->reg;
|
||||||
set = single_set (inv->insn);
|
set = single_set (inv->insn);
|
||||||
emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
|
emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
|
||||||
@ -1188,6 +1211,17 @@ move_invariant_reg (struct loop *loop, unsigned invno)
|
|||||||
for (use = inv->def->uses; use; use = use->next)
|
for (use = inv->def->uses; use; use = use->next)
|
||||||
*use->pos = reg;
|
*use->pos = reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* If we failed, clear move flag, so that we do not try to move inv
|
||||||
|
again. */
|
||||||
|
if (dump_file)
|
||||||
|
fprintf (dump_file, "Failed to move invariant %d\n", invno);
|
||||||
|
inv->move = false;
|
||||||
|
inv->reg = NULL_RTX;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move selected invariant out of the LOOP. Newly created regs are marked
|
/* Move selected invariant out of the LOOP. Newly created regs are marked
|
||||||
|
Loading…
Reference in New Issue
Block a user