/* If-conversion support.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
#ifndef HAVE_trap
#define HAVE_trap 0
#endif
-#ifndef HAVE_conditional_trap
-#define HAVE_conditional_trap 0
-#endif
#ifndef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE \
build the store_flag insn directly. */
if (cond_complex)
- cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0);
+ {
+ rtx set = pc_set (if_info->jump);
+ cond = XEXP (SET_SRC (set), 0);
+ if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
+ && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump))
+ reversep = !reversep;
+ if (if_info->then_else_reversed)
+ reversep = !reversep;
+ }
if (reversep)
code = reversed_comparison_code (cond, if_info->jump);
int reversep;
rtx target, seq;
- if (GET_CODE (if_info->b) == CONST_INT
+ if (CONST_INT_P (if_info->b)
&& INTVAL (if_info->b) == STORE_FLAG_VALUE
&& if_info->a == const0_rtx)
reversep = 0;
else if (if_info->b == const0_rtx
- && GET_CODE (if_info->a) == CONST_INT
+ && CONST_INT_P (if_info->a)
&& INTVAL (if_info->a) == STORE_FLAG_VALUE
&& (reversed_comparison_code (if_info->cond, if_info->jump)
!= UNKNOWN))
int normalize, can_reverse;
enum machine_mode mode;
- if (GET_CODE (if_info->a) == CONST_INT
- && GET_CODE (if_info->b) == CONST_INT)
+ if (CONST_INT_P (if_info->a)
+ && CONST_INT_P (if_info->b))
{
mode = GET_MODE (if_info->x);
ifalse = INTVAL (if_info->a);
make equivalent types of changes) to get the constants we need
if they're off by one in the right direction. */
- if (GET_CODE (target) == CONST_INT)
+ if (CONST_INT_P (target))
{
enum rtx_code code = GET_CODE (if_info->cond);
rtx op_a = XEXP (if_info->cond, 0);
rtx src = find_reg_equal_equiv_note (prev_insn);
if (!src)
src = SET_SRC (PATTERN (prev_insn));
- if (GET_CODE (src) == CONST_INT)
+ if (CONST_INT_P (src))
{
if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn))))
op_a = src;
else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
op_b = src;
- if (GET_CODE (op_a) == CONST_INT)
+ if (CONST_INT_P (op_a))
{
rtx tmp = op_a;
op_a = op_b;
/* Now, look to see if we can get the right constant by
adjusting the conditional. */
- if (GET_CODE (op_b) == CONST_INT)
+ if (CONST_INT_P (op_b))
{
HOST_WIDE_INT desired_val = INTVAL (target);
HOST_WIDE_INT actual_val = INTVAL (op_b);
rtx cond, t, m, c, seq;
enum machine_mode mode;
enum rtx_code code;
- bool b_unconditional;
+ bool t_unconditional;
cond = if_info->cond;
code = GET_CODE (cond);
if (GET_MODE (m) != mode)
return FALSE;
- /* This is only profitable if T is cheap, or T is unconditionally
- executed/evaluated in the original insn sequence. The latter
- happens if INSN_B was taken from TEST_BB, or if there was no
- INSN_B which can happen for e.g. conditional stores to memory. */
- b_unconditional = (if_info->insn_b == NULL_RTX
- || BLOCK_FOR_INSN (if_info->insn_b) == if_info->test_bb);
- if (rtx_cost (t, SET, optimize_bb_for_speed_p (BLOCK_FOR_INSN (if_info->insn_b)))
- >= COSTS_N_INSNS (2)
- && (!b_unconditional
- || t != if_info->b))
+ /* This is only profitable if T is unconditionally executed/evaluated in the
+ original insn sequence or T is cheap. The former happens if B is the
+ non-zero (T) value and if INSN_B was taken from TEST_BB, or there was no
+ INSN_B which can happen for e.g. conditional stores to memory. For the
+ cost computation use the block TEST_BB where the evaluation will end up
+ after the transformation. */
+ t_unconditional =
+ (t == if_info->b
+ && (if_info->insn_b == NULL_RTX
+ || BLOCK_FOR_INSN (if_info->insn_b) == if_info->test_bb));
+ if (!(t_unconditional
+ || (rtx_cost (t, SET, optimize_bb_for_speed_p (if_info->test_bb))
+ < COSTS_N_INSNS (2))))
return FALSE;
start_sequence ();
if (GET_CODE (cond) == ZERO_EXTRACT)
{
if (XEXP (cond, 1) != const1_rtx
- || GET_CODE (XEXP (cond, 2)) != CONST_INT
+ || !CONST_INT_P (XEXP (cond, 2))
|| ! rtx_equal_p (x, XEXP (cond, 0)))
return FALSE;
bitnum = INTVAL (XEXP (cond, 2));
{
/* Check for "if (X & C) x = x op C". */
if (! rtx_equal_p (x, XEXP (a, 0))
- || GET_CODE (XEXP (a, 1)) != CONST_INT
+ || !CONST_INT_P (XEXP (a, 1))
|| (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
!= (unsigned HOST_WIDE_INT) 1 << bitnum)
return FALSE;
{
/* Check for "if (X & C) x &= ~C". */
if (! rtx_equal_p (x, XEXP (a, 0))
- || GET_CODE (XEXP (a, 1)) != CONST_INT
+ || !CONST_INT_P (XEXP (a, 1))
|| (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
!= (~((HOST_WIDE_INT) 1 << bitnum) & GET_MODE_MASK (mode)))
return FALSE;
addr = XEXP (addr, 1);
break;
case PLUS:
- if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ if (CONST_INT_P (XEXP (addr, 1)))
addr = XEXP (addr, 0);
else
return false;
if (GET_MODE (x) == BLKmode)
return FALSE;
- if (GET_MODE (x) == ZERO_EXTRACT
- && (GET_CODE (XEXP (x, 1)) != CONST_INT
- || GET_CODE (XEXP (x, 2)) != CONST_INT))
+ if (GET_CODE (x) == ZERO_EXTRACT
+ && (!CONST_INT_P (XEXP (x, 1))
+ || !CONST_INT_P (XEXP (x, 2))))
return FALSE;
x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
REGS. COND is the condition we will test. */
static int
-check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) *regs, rtx cond)
+check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs, rtx cond)
{
rtx insn;
vals[REGNO (dest)] = src;
- VEC_safe_push (int, heap, regs, REGNO (dest));
+ VEC_safe_push (int, heap, *regs, REGNO (dest));
}
return TRUE;
memset (else_vals, 0, size);
/* Make sure the blocks are suitable. */
- 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)))
+ 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)))
{
VEC_free (int, heap, then_regs);
VEC_free (int, heap, else_regs);
&& cond_exec_find_if_block (&ce_info))
goto success;
- if (HAVE_trap && HAVE_conditional_trap
+ if (HAVE_trap
+ && optab_handler (ctrap_optab, word_mode)->insn_code != CODE_FOR_nothing
&& find_cond_trap (test_bb, then_edge, else_edge))
goto success;
basic_block other_bb, basic_block new_dest, int reversep)
{
rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
+ /* Number of pending changes. */
+ int n_validated_changes = 0;
jump = BB_END (test_bb);
prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
}
- if (! cond_exec_process_insns ((ce_if_block_t *)0, head, end, cond,
- prob_val, 0))
- goto cancel;
+ if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0)
+ && verify_changes (0))
+ n_validated_changes = num_validated_changes ();
+ else
+ cancel_changes (0);
earliest = jump;
}
- else
#endif
+ /* Try the NCE path if the CE path did not result in any changes. */
+ if (n_validated_changes == 0)
{
/* In the non-conditional execution case, we have to verify that there
are no trapping operations, no calls, no references to memory, and
if (INSN_P (insn))
{
unsigned int uid = INSN_UID (insn);
- struct df_ref **def_rec;
+ df_ref *def_rec;
for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
{
- struct df_ref *def = *def_rec;
+ df_ref def = *def_rec;
bitmap_set_bit (merge_set, DF_REF_REGNO (def));
}
}
/* The loop below takes the set of live registers
after JUMP, and calculates the live set before EARLIEST. */
bitmap_copy (test_live, df_get_live_in (other_bb));
- df_simulate_artificial_refs_at_end (test_bb, test_live);
+ df_simulate_initialize_backwards (test_bb, test_live);
for (insn = jump; ; insn = prev)
{
if (INSN_P (insn))
{
df_simulate_find_defs (insn, test_set);
- df_simulate_one_insn (test_bb, insn, test_live);
+ df_simulate_one_insn_backwards (test_bb, insn, test_live);
}
prev = PREV_INSN (insn);
if (insn == earliest)
goto cancel;
}
- if (! apply_change_group ())
- return FALSE;
+ if (verify_changes (n_validated_changes))
+ confirm_change_group ();
+ else
+ goto cancel;
if (other_bb != new_dest)
{