Commit 632ac2b4 by Eric Christopher Committed by Eric Christopher

ifcvt.c: Include vec.h, vecprim.h.

2007-01-15  Eric Christopher  <echristo@apple.com>

        * ifcvt.c: Include vec.h, vecprim.h.
        (check_cond_move_block): New argument regs.
        Reorganize. Add registers used to regs.
        (cond_move_process_if_block): Use regs set above as
        loop bounds.

From-SVN: r120822
parent 02168f73
2007-01-15 Eric Christopher <echristo@apple.com>
* ifcvt.c: Include vec.h, vecprim.h.
(check_cond_move_block): New argument regs.
Reorganize. Add registers used to regs.
(cond_move_process_if_block): Use regs set above as
loop bounds.
2007-01-15 Eric Christopher <echristo@apple.com>
* config/darwin.h: Update copyright.
(TARGET_OPTION_TRANSLATE_TABLE): Add umbrella.
(LINK_COMMAND_SPEC): Add -u.
......
......@@ -43,6 +43,8 @@
#include "target.h"
#include "timevar.h"
#include "tree-pass.h"
#include "vec.h"
#include "vecprim.h"
#ifndef HAVE_conditional_execution
......@@ -2431,14 +2433,20 @@ noce_process_if_block (struct ce_if_block * ce_info)
/* Check whether a block is suitable for conditional move conversion.
Every insn must be a simple set of a register to a constant or a
register. For each assignment, store the value in the array VALS,
indexed by register number. COND is the condition we will
test. */
indexed by register number, then store the register number in
REGS. COND is the condition we will test. */
static int
check_cond_move_block (basic_block bb, rtx *vals, rtx cond)
check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) *regs, rtx cond)
{
rtx insn;
/* We can only handle simple jumps at the end of the basic block.
It is almost impossible to update the CFG otherwise. */
insn = BB_END (bb);
if (JUMP_P (insn) && !onlyjump_p (insn))
return FALSE;
FOR_BB_INSNS (bb, insn)
{
rtx set, dest, src;
......@@ -2482,20 +2490,16 @@ check_cond_move_block (basic_block bb, rtx *vals, rtx cond)
if (reg_overlap_mentioned_p (dest, cond))
return FALSE;
vals[REGNO (dest)] = src;
/* Don't try to handle this if the source register is modified
later in the block. */
if (!CONSTANT_P (src)
&& modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
return FALSE;
}
/* We can only handle simple jumps at the end of the basic block.
It is almost impossible to update the CFG otherwise. */
insn = BB_END (bb);
if (JUMP_P (insn) && ! onlyjump_p (insn))
return FALSE;
vals[REGNO (dest)] = src;
VEC_safe_push (int, heap, regs, REGNO (dest));
}
return TRUE;
}
......@@ -2577,9 +2581,12 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
basic_block join_bb;
struct noce_if_info if_info;
rtx jump, cond, seq, loc_insn;
int max_reg, size, c, i;
int max_reg, size, c, reg;
rtx *then_vals;
rtx *else_vals;
VEC (int, heap) *then_regs = NULL;
VEC (int, heap) *else_regs = NULL;
unsigned int i;
if (!HAVE_conditional_move || no_new_pseudos)
return FALSE;
......@@ -2602,8 +2609,8 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
memset (else_vals, 0, size);
/* Make sure the blocks are suitable. */
if (!check_cond_move_block (then_bb, then_vals, cond)
|| (else_bb && !check_cond_move_block (else_bb, else_vals, cond)))
if (!check_cond_move_block (then_bb, then_vals, then_regs, cond)
|| (else_bb && !check_cond_move_block (else_bb, else_vals, else_regs, cond)))
return FALSE;
/* Make sure the blocks can be used together. If the same register
......@@ -2613,22 +2620,27 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
source register does not change after the assignment. Also count
the number of registers set in only one of the blocks. */
c = 0;
for (i = 0; i <= max_reg; ++i)
for (i = 0; VEC_iterate (int, then_regs, i, reg); i++)
{
if (!then_vals[i] && !else_vals[i])
if (!then_vals[reg] && !else_vals[reg])
continue;
if (!then_vals[i] || !else_vals[i])
if (!else_vals[reg])
++c;
else
{
if (!CONSTANT_P (then_vals[i])
&& !CONSTANT_P (else_vals[i])
&& !rtx_equal_p (then_vals[i], else_vals[i]))
if (!CONSTANT_P (then_vals[reg])
&& !CONSTANT_P (else_vals[reg])
&& !rtx_equal_p (then_vals[reg], else_vals[reg]))
return FALSE;
}
}
/* Finish off c for MAX_CONDITIONAL_EXECUTE. */
for (i = 0; VEC_iterate (int, else_regs, i, reg); ++i)
if (!then_vals[reg])
++c;
/* Make sure it is reasonable to convert this block. What matters
is the number of assignments currently made in only one of the
branches, since if we convert we are going to always execute
......@@ -2681,6 +2693,10 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
}
num_updated_if_blocks++;
VEC_free (int, heap, then_regs);
VEC_free (int, heap, else_regs);
return TRUE;
}
......@@ -4098,5 +4114,3 @@ struct tree_opt_pass pass_if_after_reload =
TODO_ggc_collect, /* todo_flags_finish */
'E' /* letter */
};
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