#include "vecprim.h"
#include "dbgcnt.h"
-#ifndef HAVE_conditional_execution
-#define HAVE_conditional_execution 0
-#endif
#ifndef HAVE_conditional_move
#define HAVE_conditional_move 0
#endif
/* ??? FIXME: Magic number 5. */
if (cse_not_expected
&& MEM_P (a) && MEM_P (b)
+ && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
&& if_info->branch_cost >= 5)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (a));
+
a = XEXP (a, 0);
b = XEXP (b, 0);
- x = gen_reg_rtx (Pmode);
+ x = gen_reg_rtx (address_mode);
is_mem = 1;
}
set_mem_align (tmp,
MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));
+ gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b));
+ set_mem_addr_space (tmp, MEM_ADDR_SPACE (if_info->a));
+
noce_emit_move_insn (if_info->x, tmp);
}
else if (target != x)
/* First, look to see if we put a constant in a register. */
prev_insn = prev_nonnote_insn (if_info->cond_earliest);
if (prev_insn
- && BLOCK_NUM (prev_insn) == BLOCK_NUM (if_info->cond_earliest)
+ && BLOCK_FOR_INSN (prev_insn)
+ == BLOCK_FOR_INSN (if_info->cond_earliest)
&& INSN_P (prev_insn)
&& GET_CODE (PATTERN (prev_insn)) == SET)
{
return TRUE;
}
-/* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */
+/* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);",
+ "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);",
+ etc. */
static int
noce_try_abs (struct noce_if_info *if_info)
{
rtx cond, earliest, target, seq, a, b, c;
int negate;
+ bool one_cmpl = false;
/* Reject modes with signed zeros. */
if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)))
c = a; a = b; b = c;
negate = 1;
}
+ else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b))
+ {
+ negate = 0;
+ one_cmpl = true;
+ }
+ else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a))
+ {
+ c = a; a = b; b = c;
+ negate = 1;
+ one_cmpl = true;
+ }
else
return FALSE;
{
rtx set, insn = prev_nonnote_insn (earliest);
if (insn
- && BLOCK_NUM (insn) == BLOCK_NUM (earliest)
+ && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (earliest)
&& (set = single_set (insn))
&& rtx_equal_p (SET_DEST (set), c))
{
}
start_sequence ();
-
- target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);
+ if (one_cmpl)
+ target = expand_one_cmpl_abs_nojump (GET_MODE (if_info->x), b,
+ if_info->x);
+ else
+ target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);
/* ??? It's a quandary whether cmove would be better here, especially
for integers. Perhaps combine will clean things up. */
if (target && negate)
- target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0);
+ {
+ if (one_cmpl)
+ target = expand_simple_unop (GET_MODE (target), NOT, target,
+ if_info->x, 0);
+ else
+ target = expand_simple_unop (GET_MODE (target), NEG, target,
+ if_info->x, 0);
+ }
if (! target)
{
COND_EARLIEST to JUMP. Make sure the relevant data is still
intact. */
if (! insn_b
- || BLOCK_NUM (insn_b) != BLOCK_NUM (if_info->cond_earliest)
+ || BLOCK_FOR_INSN (insn_b) != BLOCK_FOR_INSN (if_info->cond_earliest)
|| !NONJUMP_INSN_P (insn_b)
|| (set_b = single_set (insn_b)) == NULL_RTX
|| ! rtx_equal_p (x, SET_DEST (set_b))
if (HAVE_conditional_move
&& noce_try_cmove (if_info))
goto success;
- if (! HAVE_conditional_execution)
+ if (! targetm.have_conditional_execution ())
{
if (noce_try_store_flag_constants (if_info))
goto success;
&& noce_find_if_block (test_bb, then_edge, else_edge, pass))
goto success;
- if (HAVE_conditional_execution && reload_completed
+ if (targetm.have_conditional_execution () && reload_completed
&& cond_exec_find_if_block (&ce_info))
goto success;
goto success;
if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY
- && (! HAVE_conditional_execution || reload_completed))
+ && (! targetm.have_conditional_execution () || reload_completed))
{
if (find_if_case_1 (test_bb, then_edge, else_edge))
goto success;
/* We only ever should get here after reload,
and only if we have conditional execution. */
- gcc_assert (HAVE_conditional_execution && reload_completed);
+ gcc_assert (targetm.have_conditional_execution () && reload_completed);
/* Discover if any fall through predecessors of the current test basic block
were && tests (which jump to the else block) or || tests (which jump to
test_bb->index, else_bb->index);
/* ELSE is small. */
- if (! cheap_bb_rtx_cost_p (else_bb,
+ if (! cheap_bb_rtx_cost_p (else_bb,
COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src),
predictable_edge_p (else_edge)))))
return FALSE;
/* Disable handling dead code by conditional execution if the machine needs
to do anything funny with the tests, etc. */
#ifndef IFCVT_MODIFY_TESTS
- if (HAVE_conditional_execution)
+ if (targetm.have_conditional_execution ())
{
/* In the conditional execution case, we have things easy. We know
the condition is reversible. We don't have to check life info
fail = 1;
}
}
-
+
/* For TEST, we're interested in a range of insns, not a whole block.
Moreover, we're interested in the insns live from OTHER_BB. */
-
- /* The loop below takes the set of live registers
+
+ /* 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_initialize_backwards (test_bb, test_live);
FOR_EACH_BB (bb)
{
basic_block new_bb;
- while (!df_get_bb_dirty (bb)
+ while (!df_get_bb_dirty (bb)
&& (new_bb = find_if_header (bb, pass)) != NULL)
bb = new_bb;
}