From bc6688b40ef6cc12e88a2498f82dbb2cd52ee443 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 21 May 2003 01:16:33 +0000 Subject: [PATCH] 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 Co-Authored-By: Kazu Hirata From-SVN: r67054 --- gcc/ChangeLog | 15 ++++++++++++ gcc/gcse.c | 64 +++++++++++++++++++++++++++++++++++++++------------ gcc/jump.c | 29 +++++++++++++++++++++++ 3 files changed, 93 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c5c1792e147..7eaa2e76149 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2003-05-20 Roger Sayle + Kazu Hirata + Joern Rennecke + + * 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. + 2003-05-21 Danny Smith PR c++/9738 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); } diff --git a/gcc/jump.c b/gcc/jump.c index f59fdbcf9a2..f15e2abae10 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -2074,6 +2074,7 @@ redirect_jump (jump, nlabel, delete_unused) int delete_unused; { rtx olabel = JUMP_LABEL (jump); + rtx note; if (nlabel == olabel) return 1; @@ -2085,6 +2086,29 @@ redirect_jump (jump, nlabel, delete_unused) if (nlabel) ++LABEL_NUSES (nlabel); + /* Update labels in any REG_EQUAL note. */ + if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX) + { + if (nlabel && olabel) + { + rtx dest = XEXP (note, 0); + + if (GET_CODE (dest) == IF_THEN_ELSE) + { + if (GET_CODE (XEXP (dest, 1)) == LABEL_REF + && XEXP (XEXP (dest, 1), 0) == olabel) + XEXP (XEXP (dest, 1), 0) = nlabel; + if (GET_CODE (XEXP (dest, 2)) == LABEL_REF + && XEXP (XEXP (dest, 2), 0) == olabel) + XEXP (XEXP (dest, 2), 0) = nlabel; + } + else + remove_note (jump, note); + } + else + remove_note (jump, note); + } + /* If we're eliding the jump over exception cleanups at the end of a function, move the function end note so that -Wreturn-type works. */ if (olabel && nlabel @@ -2201,6 +2225,11 @@ invert_jump (jump, nlabel, delete_unused) if (redirect_jump (jump, nlabel, delete_unused)) { + /* Remove REG_EQUAL note if we have one. */ + rtx note = find_reg_note (jump, REG_EQUAL, NULL_RTX); + if (note) + remove_note (jump, note); + invert_br_probabilities (jump); return 1; -- 2.30.2