diff options
author | Roger Sayle <roger@eyesopen.com> | 2003-05-21 01:16:33 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2003-05-21 01:16:33 +0000 |
commit | bc6688b40ef6cc12e88a2498f82dbb2cd52ee443 (patch) | |
tree | f28f48b34144fa1f8eece6d07edcd6abcef71a4f /gcc/gcse.c | |
parent | fc351800ecc6c2583d0e7be9d18eed6b0934563e (diff) | |
download | gcc-bc6688b40ef6cc12e88a2498f82dbb2cd52ee443.tar.gz |
gcse.c (cprop_jump): Make use of REG_EQUAL notes on both setcc and jump, if they exist.
* gcse.c (cprop_jump): Make use of REG_EQUAL notes on both
setcc and jump, if they exist. If substituted instruction
fails to validate, store current effort in a REG_EQUAL note.
(cprop_insn): Don't attempt further substitutions if the
current instruction has been deleted.
(local_cprop_pass): Likewise.
* jump.c (redirect_jump): Also update REG_EQUAL note, if
one is attached to the jump instruction.
(invert_jump): Delete REG_EQUAL note on jump, if one exists.
Co-Authored-By: Joern Rennecke <joern.rennecke@superh.com>
Co-Authored-By: Kazu Hirata <kazu@cs.umass.edu>
From-SVN: r67054
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r-- | gcc/gcse.c | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c index db2fb57ff21..8050dd13c73 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -4089,28 +4089,42 @@ cprop_jump (bb, setcc, jump, from, src) rtx from; rtx src; { - rtx new, new_set; + rtx new, set_src, note_src; rtx set = pc_set (jump); + rtx note = find_reg_equal_equiv_note (jump); - /* First substitute in the INSN condition as the SET_SRC of the JUMP, - then substitute that given values in this expanded JUMP. */ - if (setcc != NULL + if (note) + { + note_src = XEXP (note, 0); + if (GET_CODE (note_src) == EXPR_LIST) + note_src = NULL_RTX; + } + else note_src = NULL_RTX; + + /* Prefer REG_EQUAL notes except those containing EXPR_LISTs. */ + set_src = note_src ? note_src : SET_SRC (set); + + /* First substitute the SETCC condition into the JUMP instruction, + then substitute that given values into this expanded JUMP. */ + if (setcc != NULL_RTX && !modified_between_p (from, setcc, jump) && !modified_between_p (src, setcc, jump)) { + rtx setcc_src; rtx setcc_set = single_set (setcc); - new_set = simplify_replace_rtx (SET_SRC (set), - SET_DEST (setcc_set), - SET_SRC (setcc_set)); + rtx setcc_note = find_reg_equal_equiv_note (setcc); + setcc_src = (setcc_note && GET_CODE (XEXP (setcc_note, 0)) != EXPR_LIST) + ? XEXP (setcc_note, 0) : SET_SRC (setcc_set); + set_src = simplify_replace_rtx (set_src, SET_DEST (setcc_set), + setcc_src); } else - new_set = set; + setcc = NULL_RTX; - new = simplify_replace_rtx (new_set, from, src); + new = simplify_replace_rtx (set_src, from, src); - /* If no simplification can be made, then try the next - register. */ - if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set))) + /* If no simplification can be made, then try the next register. */ + if (rtx_equal_p (new, SET_SRC (set))) return 0; /* If this is now a no-op delete it, otherwise this must be a valid insn. */ @@ -4120,11 +4134,27 @@ cprop_jump (bb, setcc, jump, from, src) { /* Ensure the value computed inside the jump insn to be equivalent to one computed by setcc. */ - if (setcc - && modified_in_p (new, setcc)) + if (setcc && modified_in_p (new, setcc)) return 0; if (! validate_change (jump, &SET_SRC (set), new, 0)) - return 0; + { + /* When (some) constants are not valid in a comparison, and there + are two registers to be replaced by constants before the entire + comparison can be folded into a constant, we need to keep + intermediate information in REG_EQUAL notes. For targets with + separate compare insns, such notes are added by try_replace_reg. + When we have a combined compare-and-branch instruction, however, + we need to attach a note to the branch itself to make this + optimization work. */ + + if (!rtx_equal_p (new, note_src)) + set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new)); + return 0; + } + + /* Remove REG_EQUAL note after simplification. */ + if (note_src) + remove_note (jump, note); /* If this has turned into an unconditional jump, then put a barrier after it so that the unreachable @@ -4261,6 +4291,8 @@ cprop_insn (insn, alter_jumps) print_rtl (gcse_file, src); fprintf (gcse_file, "\n"); } + if (INSN_DELETED_P (insn)) + return 1; } } else if (GET_CODE (src) == REG @@ -4503,6 +4535,8 @@ local_cprop_pass (alter_jumps) changed = true; break; } + if (INSN_DELETED_P (insn)) + break; } while (reg_use_count); } |