/* If-conversion support.
- Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ Copyright (C) 2000-2019 Free Software Foundation, Inc.
This file is part of GCC.
return count;
}
-/* Determine whether the total insn_rtx_cost on non-jump insns in
+/* Determine whether the total insn_cost on non-jump insns in
basic block BB is less than MAX_COST. This function returns
false if the cost of any instruction could not be estimated.
: REG_BR_PROB_BASE;
/* Set scale to REG_BR_PROB_BASE to void the identical scaling
- applied to insn_rtx_cost when optimizing for size. Only do
+ applied to insn_cost when optimizing for size. Only do
this after combine because if-conversion might interfere with
passes before combine.
{
if (NONJUMP_INSN_P (insn))
{
- int cost = insn_rtx_cost (PATTERN (insn), speed) * REG_BR_PROB_BASE;
+ int cost = insn_cost (insn, speed) * REG_BR_PROB_BASE;
if (cost == 0)
return false;
return FALSE;
/* If the conditional jump is more than just a conditional jump,
- then we can not do conditional execution conversion on this block. */
+ then we cannot do conditional execution conversion on this block. */
if (! onlyjump_p (BB_END (test_bb)))
return FALSE;
goto fail;
/* If the conditional jump is more than just a conditional jump, then
- we can not do conditional execution conversion on this block. */
+ we cannot do conditional execution conversion on this block. */
if (! onlyjump_p (BB_END (bb)))
goto fail;
{
machine_mode outmode;
rtx outer, inner;
- int bitpos;
+ poly_int64 bitpos;
if (GET_CODE (x) != STRICT_LOW_PART)
{
HOST_WIDE_INT itrue, ifalse, diff, tmp;
int normalize;
bool can_reverse;
- machine_mode mode = GET_MODE (if_info->x);;
+ machine_mode mode = GET_MODE (if_info->x);
rtx common = NULL_RTX;
rtx a = if_info->a;
{
rtx reg_vtrue = SUBREG_REG (vtrue);
rtx reg_vfalse = SUBREG_REG (vfalse);
- unsigned int byte_vtrue = SUBREG_BYTE (vtrue);
- unsigned int byte_vfalse = SUBREG_BYTE (vfalse);
+ poly_uint64 byte_vtrue = SUBREG_BYTE (vtrue);
+ poly_uint64 byte_vfalse = SUBREG_BYTE (vfalse);
rtx promoted_target;
if (GET_MODE (reg_vtrue) != GET_MODE (reg_vfalse)
- || byte_vtrue != byte_vfalse
+ || maybe_ne (byte_vtrue, byte_vfalse)
|| (SUBREG_PROMOTED_VAR_P (vtrue)
!= SUBREG_PROMOTED_VAR_P (vfalse))
|| (SUBREG_PROMOTED_GET (vtrue)
{
rtx cond, x, a, result;
rtx_insn *seq;
- machine_mode mode;
+ scalar_int_mode mode;
enum rtx_code code;
int bitnum;
cond = if_info->cond;
code = GET_CODE (cond);
+ /* Check for an integer operation. */
+ if (!is_a <scalar_int_mode> (GET_MODE (x), &mode))
+ return FALSE;
+
if (!noce_simple_bbs (if_info))
return FALSE;
|| ! rtx_equal_p (x, XEXP (cond, 0)))
return FALSE;
bitnum = INTVAL (XEXP (cond, 2));
- mode = GET_MODE (x);
if (BITS_BIG_ENDIAN)
bitnum = GET_MODE_BITSIZE (mode) - 1 - bitnum;
if (bitnum < 0 || bitnum >= HOST_BITS_PER_WIDE_INT)
if (first_insn == last_insn)
{
*simple_p = noce_operand_ok (SET_DEST (first_set));
- *cost += insn_rtx_cost (first_set, speed_p);
+ *cost += pattern_cost (first_set, speed_p);
return *simple_p;
}
/* The regs that are live out of test_bb. */
bitmap test_bb_live_out = df_get_live_out (test_bb);
- int potential_cost = insn_rtx_cost (last_set, speed_p);
+ int potential_cost = pattern_cost (last_set, speed_p);
rtx_insn *insn;
FOR_BB_INSNS (test_bb, insn)
{
|| reg_overlap_mentioned_p (SET_DEST (sset), cond))
goto free_bitmap_and_fail;
- potential_cost += insn_rtx_cost (sset, speed_p);
+ potential_cost += pattern_cost (sset, speed_p);
bitmap_set_bit (test_bb_temps, REGNO (SET_DEST (sset)));
}
}
{
machine_mode src_mode = GET_MODE (new_val);
machine_mode dst_mode = GET_MODE (temp);
- if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode))
+ if (!partial_subreg_p (dst_mode, src_mode))
{
end_sequence ();
return FALSE;
{
machine_mode src_mode = GET_MODE (old_val);
machine_mode dst_mode = GET_MODE (temp);
- if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode))
+ if (!partial_subreg_p (dst_mode, src_mode))
{
end_sequence ();
return FALSE;
}
/* If the conditional jump is more than just a conditional
- jump, then we can not do if-conversion on this block. */
+ jump, then we cannot do if-conversion on this block. */
jump = BB_END (test_bb);
if (! onlyjump_p (jump))
return FALSE;
return FALSE;
/* If the conditional jump is more than just a conditional jump, then
- we can not do if-conversion on this block. Give up for returnjump_p,
+ we cannot do if-conversion on this block. Give up for returnjump_p,
changing a conditional return followed by unconditional trap for
conditional trap followed by unconditional return is likely not
beneficial and harder to handle. */
redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
if (reversep)
{
- std::swap (BRANCH_EDGE (test_bb)->count,
- FALLTHRU_EDGE (test_bb)->count);
std::swap (BRANCH_EDGE (test_bb)->probability,
FALLTHRU_EDGE (test_bb)->probability);
update_br_prob_note (test_bb);
if (optimize == 1)
df_remove_problem (df_live);
+ /* Some non-cold blocks may now be only reachable from cold blocks.
+ Fix that up. */
+ fixup_partitions ();
+
checking_verify_flow_info ();
}
\f
static unsigned int
rest_of_handle_if_conversion (void)
{
+ int flags = 0;
+
if (flag_if_conversion)
{
if (dump_file)
}
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert (false);
+ if (num_updated_if_blocks)
+ /* Get rid of any dead CC-related instructions. */
+ flags |= CLEANUP_FORCE_FAST_DCE;
}
- cleanup_cfg (0);
+ cleanup_cfg (flags);
return 0;
}