#include "insn-config.h"
#include "recog.h"
#include "except.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfgrtl.h"
+#include "cfganal.h"
+#include "cfgcleanup.h"
#include "basic-block.h"
#include "expr.h"
#include "output.h"
+#include "insn-codes.h"
#include "optabs.h"
#include "diagnostic-core.h"
#include "tm_p.h"
+ 1)
#endif
+#ifndef HAVE_cbranchcc4
+#define HAVE_cbranchcc4 0
+#endif
+
#define IFCVT_MULTIPLE_DUMPS 1
#define NULL_BLOCK ((basic_block) NULL)
if (CALL_P (insn) && prob_val >= 0)
validate_change (insn, ®_NOTES (insn),
- gen_rtx_INT_LIST ((enum machine_mode) REG_BR_PROB,
+ gen_rtx_INT_LIST ((machine_mode) REG_BR_PROB,
prob_val, REG_NOTES (insn)), 1);
insn_done:
static void
noce_emit_move_insn (rtx x, rtx y)
{
- enum machine_mode outmode;
+ machine_mode outmode;
rtx outer, inner;
int bitpos;
int reversep;
HOST_WIDE_INT itrue, ifalse, diff, tmp;
int normalize, can_reverse;
- enum machine_mode mode;
+ machine_mode mode;
if (CONST_INT_P (if_info->a)
&& CONST_INT_P (if_info->b))
if (target)
{
+ int old_cost, new_cost, insn_cost;
+ int speed_p;
+
if (target != if_info->x)
noce_emit_move_insn (if_info->x, target);
if (!seq)
return FALSE;
+ speed_p = optimize_bb_for_speed_p (BLOCK_FOR_INSN (if_info->insn_a));
+ insn_cost = insn_rtx_cost (PATTERN (if_info->insn_a), speed_p);
+ old_cost = COSTS_N_INSNS (if_info->branch_cost) + insn_cost;
+ new_cost = seq_cost (seq, speed_p);
+
+ if (new_cost > old_cost)
+ return FALSE;
+
emit_insn_before_setloc (seq, if_info->jump,
INSN_LOCATION (if_info->insn_a));
return TRUE;
end_sequence ();
}
- /* Don't even try if the comparison operands are weird. */
+ /* Don't even try if the comparison operands are weird
+ except that the target supports cbranchcc4. */
if (! general_operand (cmp_a, GET_MODE (cmp_a))
|| ! general_operand (cmp_b, GET_MODE (cmp_b)))
- return NULL_RTX;
+ {
+ if (!(HAVE_cbranchcc4)
+ || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
+ || cmp_b != const0_rtx)
+ return NULL_RTX;
+ }
#if HAVE_conditional_move
unsignedp = (code == LTU || code == GEU
&& MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
&& if_info->branch_cost >= 5)
{
- enum machine_mode address_mode = get_address_mode (a);
+ machine_mode address_mode = get_address_mode (a);
a = XEXP (a, 0);
b = XEXP (b, 0);
}
cond = canonicalize_condition (if_info->jump, cond, reverse,
- earliest, target, false, true);
+ earliest, target, HAVE_cbranchcc4, true);
if (! cond || ! reg_mentioned_p (target, cond))
return NULL;
{
rtx cond, t, m, c;
rtx_insn *seq;
- enum machine_mode mode;
+ machine_mode mode;
enum rtx_code code;
bool t_unconditional;
{
rtx cond, x, a, result;
rtx_insn *seq;
- enum machine_mode mode;
+ machine_mode mode;
enum rtx_code code;
int bitnum;
/* Otherwise, fall back on canonicalize_condition to do the dirty
work of manipulating MODE_CC values and COMPARE rtx codes. */
tmp = canonicalize_condition (jump, cond, reverse, earliest,
- NULL_RTX, false, true);
+ NULL_RTX, HAVE_cbranchcc4, true);
/* We don't handle side-effects in the condition, like handling
REG_INC notes and making sure no duplicate conditions are emitted. */