ifcvt.c (noce_try_store_flag_constants): Don't check no_new_pseudos here.

* ifcvt.c (noce_try_store_flag_constants): Don't check
	no_new_pseudos here.
	(noce_try_store_flag_constants): Don't check no_new_pseudos.
	(noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove_arith,
	noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
	noce_try_sign_mask): Likewise.
	(if_convert): Check no_new_pseudos here.

	(cond_exec_process_if_block, noce_process_if_block, find_if_block):
	Remove prototypes.
	(struct noce_if_info): Add then_bb, else_bb, join_bb members.
	(noce_get_condition): Handle new then_else_reversed argument.
	(noce_init_if_info): Remove, fold into noce_find_if_block.
	(noce_process_if_block): Take a struct noce_if_info as the
	argument.  Don't set up one based on ce_if_info.  Update pointer
	references accordingly.
	(cond_move_process_if_block): Likewise.
	(process_if_block): Removed.
	(find_if_block): Removed.  Move functionality two new functions,
	noce_find_if_block and cond_exec_find_if_block.
	(noce_find_if_block): New function.  Be aware of IF-THEN-JOIN
	blocks and the symmetric IF-ELSE-JOIN case.
	(cond_exec_find_if_block): Also new function mostly based on old
	find_if_block and process_if_block.
	(find_if_header): Replace find_if_block call with separately
	guarded calls to noce_find_if_block and cond_exec_find_if_block.
	(find_cond_trap): Update noce_get_condition call.
	(dead_or_predicable): Likewise.

From-SVN: r123223
This commit is contained in:
Steven Bosscher 2007-03-26 19:37:11 +00:00
parent 646714ab75
commit 93242b9c1b
2 changed files with 239 additions and 173 deletions

View File

@ -1,3 +1,34 @@
2007-03-26 Steven Bosscher <steven@gcc.gnu.org>
* ifcvt.c (noce_try_store_flag_constants): Don't check
no_new_pseudos here.
(noce_try_store_flag_constants): Don't check no_new_pseudos.
(noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove_arith,
noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
noce_try_sign_mask): Likewise.
(if_convert): Check no_new_pseudos here.
(cond_exec_process_if_block, noce_process_if_block, find_if_block):
Remove prototypes.
(struct noce_if_info): Add then_bb, else_bb, join_bb members.
(noce_get_condition): Handle new then_else_reversed argument.
(noce_init_if_info): Remove, fold into noce_find_if_block.
(noce_process_if_block): Take a struct noce_if_info as the
argument. Don't set up one based on ce_if_info. Update pointer
references accordingly.
(cond_move_process_if_block): Likewise.
(process_if_block): Removed.
(find_if_block): Removed. Move functionality two new functions,
noce_find_if_block and cond_exec_find_if_block.
(noce_find_if_block): New function. Be aware of IF-THEN-JOIN
blocks and the symmetric IF-ELSE-JOIN case.
(cond_exec_find_if_block): Also new function mostly based on old
find_if_block and process_if_block.
(find_if_header): Replace find_if_block call with separately
guarded calls to noce_find_if_block and cond_exec_find_if_block.
(find_cond_trap): Update noce_get_condition call.
(dead_or_predicable): Likewise.
2007-03-26 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (IX86_BUILTIN_CMPNEPD, IX86_BUILTIN_CMPNESD):

View File

@ -96,16 +96,14 @@ static rtx last_active_insn (basic_block, int);
static basic_block block_fallthru (basic_block);
static int cond_exec_process_insns (ce_if_block_t *, rtx, rtx, rtx, rtx, int);
static rtx cond_exec_get_condition (rtx);
static int cond_exec_process_if_block (ce_if_block_t *, int);
static rtx noce_get_condition (rtx, rtx *);
static rtx noce_get_condition (rtx, rtx *, bool);
static int noce_operand_ok (rtx);
static int noce_process_if_block (ce_if_block_t *);
static int process_if_block (ce_if_block_t *);
static void merge_if_block (ce_if_block_t *);
static int find_cond_trap (basic_block, edge, edge);
static basic_block find_if_header (basic_block, int);
static int block_jumps_and_fallthru_p (basic_block, basic_block);
static int find_if_block (ce_if_block_t *);
static int noce_find_if_block (basic_block, edge, edge, int);
static int cond_exec_find_if_block (ce_if_block_t *);
static int find_if_case_1 (basic_block, edge, edge);
static int find_if_case_2 (basic_block, edge, edge);
static int find_memory (rtx *, void *);
@ -598,8 +596,8 @@ cond_exec_process_if_block (ce_if_block_t * ce_info,
struct noce_if_info
{
/* A basic block that ends in a simple conditional jump. */
basic_block test_bb;
/* The basic blocks that make up the IF-THEN-{ELSE-,}JOIN block. */
basic_block test_bb, then_bb, else_bb, join_bb;
/* The jump that ends TEST_BB. */
rtx jump;
@ -938,8 +936,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
int normalize, can_reverse;
enum machine_mode mode;
if (! no_new_pseudos
&& GET_CODE (if_info->a) == CONST_INT
if (GET_CODE (if_info->a) == CONST_INT
&& GET_CODE (if_info->b) == CONST_INT)
{
mode = GET_MODE (if_info->x);
@ -1065,8 +1062,7 @@ noce_try_addcc (struct noce_if_info *if_info)
rtx target, seq;
int subtract, normalize;
if (! no_new_pseudos
&& GET_CODE (if_info->a) == PLUS
if (GET_CODE (if_info->a) == PLUS
&& rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
&& (reversed_comparison_code (if_info->cond, if_info->jump)
!= UNKNOWN))
@ -1157,9 +1153,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
int reversep;
reversep = 0;
if (! no_new_pseudos
&& (BRANCH_COST >= 2
|| STORE_FLAG_VALUE == -1)
if ((BRANCH_COST >= 2
|| STORE_FLAG_VALUE == -1)
&& ((if_info->a == const0_rtx
&& rtx_equal_p (if_info->b, if_info->x))
|| ((reversep = (reversed_comparison_code (if_info->cond,
@ -1314,7 +1309,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
conditional on their addresses followed by a load. Don't do this
early because it'll screw alias analysis. Note that we've
already checked for no side effects. */
if (! no_new_pseudos && cse_not_expected
/* ??? FIXME: Magic number 5. */
if (cse_not_expected
&& MEM_P (a) && MEM_P (b)
&& BRANCH_COST >= 5)
{
@ -1389,9 +1385,6 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
{
rtx set;
if (no_new_pseudos)
goto end_seq_and_fail;
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (a));
@ -1414,9 +1407,6 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
{
rtx set, last;
if (no_new_pseudos)
goto end_seq_and_fail;
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
@ -1648,10 +1638,6 @@ noce_try_minmax (struct noce_if_info *if_info)
enum rtx_code code, op;
int unsignedp;
/* ??? Can't guarantee that expand_binop won't create pseudos. */
if (no_new_pseudos)
return FALSE;
/* ??? Reject modes with NaNs or signed zeros since we don't know how
they will be resolved with an SMIN/SMAX. It wouldn't be too hard
to get the target to tell us... */
@ -1744,10 +1730,6 @@ noce_try_abs (struct noce_if_info *if_info)
rtx cond, earliest, target, seq, a, b, c;
int negate;
/* ??? Can't guarantee that expand_binop won't create pseudos. */
if (no_new_pseudos)
return FALSE;
/* Recognize A and B as constituting an ABS or NABS. The canonical
form is a branch around the negation, taken when the object is the
first operand of a comparison against 0 that evaluates to true. */
@ -1868,9 +1850,6 @@ noce_try_sign_mask (struct noce_if_info *if_info)
enum rtx_code code;
bool b_unconditional;
if (no_new_pseudos)
return FALSE;
cond = if_info->cond;
code = GET_CODE (cond);
m = XEXP (cond, 0);
@ -2036,10 +2015,13 @@ noce_try_bitop (struct noce_if_info *if_info)
/* Similar to get_condition, only the resulting condition must be
valid at JUMP, instead of at EARLIEST. */
valid at JUMP, instead of at EARLIEST.
If THEN_ELSE_REVERSED is true, the fallthrough goes to the THEN
block of the caller, and we have to reverse the condition. */
static rtx
noce_get_condition (rtx jump, rtx *earliest)
noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed)
{
rtx cond, set, tmp;
bool reverse;
@ -2054,6 +2036,11 @@ noce_get_condition (rtx jump, rtx *earliest)
reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
&& XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
/* We may have to reverse because the caller's if block is not canonical
(i.e. the ELSE block isn't the fallthrough block for the TEST block). */
if (then_else_reversed)
reverse = !reverse;
/* If the condition variable is a register and is MODE_INT, accept it. */
cond = XEXP (SET_SRC (set), 0);
@ -2074,52 +2061,6 @@ noce_get_condition (rtx jump, rtx *earliest)
NULL_RTX, false, true);
}
/* Initialize for a simple IF-THEN or IF-THEN-ELSE block. We will not
be using conditional execution. Set some fields of IF_INFO based
on CE_INFO: test_bb, cond, jump, cond_earliest. Return TRUE if
things look OK. */
static int
noce_init_if_info (struct ce_if_block *ce_info, struct noce_if_info *if_info)
{
basic_block test_bb = ce_info->test_bb;
rtx cond, jump;
/* If test is comprised of && or || elements, don't handle it unless
it is the special case of && elements without an ELSE block. */
if (ce_info->num_multiple_test_blocks)
{
if (ce_info->else_bb || !ce_info->and_and_p)
return FALSE;
ce_info->test_bb = test_bb = ce_info->last_test_bb;
ce_info->num_multiple_test_blocks = 0;
ce_info->num_and_and_blocks = 0;
ce_info->num_or_or_blocks = 0;
}
/* If this is not a standard conditional jump, we can't parse it. */
jump = BB_END (test_bb);
cond = noce_get_condition (jump, &if_info->cond_earliest);
if (!cond)
return FALSE;
/* If the conditional jump is more than just a conditional
jump, then we can not do if-conversion on this block. */
if (! onlyjump_p (jump))
return FALSE;
/* We must be comparing objects whose modes imply the size. */
if (GET_MODE (XEXP (cond, 0)) == BLKmode)
return FALSE;
if_info->test_bb = test_bb;
if_info->cond = cond;
if_info->jump = jump;
return TRUE;
}
/* Return true if OP is ok for if-then-else processing. */
static int
@ -2189,22 +2130,22 @@ noce_mem_write_may_trap_or_fault_p (rtx mem)
return false;
}
/* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
without using conditional execution. Return TRUE if we were
successful at converting the block. */
/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
it without using conditional execution. Return TRUE if we were successful
at converting the block. */
static int
noce_process_if_block (struct ce_if_block * ce_info)
noce_process_if_block (struct noce_if_info *if_info)
{
basic_block test_bb = ce_info->test_bb; /* test block */
basic_block then_bb = ce_info->then_bb; /* THEN */
basic_block else_bb = ce_info->else_bb; /* ELSE or NULL */
basic_block join_bb;
struct noce_if_info if_info;
basic_block test_bb = if_info->test_bb; /* test block */
basic_block then_bb = if_info->then_bb; /* THEN */
basic_block else_bb = if_info->else_bb; /* ELSE or NULL */
basic_block join_bb = if_info->join_bb; /* JOIN */
rtx jump = if_info->jump;
rtx cond = if_info->cond;
rtx insn_a, insn_b;
rtx set_a, set_b;
rtx orig_x, x, a, b;
rtx jump, cond;
/* We're looking for patterns of the form
@ -2216,12 +2157,6 @@ noce_process_if_block (struct ce_if_block * ce_info)
??? For future expansion, look for multiple X in such patterns. */
if (!noce_init_if_info (ce_info, &if_info))
return FALSE;
cond = if_info.cond;
jump = if_info.jump;
/* Look for one of the potential sets. */
insn_a = first_active_insn (then_bb);
if (! insn_a
@ -2251,7 +2186,7 @@ noce_process_if_block (struct ce_if_block * ce_info)
}
else
{
insn_b = prev_nonnote_insn (if_info.cond_earliest);
insn_b = prev_nonnote_insn (if_info->cond_earliest);
/* We're going to be moving the evaluation of B down from above
COND_EARLIEST to JUMP. Make sure the relevant data is still
intact. */
@ -2261,13 +2196,13 @@ noce_process_if_block (struct ce_if_block * ce_info)
|| ! rtx_equal_p (x, SET_DEST (set_b))
|| reg_overlap_mentioned_p (x, SET_SRC (set_b))
|| modified_between_p (SET_SRC (set_b),
PREV_INSN (if_info.cond_earliest), jump)
PREV_INSN (if_info->cond_earliest), jump)
/* Likewise with X. In particular this can happen when
noce_get_condition looks farther back in the instruction
stream than one might expect. */
|| reg_overlap_mentioned_p (x, cond)
|| reg_overlap_mentioned_p (x, a)
|| modified_between_p (x, PREV_INSN (if_info.cond_earliest), jump))
|| modified_between_p (x, PREV_INSN (if_info->cond_earliest), jump))
insn_b = set_b = NULL_RTX;
}
@ -2288,7 +2223,7 @@ noce_process_if_block (struct ce_if_block * ce_info)
|| (SMALL_REGISTER_CLASSES
&& REGNO (x) < FIRST_PSEUDO_REGISTER))
{
if (no_new_pseudos || GET_MODE (x) == BLKmode)
if (GET_MODE (x) == BLKmode)
return FALSE;
if (GET_MODE (x) == ZERO_EXTRACT
@ -2305,11 +2240,11 @@ noce_process_if_block (struct ce_if_block * ce_info)
return FALSE;
/* Set up the info block for our subroutines. */
if_info.insn_a = insn_a;
if_info.insn_b = insn_b;
if_info.x = x;
if_info.a = a;
if_info.b = b;
if_info->insn_a = insn_a;
if_info->insn_b = insn_b;
if_info->x = x;
if_info->a = a;
if_info->b = b;
/* Try optimizations in some approximation of a useful order. */
/* ??? Should first look to see if X is live incoming at all. If it
@ -2359,31 +2294,31 @@ noce_process_if_block (struct ce_if_block * ce_info)
if (!set_b && MEM_P (orig_x) && noce_mem_write_may_trap_or_fault_p (orig_x))
return FALSE;
if (noce_try_move (&if_info))
if (noce_try_move (if_info))
goto success;
if (noce_try_store_flag (&if_info))
if (noce_try_store_flag (if_info))
goto success;
if (noce_try_bitop (&if_info))
if (noce_try_bitop (if_info))
goto success;
if (noce_try_minmax (&if_info))
if (noce_try_minmax (if_info))
goto success;
if (noce_try_abs (&if_info))
if (noce_try_abs (if_info))
goto success;
if (HAVE_conditional_move
&& noce_try_cmove (&if_info))
&& noce_try_cmove (if_info))
goto success;
if (! HAVE_conditional_execution)
{
if (noce_try_store_flag_constants (&if_info))
if (noce_try_store_flag_constants (if_info))
goto success;
if (noce_try_addcc (&if_info))
if (noce_try_addcc (if_info))
goto success;
if (noce_try_store_flag_mask (&if_info))
if (noce_try_store_flag_mask (if_info))
goto success;
if (HAVE_conditional_move
&& noce_try_cmove_arith (&if_info))
&& noce_try_cmove_arith (if_info))
goto success;
if (noce_try_sign_mask (&if_info))
if (noce_try_sign_mask (if_info))
goto success;
}
@ -2409,8 +2344,6 @@ noce_process_if_block (struct ce_if_block * ce_info)
/* The original THEN and ELSE blocks may now be removed. The test block
must now jump to the join block. If the test block and the join block
can be merged, do so. */
join_bb = single_succ (then_bb);
if (else_bb)
{
delete_basic_block (else_bb);
@ -2572,19 +2505,20 @@ cond_move_convert_if_block (struct noce_if_info *if_infop,
return true;
}
/* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
using only conditional moves. Return TRUE if we were successful at
/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
it using only conditional moves. Return TRUE if we were successful at
converting the block. */
static int
cond_move_process_if_block (struct ce_if_block *ce_info)
cond_move_process_if_block (struct noce_if_info *if_info)
{
basic_block test_bb = ce_info->test_bb;
basic_block then_bb = ce_info->then_bb;
basic_block else_bb = ce_info->else_bb;
basic_block join_bb;
struct noce_if_info if_info;
rtx jump, cond, seq, loc_insn;
basic_block test_bb = if_info->test_bb;
basic_block then_bb = if_info->then_bb;
basic_block else_bb = if_info->else_bb;
basic_block join_bb = if_info->join_bb;
rtx jump = if_info->jump;
rtx cond = if_info->cond;
rtx seq, loc_insn;
int max_reg, size, c, reg;
rtx *then_vals;
rtx *else_vals;
@ -2592,17 +2526,6 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
VEC (int, heap) *else_regs = NULL;
unsigned int i;
if (!HAVE_conditional_move || no_new_pseudos)
return FALSE;
memset (&if_info, 0, sizeof if_info);
if (!noce_init_if_info (ce_info, &if_info))
return FALSE;
cond = if_info.cond;
jump = if_info.jump;
/* Build a mapping for each block to the value used for each
register. */
max_reg = max_reg_num ();
@ -2655,16 +2578,16 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
/* Try to emit the conditional moves. First do the then block,
then do anything left in the else blocks. */
start_sequence ();
if (!cond_move_convert_if_block (&if_info, then_bb, cond,
if (!cond_move_convert_if_block (if_info, then_bb, cond,
then_vals, else_vals, false)
|| (else_bb
&& !cond_move_convert_if_block (&if_info, else_bb, cond,
&& !cond_move_convert_if_block (if_info, else_bb, cond,
then_vals, else_vals, true)))
{
end_sequence ();
return FALSE;
}
seq = end_ifcvt_sequence (&if_info);
seq = end_ifcvt_sequence (if_info);
if (!seq)
return FALSE;
@ -2676,7 +2599,6 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
}
emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));
join_bb = single_succ (then_bb);
if (else_bb)
{
delete_basic_block (else_bb);
@ -2705,40 +2627,127 @@ cond_move_process_if_block (struct ce_if_block *ce_info)
}
/* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
straight line code. Return true if successful. */
/* Determine if a given basic block heads a simple IF-THEN-JOIN or an
IF-THEN-ELSE-JOIN block.
If so, we'll try to convert the insns to not require the branch,
using only transformations that do not require conditional execution.
Return TRUE if we were successful at converting the block. */
static int
process_if_block (struct ce_if_block * ce_info)
noce_find_if_block (basic_block test_bb,
edge then_edge, edge else_edge,
int pass)
{
if (! reload_completed
&& noce_process_if_block (ce_info))
basic_block then_bb, else_bb, join_bb;
bool then_else_reversed = false;
rtx jump, cond;
struct noce_if_info if_info;
/* We only ever should get here before reload. */
gcc_assert (!reload_completed);
/* Recognize an IF-THEN-ELSE-JOIN block. */
if (single_pred_p (then_edge->dest)
&& single_succ_p (then_edge->dest)
&& single_pred_p (else_edge->dest)
&& single_succ_p (else_edge->dest)
&& single_succ (then_edge->dest) == single_succ (else_edge->dest))
{
then_bb = then_edge->dest;
else_bb = else_edge->dest;
join_bb = single_succ (then_bb);
}
/* Recognize an IF-THEN-JOIN block. */
else if (single_pred_p (then_edge->dest)
&& single_succ_p (then_edge->dest)
&& single_succ (then_edge->dest) == else_edge->dest)
{
then_bb = then_edge->dest;
else_bb = NULL_BLOCK;
join_bb = else_edge->dest;
}
/* Recognize an IF-ELSE-JOIN block. We can have those because the order
of basic blocks in cfglayout mode does not matter, so the fallthrough
edge can go to any basic block (and not just to bb->next_bb, like in
cfgrtl mode). */
else if (single_pred_p (else_edge->dest)
&& single_succ_p (else_edge->dest)
&& single_succ (else_edge->dest) == then_edge->dest)
{
/* The noce transformations do not apply to IF-ELSE-JOIN blocks.
To make this work, we have to invert the THEN and ELSE blocks
and reverse the jump condition. */
then_bb = else_edge->dest;
else_bb = NULL_BLOCK;
join_bb = single_succ (then_bb);
then_else_reversed = true;
}
else
/* Not a form we can handle. */
return FALSE;
/* The edges of the THEN and ELSE blocks cannot have complex edges. */
if (single_succ_edge (then_bb)->flags & EDGE_COMPLEX)
return FALSE;
if (else_bb
&& single_succ_edge (else_bb)->flags & EDGE_COMPLEX)
return FALSE;
num_possible_if_blocks++;
if (dump_file)
{
fprintf (dump_file,
"\nIF-THEN%s-JOIN block found, pass %d, test %d, then %d",
(else_bb) ? "-ELSE" : "",
pass, test_bb->index, then_bb->index);
if (else_bb)
fprintf (dump_file, ", else %d", else_bb->index);
fprintf (dump_file, ", join %d\n", join_bb->index);
}
/* If the conditional jump is more than just a conditional
jump, then we can not do if-conversion on this block. */
jump = BB_END (test_bb);
if (! onlyjump_p (jump))
return FALSE;
/* If this is not a standard conditional jump, we can't parse it. */
cond = noce_get_condition (jump,
&if_info.cond_earliest,
then_else_reversed);
if (!cond)
return FALSE;
/* We must be comparing objects whose modes imply the size. */
if (GET_MODE (XEXP (cond, 0)) == BLKmode)
return FALSE;
/* Initialize an IF_INFO struct to pass around. */
memset (&if_info, 0, sizeof if_info);
if_info.test_bb = test_bb;
if_info.then_bb = then_bb;
if_info.else_bb = else_bb;
if_info.join_bb = join_bb;
if_info.cond = cond;
if_info.jump = jump;
/* Do the real work. */
if (noce_process_if_block (&if_info))
return TRUE;
if (HAVE_conditional_move
&& cond_move_process_if_block (ce_info))
&& cond_move_process_if_block (&if_info))
return TRUE;
if (HAVE_conditional_execution && reload_completed)
{
/* If we have && and || tests, try to first handle combining the && and
|| tests into the conditional code, and if that fails, go back and
handle it without the && and ||, which at present handles the && case
if there was no ELSE block. */
if (cond_exec_process_if_block (ce_info, TRUE))
return TRUE;
if (ce_info->num_multiple_test_blocks)
{
cancel_changes (0);
if (cond_exec_process_if_block (ce_info, FALSE))
return TRUE;
}
}
return FALSE;
}
/* Merge the blocks and mark for local life update. */
@ -2901,7 +2910,12 @@ find_if_header (basic_block test_bb, int pass)
IFCVT_INIT_EXTRA_FIELDS (&ce_info);
#endif
if (find_if_block (&ce_info))
if (! reload_completed
&& noce_find_if_block (test_bb, then_edge, else_edge, pass))
goto success;
if (HAVE_conditional_execution && reload_completed
&& cond_exec_find_if_block (&ce_info))
goto success;
if (HAVE_trap && HAVE_conditional_trap
@ -2999,7 +3013,7 @@ block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
Return TRUE if we were successful at converting the block. */
static int
find_if_block (struct ce_if_block * ce_info)
cond_exec_find_if_block (struct ce_if_block * ce_info)
{
basic_block test_bb = ce_info->test_bb;
basic_block then_bb = ce_info->then_bb;
@ -3011,11 +3025,14 @@ find_if_block (struct ce_if_block * ce_info)
ce_info->last_test_bb = test_bb;
/* We only ever should get here after reload,
and only if we have conditional execution. */
gcc_assert (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
the then block). */
if (HAVE_conditional_execution && reload_completed
&& single_pred_p (test_bb)
if (single_pred_p (test_bb)
&& single_pred_edge (test_bb)->flags == EDGE_FALLTHRU)
{
basic_block bb = single_pred (test_bb);
@ -3201,10 +3218,24 @@ find_if_block (struct ce_if_block * ce_info)
}
/* Do the real work. */
ce_info->else_bb = else_bb;
ce_info->join_bb = join_bb;
return process_if_block (ce_info);
/* If we have && and || tests, try to first handle combining the && and ||
tests into the conditional code, and if that fails, go back and handle
it without the && and ||, which at present handles the && case if there
was no ELSE block. */
if (cond_exec_process_if_block (ce_info, TRUE))
return TRUE;
if (ce_info->num_multiple_test_blocks)
{
cancel_changes (0);
if (cond_exec_process_if_block (ce_info, FALSE))
return TRUE;
}
}
/* Convert a branch over a trap, or a branch
@ -3237,7 +3268,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
/* If this is not a standard conditional jump, we can't parse it. */
jump = BB_END (test_bb);
cond = noce_get_condition (jump, &cond_earliest);
cond = noce_get_condition (jump, &cond_earliest, false);
if (! cond)
return FALSE;
@ -3733,7 +3764,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
return FALSE;
/* Find the extent of the conditional. */
cond = noce_get_condition (jump, &earliest);
cond = noce_get_condition (jump, &earliest, false);
if (! cond)
return FALSE;
@ -3908,6 +3939,10 @@ if_convert (int x_life_data_ok)
num_true_changes = 0;
life_data_ok = (x_life_data_ok != 0);
/* Some transformations in this pass can create new pseudos,
if the pass runs before reload. Make sure we can do so. */
gcc_assert (! no_new_pseudos || reload_completed);
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
if (current_loops)
{