ifcvt.c (cond_move_convert_if_block): New function, code factored out from...
* ifcvt.c (cond_move_convert_if_block): New function, code factored out from... (cond_move_process_if_block): ...here. Call the new function on the THEN and ELSE blocks. (merge_if_block): Do not copy global_live_at_end, merge_blocks already takes care of this. From-SVN: r120524
This commit is contained in:
parent
472017b355
commit
dc1f5a1118
|
@ -1,3 +1,12 @@
|
||||||
|
2007-01-06 Steven Bosscher <steven@gcc.gnu.org>
|
||||||
|
|
||||||
|
* ifcvt.c (cond_move_convert_if_block): New function, code
|
||||||
|
factored out from...
|
||||||
|
(cond_move_process_if_block): ...here. Call the new function
|
||||||
|
on the THEN and ELSE blocks.
|
||||||
|
(merge_if_block): Do not copy global_live_at_end, merge_blocks
|
||||||
|
already takes care of this.
|
||||||
|
|
||||||
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
PR c/19978
|
PR c/19978
|
||||||
|
|
148
gcc/ifcvt.c
148
gcc/ifcvt.c
|
@ -2466,6 +2466,70 @@ check_cond_move_block (basic_block bb, rtx *vals, rtx cond)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given a basic block BB suitable for conditional move conversion,
|
||||||
|
a condition COND, and arrays THEN_VALS and ELSE_VALS containing the
|
||||||
|
register values depending on COND, emit the insns in the block as
|
||||||
|
conditional moves. If ELSE_BLOCK is true, THEN_BB was already
|
||||||
|
processed. The caller has started a sequence for the conversion.
|
||||||
|
Return true if successful, false if something goes wrong. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cond_move_convert_if_block (struct noce_if_info *if_infop,
|
||||||
|
basic_block bb, rtx cond,
|
||||||
|
rtx *then_vals, rtx *else_vals,
|
||||||
|
bool else_block_p)
|
||||||
|
{
|
||||||
|
enum rtx_code code;
|
||||||
|
rtx insn, cond_arg0, cond_arg1;
|
||||||
|
|
||||||
|
code = GET_CODE (cond);
|
||||||
|
cond_arg0 = XEXP (cond, 0);
|
||||||
|
cond_arg1 = XEXP (cond, 1);
|
||||||
|
|
||||||
|
FOR_BB_INSNS (bb, insn)
|
||||||
|
{
|
||||||
|
rtx set, target, dest, t, e;
|
||||||
|
unsigned int regno;
|
||||||
|
|
||||||
|
if (!INSN_P (insn) || JUMP_P (insn))
|
||||||
|
continue;
|
||||||
|
set = single_set (insn);
|
||||||
|
gcc_assert (set && REG_P (SET_DEST (set)));
|
||||||
|
|
||||||
|
dest = SET_DEST (set);
|
||||||
|
regno = REGNO (dest);
|
||||||
|
|
||||||
|
t = then_vals[regno];
|
||||||
|
e = else_vals[regno];
|
||||||
|
|
||||||
|
if (else_block_p)
|
||||||
|
{
|
||||||
|
/* If this register was set in the then block, we already
|
||||||
|
handled this case there. */
|
||||||
|
if (t)
|
||||||
|
continue;
|
||||||
|
t = dest;
|
||||||
|
gcc_assert (e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gcc_assert (t);
|
||||||
|
if (!e)
|
||||||
|
e = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = noce_emit_cmove (if_infop, dest, code, cond_arg0, cond_arg1,
|
||||||
|
t, e);
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (target != dest)
|
||||||
|
noce_emit_move_insn (dest, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
|
/* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
|
||||||
using only conditional moves. Return TRUE if we were successful at
|
using only conditional moves. Return TRUE if we were successful at
|
||||||
converting the block. */
|
converting the block. */
|
||||||
|
@ -2476,11 +2540,10 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
|
||||||
basic_block then_bb = ce_info->then_bb;
|
basic_block then_bb = ce_info->then_bb;
|
||||||
basic_block else_bb = ce_info->else_bb;
|
basic_block else_bb = ce_info->else_bb;
|
||||||
struct noce_if_info if_info;
|
struct noce_if_info if_info;
|
||||||
rtx jump, cond, insn, seq, cond_arg0, cond_arg1, loc_insn;
|
rtx jump, cond, insn, seq, loc_insn;
|
||||||
int max_reg, size, c, i;
|
int max_reg, size, c, i;
|
||||||
rtx *then_vals;
|
rtx *then_vals;
|
||||||
rtx *else_vals;
|
rtx *else_vals;
|
||||||
enum rtx_code code;
|
|
||||||
|
|
||||||
if (!HAVE_conditional_move || no_new_pseudos)
|
if (!HAVE_conditional_move || no_new_pseudos)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2537,78 +2600,18 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
|
||||||
if (c > MAX_CONDITIONAL_EXECUTE)
|
if (c > MAX_CONDITIONAL_EXECUTE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Emit the conditional moves. First do the then block, then do
|
/* Try to emit the conditional moves. First do the then block,
|
||||||
anything left in the else blocks. */
|
then do anything left in the else blocks. */
|
||||||
|
|
||||||
code = GET_CODE (cond);
|
|
||||||
cond_arg0 = XEXP (cond, 0);
|
|
||||||
cond_arg1 = XEXP (cond, 1);
|
|
||||||
|
|
||||||
start_sequence ();
|
start_sequence ();
|
||||||
|
if (!cond_move_convert_if_block (&if_info, then_bb, cond,
|
||||||
FOR_BB_INSNS (then_bb, insn)
|
then_vals, else_vals, false)
|
||||||
{
|
|| (else_bb
|
||||||
rtx set, target, dest, t, e;
|
&& !cond_move_convert_if_block (&if_info, else_bb, cond,
|
||||||
unsigned int regno;
|
then_vals, else_vals, true)))
|
||||||
|
|
||||||
if (!INSN_P (insn) || JUMP_P (insn))
|
|
||||||
continue;
|
|
||||||
set = single_set (insn);
|
|
||||||
gcc_assert (set && REG_P (SET_DEST (set)));
|
|
||||||
|
|
||||||
dest = SET_DEST (set);
|
|
||||||
regno = REGNO (dest);
|
|
||||||
t = then_vals[regno];
|
|
||||||
e = else_vals[regno];
|
|
||||||
gcc_assert (t);
|
|
||||||
if (!e)
|
|
||||||
e = dest;
|
|
||||||
target = noce_emit_cmove (&if_info, dest, code, cond_arg0, cond_arg1,
|
|
||||||
t, e);
|
|
||||||
if (!target)
|
|
||||||
{
|
{
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target != dest)
|
|
||||||
noce_emit_move_insn (dest, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (else_bb)
|
|
||||||
{
|
|
||||||
FOR_BB_INSNS (else_bb, insn)
|
|
||||||
{
|
|
||||||
rtx set, target, dest;
|
|
||||||
unsigned int regno;
|
|
||||||
|
|
||||||
if (!INSN_P (insn) || JUMP_P (insn))
|
|
||||||
continue;
|
|
||||||
set = single_set (insn);
|
|
||||||
gcc_assert (set && REG_P (SET_DEST (set)));
|
|
||||||
|
|
||||||
dest = SET_DEST (set);
|
|
||||||
regno = REGNO (dest);
|
|
||||||
|
|
||||||
/* If this register was set in the then block, we already
|
|
||||||
handled this case above. */
|
|
||||||
if (then_vals[regno])
|
|
||||||
continue;
|
|
||||||
gcc_assert (else_vals[regno]);
|
|
||||||
|
|
||||||
target = noce_emit_cmove (&if_info, dest, code, cond_arg0, cond_arg1,
|
|
||||||
dest, else_vals[regno]);
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
end_sequence ();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target != dest)
|
|
||||||
noce_emit_move_insn (dest, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seq = end_ifcvt_sequence (&if_info);
|
seq = end_ifcvt_sequence (&if_info);
|
||||||
if (!seq)
|
if (!seq)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2711,9 +2714,6 @@ merge_if_block (struct ce_if_block * ce_info)
|
||||||
|
|
||||||
if (then_bb)
|
if (then_bb)
|
||||||
{
|
{
|
||||||
if (combo_bb->il.rtl->global_live_at_end)
|
|
||||||
COPY_REG_SET (combo_bb->il.rtl->global_live_at_end,
|
|
||||||
then_bb->il.rtl->global_live_at_end);
|
|
||||||
merge_blocks (combo_bb, then_bb);
|
merge_blocks (combo_bb, then_bb);
|
||||||
num_true_changes++;
|
num_true_changes++;
|
||||||
}
|
}
|
||||||
|
@ -2764,10 +2764,6 @@ merge_if_block (struct ce_if_block * ce_info)
|
||||||
&& join_bb != EXIT_BLOCK_PTR)
|
&& join_bb != EXIT_BLOCK_PTR)
|
||||||
{
|
{
|
||||||
/* We can merge the JOIN. */
|
/* We can merge the JOIN. */
|
||||||
if (combo_bb->il.rtl->global_live_at_end)
|
|
||||||
COPY_REG_SET (combo_bb->il.rtl->global_live_at_end,
|
|
||||||
join_bb->il.rtl->global_live_at_end);
|
|
||||||
|
|
||||||
merge_blocks (combo_bb, join_bb);
|
merge_blocks (combo_bb, join_bb);
|
||||||
num_true_changes++;
|
num_true_changes++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue