* [PATCH] Clean up ifcvt.c a bit
@ 2007-01-06 13:22 Steven Bosscher
2007-01-06 13:45 ` Richard Guenther
0 siblings, 1 reply; 2+ messages in thread
From: Steven Bosscher @ 2007-01-06 13:22 UTC (permalink / raw)
To: gcc-patches; +Cc: Ian Lance Taylor
Hello,
This is the first of (probably) a few patches to clean up ifcvt.c to
make it ready for working in cfglayout mode.
The first part of this patch just factors nearly identical code into
a new function.
The second part stops us from copying global_live_at_end. We don't
have to do this, because merge_blocks already takes care of it.
Bootstrapped (c,c++,objc,fortran) + tested on x86-64-unknown-linux-gnu.
OK for trunk?
Gr.
Steven
* 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.
Index: ifcvt.c
===================================================================
--- ifcvt.c (revision 120520)
+++ ifcvt.c (working copy)
@@ -2466,6 +2495,70 @@ check_cond_move_block (basic_block bb, r
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_BLOCK was already
+ processed. The parent 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
using only conditional moves. Return TRUE if we were successful at
converting the block. */
@@ -2476,11 +2569,10 @@ cond_move_process_if_block (struct ce_if
basic_block then_bb = ce_info->then_bb;
basic_block else_bb = ce_info->else_bb;
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;
rtx *then_vals;
rtx *else_vals;
- enum rtx_code code;
if (!HAVE_conditional_move || no_new_pseudos)
return FALSE;
@@ -2537,78 +2629,18 @@ cond_move_process_if_block (struct ce_if
if (c > MAX_CONDITIONAL_EXECUTE)
return FALSE;
- /* Emit the conditional moves. First do the then block, then do
- anything left in the else blocks. */
-
- code = GET_CODE (cond);
- cond_arg0 = XEXP (cond, 0);
- cond_arg1 = XEXP (cond, 1);
-
+ /* Try to emit the conditional moves. First do the then block,
+ then do anything left in the else blocks. */
start_sequence ();
-
- FOR_BB_INSNS (then_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];
- 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 ();
- return FALSE;
- }
-
- if (target != dest)
- noce_emit_move_insn (dest, target);
- }
-
- if (else_bb)
+ if (!cond_move_convert_if_block (&if_info, then_bb, cond,
+ then_vals, else_vals, false)
+ || (else_bb
+ && !cond_move_convert_if_block (&if_info, else_bb, cond,
+ then_vals, else_vals, true)))
{
- 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);
- }
+ end_sequence ();
+ return FALSE;
}
-
seq = end_ifcvt_sequence (&if_info);
if (!seq)
return FALSE;
@@ -2711,9 +2743,6 @@ merge_if_block (struct ce_if_block * ce_
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);
num_true_changes++;
}
@@ -2764,10 +2793,6 @@ merge_if_block (struct ce_if_block * ce_
&& join_bb != EXIT_BLOCK_PTR)
{
/* 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);
num_true_changes++;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Clean up ifcvt.c a bit
2007-01-06 13:22 [PATCH] Clean up ifcvt.c a bit Steven Bosscher
@ 2007-01-06 13:45 ` Richard Guenther
0 siblings, 0 replies; 2+ messages in thread
From: Richard Guenther @ 2007-01-06 13:45 UTC (permalink / raw)
To: Steven Bosscher; +Cc: gcc-patches, Ian Lance Taylor
On 1/6/07, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> Hello,
>
> This is the first of (probably) a few patches to clean up ifcvt.c to
> make it ready for working in cfglayout mode.
>
> The first part of this patch just factors nearly identical code into
> a new function.
> The second part stops us from copying global_live_at_end. We don't
> have to do this, because merge_blocks already takes care of it.
>
> Bootstrapped (c,c++,objc,fortran) + tested on x86-64-unknown-linux-gnu.
> OK for trunk?
This is ok.
Thanks,
Richard.
> Gr.
> Steven
>
> * 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.
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-01-06 13:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-06 13:22 [PATCH] Clean up ifcvt.c a bit Steven Bosscher
2007-01-06 13:45 ` Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).