diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2007-01-06 13:56:53 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2007-01-06 13:56:53 +0000 |
commit | dc1f5a111805364e5311333cb2d0e7522034a258 (patch) | |
tree | 2fc0af3f16201a5d3813eb323564312466a358f8 /gcc | |
parent | 472017b355ded38484c1e957312791fef1965cfa (diff) | |
download | gcc-dc1f5a111805364e5311333cb2d0e7522034a258.zip gcc-dc1f5a111805364e5311333cb2d0e7522034a258.tar.gz gcc-dc1f5a111805364e5311333cb2d0e7522034a258.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/ifcvt.c | 152 |
2 files changed, 83 insertions, 78 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b0bbd5..2623d7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> PR c/19978 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index b869092..553d69d 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -2466,6 +2466,70 @@ check_cond_move_block (basic_block bb, rtx *vals, rtx cond) 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 using only conditional moves. Return TRUE if we were successful at 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 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 +2600,18 @@ cond_move_process_if_block (struct ce_if_block *ce_info) 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) + 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))) { - 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) - { - 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 +2714,6 @@ merge_if_block (struct ce_if_block * ce_info) 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 +2764,6 @@ merge_if_block (struct ce_if_block * ce_info) && 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++; } |