diff options
author | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-28 13:11:44 +0000 |
---|---|---|
committer | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-28 13:11:44 +0000 |
commit | b9f1cca59de85ed245cc0be1502d3004053d7305 (patch) | |
tree | a3302f4c09b4eb6c793d19de6e01698e604bf91a /gcc/combine.c | |
parent | 4f264c8b1f30ba6c58be89d6015a7b28829cf99f (diff) | |
download | gcc-b9f1cca59de85ed245cc0be1502d3004053d7305.tar.gz |
* combine.c (can_combine_p): Do not prevent building insns that use
and clobber the same fixed hard register.
(reg_dead_at_p): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83785 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 008e351ca1a..7ce6b32c59a 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1129,16 +1129,30 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ, else if (GET_CODE (dest) != CC0) return 0; - /* Don't substitute for a register intended as a clobberable operand. - Similarly, don't substitute an expression containing a register that - will be clobbered in I3. */ + if (GET_CODE (PATTERN (i3)) == PARALLEL) for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--) - if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER - && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), - src) - || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest))) - return 0; + if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER) + { + /* Don't substitute for a register intended as a clobberable + operand. */ + rtx reg = XEXP (XVECEXP (PATTERN (i3), 0, i), 0); + if (rtx_equal_p (reg, dest)) + return 0; + + /* If the clobber represents an earlyclobber operand, we must not + substitute an expression containing the clobbered register. + As we do not analyse the constraint strings here, we have to + make the conservative assumption. However, if the register is + a fixed hard reg, the clobber cannot represent any operand; + we leave it up to the machine description to either accept or + reject use-and-clobber patterns. */ + if (!REG_P (reg) + || REGNO (reg) >= FIRST_PSEUDO_REGISTER + || !fixed_regs[REGNO (reg)]) + if (reg_overlap_mentioned_p (reg, src)) + return 0; + } /* If INSN contains anything volatile, or is an `asm' (whether volatile or not), reject, unless nothing volatile comes between it and I3 */ @@ -11142,11 +11156,13 @@ reg_dead_at_p (rtx reg, rtx insn) reg_dead_flag = 0; - /* Check that reg isn't mentioned in NEWPAT_USED_REGS. */ + /* Check that reg isn't mentioned in NEWPAT_USED_REGS. For fixed registers + we allow the machine description to decide whether use-and-clobber + patterns are OK. */ if (reg_dead_regno < FIRST_PSEUDO_REGISTER) { for (i = reg_dead_regno; i < reg_dead_endregno; i++) - if (TEST_HARD_REG_BIT (newpat_used_regs, i)) + if (!fixed_regs[i] && TEST_HARD_REG_BIT (newpat_used_regs, i)) return 0; } |