summaryrefslogtreecommitdiff
path: root/gcc/ifcvt.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-19 01:07:10 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-19 01:07:10 +0000
commit068fc551ab26da1d9b68a2190e9976b411532caf (patch)
tree6817aa9bc3ff6e8d11f2ab3f5a2a0d8f9a3b3d77 /gcc/ifcvt.c
parentcf78c9ff43aec986d82bd90e80ecfb07a7fe2c98 (diff)
downloadgcc-068fc551ab26da1d9b68a2190e9976b411532caf.tar.gz
* ifcvt.c (noce_process_if_block): Correctly detect X modified
with INSN_B before COND_EARLIEST. Don't check A and B for modification in condition range. Reorder INSN_B for A==B properly. (if_convert): Iterate until no matches for a block. * gcc.c-torture/execute/20020916-1.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57294 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r--gcc/ifcvt.c30
1 files changed, 9 insertions, 21 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 3ae828b43f8..42c5fb50bdb 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1700,7 +1700,7 @@ noce_process_if_block (ce_info)
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
@@ -1776,24 +1776,12 @@ noce_process_if_block (ce_info)
|| ! 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;
@@ -1839,7 +1827,7 @@ noce_process_if_block (ce_info)
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. */
@@ -1894,9 +1882,9 @@ noce_process_if_block (ce_info)
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. */
@@ -3115,8 +3103,8 @@ if_convert (x_life_data_ok)
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;
}