+2007-03-29 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ifcvt.c (struct noce_if_info): Add then_else_reversed field.
+ (noce_get_alt_condition): Look at it to determine whether to
+ reverse the condition or not.
+ (noce_get_condition): Substitute the truth for lies.
+ (noce_find_if_block): Set the then_else_reversed field.
+
2007-03-29 Lars Poeschel <larsi@wh2.tu-dresden.de>
* config/fr30/fr30.md (movdi): Do not accept immediates as the
/* The SET_DEST of INSN_A. */
rtx x;
+
+ /* True if this if block is not canonical. In the canonical form of
+ if blocks, the THEN_BB is the block reached via the fallthru edge
+ from TEST_BB. For the noce transformations, we allow the symmetric
+ form as well. */
+ bool then_else_reversed;
};
static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
reverse
= GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
&& XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
+ if (if_info->then_else_reversed)
+ reverse = !reverse;
/* If we're looking for a constant, try to make the conditional
have that constant in it. There are two reasons why it may
/* Similar to get_condition, only the resulting condition must be
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. */
+ If THEN_ELSE_REVERSED is true, the fallthrough does not go to the
+ THEN block of the caller, and we have to reverse the condition. */
static rtx
noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed)
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). */
+ /* We may have to reverse because the caller's if block is not canonical,
+ i.e. the THEN block isn't the fallthrough block for the TEST block
+ (see find_if_header). */
if (then_else_reversed)
reverse = !reverse;
/* 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). */
+ cfgrtl mode). */
else if (single_pred_p (else_edge->dest)
&& single_succ_p (else_edge->dest)
&& single_succ (else_edge->dest) == then_edge->dest)
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_info.join_bb = join_bb;
if_info.cond = cond;
if_info.jump = jump;
+ if_info.then_else_reversed = then_else_reversed;
/* Do the real work. */