aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-08-21 13:04:26 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-08-21 13:04:26 -0400
commit8783b15e06b41ec45b155afa523fd06482982912 (patch)
tree6104b5d1a023e83e90ebce256664c06fa9920b8d
parent32c5cac2a5b73cc2ad5e8017ffc21c1f4da00025 (diff)
downloadgcc-8783b15e06b41ec45b155afa523fd06482982912.zip
gcc-8783b15e06b41ec45b155afa523fd06482982912.tar.gz
gcc-8783b15e06b41ec45b155afa523fd06482982912.tar.bz2
(reg_unused_after): For a SEQUENCE, make sure all insns are safe
before returning 1. From-SVN: r10261
-rw-r--r--gcc/config/sh/sh.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 4af8d1f..f52ba43 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -1868,7 +1868,7 @@ reg_unused_after (reg, insn)
rtx reg;
rtx insn;
{
- enum rtx_code code, prev_code = UNKNOWN;
+ enum rtx_code code;
rtx set;
/* If the reg is set by this instruction, then it is safe for our
@@ -1881,20 +1881,45 @@ reg_unused_after (reg, insn)
while (insn = NEXT_INSN (insn))
{
- if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)])
- return 1;
-
code = GET_CODE (insn);
- if (GET_CODE (insn) == CODE_LABEL)
+
+ if (code == CODE_LABEL)
return 1;
- if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
+ /* If this is a sequence, we must handle them all at once.
+ We could have for instance a call that sets the target register,
+ and a insn in a delay slot that uses the register. In this case,
+ we must return 0. */
+ else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
{
- insn = XVECEXP (PATTERN (insn), 0, 0);
- code = GET_CODE (insn);
- }
+ int i;
+ int retval = 0;
+
+ for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ {
+ rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
+ rtx set = single_set (this_insn);
+
+ if (GET_CODE (this_insn) == CALL_INSN)
+ code = CALL_INSN;
- if (GET_RTX_CLASS (code) == 'i')
+ if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
+ return 0;
+ if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
+ {
+ if (GET_CODE (SET_DEST (set)) != MEM)
+ retval = 1;
+ else
+ return 0;
+ }
+ if (set == 0
+ && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
+ return 0;
+ }
+ if (retval == 1)
+ return 1;
+ }
+ else if (GET_RTX_CLASS (code) == 'i')
{
rtx set = single_set (insn);
@@ -1905,7 +1930,9 @@ reg_unused_after (reg, insn)
if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
return 0;
}
- prev_code = code;
+
+ if (code == CALL_INSN && call_used_regs[REGNO (reg)])
+ return 1;
}
return 1;
}