diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-19 01:07:10 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-19 01:07:10 +0000 |
commit | 068fc551ab26da1d9b68a2190e9976b411532caf (patch) | |
tree | 6817aa9bc3ff6e8d11f2ab3f5a2a0d8f9a3b3d77 /gcc/ifcvt.c | |
parent | cf78c9ff43aec986d82bd90e80ecfb07a7fe2c98 (diff) | |
download | gcc-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.c | 30 |
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; } |