diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 1997-04-13 18:20:27 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 1997-04-13 18:20:27 +0000 |
commit | 31418d3513edce4366a45f622701fbc858c3dad8 (patch) | |
tree | d74b15c353fc918f810a88f42550e51d5ed4113d /gcc | |
parent | c7063b9a371df4010a5fcabdf9f6fba19a4626c5 (diff) | |
download | gcc-31418d3513edce4366a45f622701fbc858c3dad8.zip gcc-31418d3513edce4366a45f622701fbc858c3dad8.tar.gz gcc-31418d3513edce4366a45f622701fbc858c3dad8.tar.bz2 |
Remove REG_DEAD notes when eliminating a set in the reload CSE pass
From-SVN: r13886
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/reload1.c | 95 |
1 files changed, 74 insertions, 21 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index 42fe5c7..119e51a 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -400,7 +400,7 @@ static void reload_cse_invalidate_mem PROTO((rtx)); static void reload_cse_invalidate_rtx PROTO((rtx, rtx)); static void reload_cse_regs PROTO((rtx)); static int reload_cse_regno_equal_p PROTO((int, rtx, enum machine_mode)); -static int reload_cse_noop_set_p PROTO((rtx)); +static int reload_cse_noop_set_p PROTO((rtx, rtx)); static void reload_cse_simplify_set PROTO((rtx, rtx)); static void reload_cse_check_clobber PROTO((rtx, rtx)); static void reload_cse_record_set PROTO((rtx, rtx)); @@ -7844,11 +7844,8 @@ reload_cse_regs (first) body = PATTERN (insn); if (GET_CODE (body) == SET) { - if (reload_cse_noop_set_p (body)) + if (reload_cse_noop_set_p (body, insn)) { - /* If we were preserving death notes, then we would want - to remove any existing death note for the register - being set. */ PUT_CODE (insn, NOTE); NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (insn) = 0; @@ -7868,13 +7865,10 @@ reload_cse_regs (first) the entire PARALLEL. */ for (i = XVECLEN (body, 0) - 1; i >= 0; --i) if (GET_CODE (XVECEXP (body, 0, i)) != SET - || ! reload_cse_noop_set_p (XVECEXP (body, 0, i))) + || ! reload_cse_noop_set_p (XVECEXP (body, 0, i), insn)) break; if (i < 0) { - /* If we were preserving death notes, then we would want - to remove any existing death notes for the registers - being set. */ PUT_CODE (insn, NOTE); NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (insn) = 0; @@ -7957,15 +7951,18 @@ reload_cse_regno_equal_p (regno, val, mode) return 0; } -/* See whether a single SET instruction is a nooop. */ +/* See whether a single set is a noop. SET is the set instruction we + are should check, and INSN is the instruction from which it came. */ static int -reload_cse_noop_set_p (set) +reload_cse_noop_set_p (set, insn) rtx set; + rtx insn; { rtx src, dest; enum machine_mode dest_mode; int dreg, sreg; + int ret; src = SET_SRC (set); dest = SET_DEST (set); @@ -7977,27 +7974,38 @@ reload_cse_noop_set_p (set) dreg = true_regnum (dest); sreg = true_regnum (src); + /* Check for setting a register to itself. In this case, we don't + have to worry about REG_DEAD notes. */ + if (dreg >= 0 && dreg == sreg) + return 1; + + ret = 0; if (dreg >= 0) { /* Check for setting a register to itself. */ if (dreg == sreg) - return 1; + ret = 1; /* Check for setting a register to a value which we already know is in the register. */ - if (reload_cse_regno_equal_p (dreg, src, dest_mode)) - return 1; + else if (reload_cse_regno_equal_p (dreg, src, dest_mode)) + ret = 1; /* Check for setting a register DREG to another register SREG where SREG is equal to a value which is already in DREG. */ - if (sreg >= 0) + else if (sreg >= 0) { rtx x; for (x = reg_values[sreg]; x; x = XEXP (x, 1)) - if (XEXP (x, 0) != 0 - && reload_cse_regno_equal_p (dreg, XEXP (x, 0), dest_mode)) - return 1; + { + if (XEXP (x, 0) != 0 + && reload_cse_regno_equal_p (dreg, XEXP (x, 0), dest_mode)) + { + ret = 1; + break; + } + } } } else if (GET_CODE (dest) == MEM) @@ -8007,10 +8015,33 @@ reload_cse_noop_set_p (set) if (sreg >= 0 && reload_cse_regno_equal_p (sreg, dest, dest_mode) && ! side_effects_p (dest)) - return 1; + ret = 1; } - return 0; + /* If we can delete this SET, then we need to look for an earlier + REG_DEAD note on DREG, and remove it if it exists. */ + if (ret) + { + if (! find_regno_note (insn, REG_UNUSED, dreg)) + { + rtx trial; + + for (trial = prev_nonnote_insn (insn); + (trial + && GET_CODE (trial) != CODE_LABEL + && GET_CODE (trial) != BARRIER); + trial = prev_nonnote_insn (trial)) + { + if (find_regno_note (trial, REG_DEAD, dreg)) + { + remove_death (dreg, trial); + break; + } + } + } + } + + return ret; } /* Try to simplify a single SET instruction. SET is the set pattern. @@ -8065,7 +8096,29 @@ reload_cse_simplify_set (set, insn) push_obstacks (&reload_obstack, &reload_obstack); if (validated) - return; + { + /* We need to look for an earlier REG_DEAD note on I, + and remove it if it exists. */ + if (! find_regno_note (insn, REG_UNUSED, i)) + { + rtx trial; + + for (trial = prev_nonnote_insn (insn); + (trial + && GET_CODE (trial) != CODE_LABEL + && GET_CODE (trial) != BARRIER); + trial = prev_nonnote_insn (trial)) + { + if (find_regno_note (trial, REG_DEAD, i)) + { + remove_death (i, trial); + break; + } + } + } + + return; + } } } } |