#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
rtx insn_a, insn_b;
rtx set_a, set_b;
rtx orig_x, x, a, b;
- rtx jump, cond, insn;
+ rtx jump, cond;
/* We're looking for patterns of the form
|| ! rtx_equal_p (x, SET_DEST (set_b))
|| reg_overlap_mentioned_p (x, cond)
|| reg_overlap_mentioned_p (x, a)
- || reg_overlap_mentioned_p (x, SET_SRC (set_b)))
+ || reg_overlap_mentioned_p (x, SET_SRC (set_b))
+ || modified_between_p (x, if_info.cond_earliest, NEXT_INSN (jump)))
insn_b = set_b = NULL_RTX;
}
b = (set_b ? SET_SRC (set_b) : x);
- /* X may not be mentioned in the range (cond_earliest, jump].
- Note the use of reg_overlap_mentioned_p, which handles memories
- properly, as opposed to reg_mentioned_p, which doesn't. */
- for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
- if (INSN_P (insn) && reg_overlap_mentioned_p (x, PATTERN (insn)))
- return FALSE;
-
- /* A and B may not be modified in the range [cond_earliest, jump). */
- for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
- && (modified_in_p (a, insn) || modified_in_p (b, insn)))
- return FALSE;
-
/* Only operate on register destinations, and even then avoid extending
the lifetime of hard registers on small register class machines. */
orig_x = x;
if (else_bb && insn_b == else_bb->end)
else_bb->end = PREV_INSN (insn_b);
- reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
+ reorder_insns (insn_b, insn_b, PREV_INSN (jump));
/* If there was a REG_EQUAL note, delete it since it may have been
true due to this insn being after a jump. */
if (insn_b && else_bb)
delete_insn (insn_b);
- /* The new insns will have been inserted before cond_earliest. We should
- be able to remove the jump with impunity, but the condition itself may
- have been modified by gcse to be shared across basic blocks. */
+ /* The new insns will have been inserted immediately before the jump. We
+ should be able to remove the jump with impunity, but the condition itself
+ may have been modified by gcse to be shared across basic blocks. */
delete_insn (jump);
/* If we used a temporary, fix it up now. */
FOR_EACH_BB (bb)
{
- basic_block new_bb = find_if_header (bb, pass);
- if (new_bb)
+ basic_block new_bb;
+ while ((new_bb = find_if_header (bb, pass)))
bb = new_bb;
}