aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>2023-01-20 12:33:37 +0900
committerMax Filippov <jcmvbkbc@gmail.com>2023-01-24 13:23:03 -0800
commit1c407dc088231ba5f2cc63d9278f4b797db48de1 (patch)
tree5c360e20836e0e4f81874c79c7df22cfab87914e /gcc
parent265a749f290f7c6adc9a3aaa9c585b498a8a38ea (diff)
downloadgcc-1c407dc088231ba5f2cc63d9278f4b797db48de1.zip
gcc-1c407dc088231ba5f2cc63d9278f4b797db48de1.tar.gz
gcc-1c407dc088231ba5f2cc63d9278f4b797db48de1.tar.bz2
xtensa: Revise complex hard register clobber elimination
In the previously posted patch "xtensa: Make complex hard register clobber elimination more robust and accurate", the check code for insns that refer to the [DS]Cmode hard register before it is overwritten after it is clobbered is incomplete. Fortunately such insns are seldom emitted, so it didn't matter. This patch fixes that for the sake of completeness. gcc/ChangeLog: * config/xtensa/xtensa.md: Fix exit from loops detecting references before overwriting in the split pattern.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/xtensa/xtensa.md72
1 files changed, 37 insertions, 35 deletions
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index dd3fc37..d3996b2 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2973,45 +2973,47 @@
{
auto_sbitmap bmp (FIRST_PSEUDO_REGISTER);
rtx_insn *insn;
- rtx reg = gen_rtx_REG (SImode, 0);
+ rtx reg = gen_rtx_REG (SImode, 0), dest;
+ unsigned int regno;
+ sbitmap_iterator iter;
bitmap_set_range (bmp, REGNO (operands[0]), REG_NREGS (operands[0]));
for (insn = next_nonnote_nondebug_insn_bb (curr_insn);
insn; insn = next_nonnote_nondebug_insn_bb (insn))
- {
- sbitmap_iterator iter;
- unsigned int regno;
- if (NONJUMP_INSN_P (insn))
- {
- EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
- {
- set_regno_raw (reg, regno, REG_NREGS (reg));
- if (reg_overlap_mentioned_p (reg, PATTERN (insn)))
- break;
- }
- if (GET_CODE (PATTERN (insn)) == SET)
- {
- rtx x = SET_DEST (PATTERN (insn));
- if (REG_P (x) && HARD_REGISTER_P (x))
- bitmap_clear_range (bmp, REGNO (x), REG_NREGS (x));
- else if (SUBREG_P (x) && HARD_REGISTER_P (SUBREG_REG (x)))
- {
- struct subreg_info info;
- subreg_get_info (regno = REGNO (SUBREG_REG (x)),
- GET_MODE (SUBREG_REG (x)),
- SUBREG_BYTE (x), GET_MODE (x), &info);
- if (!info.representable_p)
- break;
- bitmap_clear_range (bmp, regno + info.offset, info.nregs);
- }
- }
- if (bitmap_empty_p (bmp))
- goto FALLTHRU;
- }
- else if (CALL_P (insn))
+ if (NONJUMP_INSN_P (insn))
+ {
EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
- if (call_used_or_fixed_reg_p (regno))
- break;
- }
+ {
+ set_regno_raw (reg, regno, REG_NREGS (reg));
+ if (reg_referenced_p (reg, PATTERN (insn)))
+ goto ABORT;
+ }
+ if (GET_CODE (PATTERN (insn)) == SET
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ {
+ dest = SET_DEST (PATTERN (insn));
+ if (REG_P (dest) && HARD_REGISTER_P (dest))
+ bitmap_clear_range (bmp, REGNO (dest), REG_NREGS (dest));
+ else if (SUBREG_P (dest)
+ && HARD_REGISTER_P (SUBREG_REG (dest)))
+ {
+ struct subreg_info info;
+ subreg_get_info (regno = REGNO (SUBREG_REG (dest)),
+ GET_MODE (SUBREG_REG (dest)),
+ SUBREG_BYTE (dest), GET_MODE (dest),
+ &info);
+ if (!info.representable_p)
+ break;
+ bitmap_clear_range (bmp, regno + info.offset, info.nregs);
+ }
+ }
+ if (bitmap_empty_p (bmp))
+ goto FALLTHRU;
+ }
+ else if (CALL_P (insn))
+ EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
+ if (call_used_or_fixed_reg_p (regno))
+ goto ABORT;
+ABORT:
FAIL;
FALLTHRU:;
})