/* If-conversion support.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GCC.
/* If this instruction is the load or set of a "stack" register,
such as a floating point register on x87, then the cost of
- speculatively executing this instruction needs to include
- the additional cost of popping this register off of the
- register stack. */
+ speculatively executing this insn may need to include
+ the additional cost of popping its result off of the
+ register stack. Unfortunately, correctly recognizing and
+ accounting for this additional overhead is tricky, so for
+ now we simply prohibit such speculative execution. */
#ifdef STACK_REGS
{
rtx set = single_set (insn);
if (set && STACK_REG_P (SET_DEST (set)))
- cost += COSTS_N_INSNS (1);
+ return false;
}
#endif
return FALSE;
}
else
+ insn_cost = 0;
+
+ if (insn_b)
{
- insn_cost = 0;
+ insn_cost += insn_rtx_cost (PATTERN (insn_b));
+ if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (BRANCH_COST))
+ return FALSE;
}
- if (insn_b) {
- insn_cost += insn_rtx_cost (PATTERN (insn_b));
- if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (BRANCH_COST))
- return FALSE;
- }
-
/* Possibly rearrange operands to make things come out more natural. */
if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)
{
return FALSE;
bitnum = INTVAL (XEXP (cond, 2));
mode = GET_MODE (x);
- if (bitnum >= HOST_BITS_PER_WIDE_INT)
+ if (BITS_BIG_ENDIAN)
+ bitnum = GET_MODE_BITSIZE (mode) - 1 - bitnum;
+ if (bitnum < 0 || bitnum >= HOST_BITS_PER_WIDE_INT)
return FALSE;
}
else
src = SET_SRC (set);
if (!REG_P (dest)
|| (SMALL_REGISTER_CLASSES && HARD_REGISTER_P (dest)))
- return false;
+ return FALSE;
if (!CONSTANT_P (src) && !register_operand (src, VOIDmode))
return FALSE;
if (may_trap_p (src) || may_trap_p (dest))
return FALSE;
+ /* Don't try to handle this if the source register was
+ modified earlier in the block. */
+ if ((REG_P (src)
+ && vals[REGNO (src)] != NULL)
+ || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
+ && vals[REGNO (SUBREG_REG (src))] != NULL))
+ return FALSE;
+
/* Don't try to handle this if the destination register was
modified earlier in the block. */
if (vals[REGNO (dest)] != NULL)
head = BB_HEAD (merge_bb);
end = BB_END (merge_bb);
+ /* If merge_bb ends with a tablejump, predicating/moving insn's
+ into test_bb and then deleting merge_bb will result in the jumptable
+ that follows merge_bb being removed along with merge_bb and then we
+ get an unresolved reference to the jumptable. */
+ if (tablejump_p (end, NULL, NULL))
+ return FALSE;
+
if (LABEL_P (head))
head = NEXT_INSN (head);
if (NOTE_P (head))