Eric,
This patch adds scanning of clobbers in CALL_INSN_FUNCTION_USAGE to
find_all_hard_reg_sets.
For MIPS, calls are split at some point. After the split, one of the resulting
insns may clobber $6. But before the split, that's not explicit in the rtl
representation of the unsplit call.
For -fuse-caller-save, that's a problem, and Richard S. suggested to add the
clobber of $6 to the CALL_INSN_FUNCTION_USAGE of the unsplit call.
I wrote a patch for that (
http://gcc.gnu.org/ml/gcc-patches/2014-01/msg00730.html ), but found that doing
so did not fix the problem with -fuse-caller-save, because
find_all_hard_reg_sets (the mechanism -fuse-caller-save uses to detect which
registers are set or clobbered) does not take CALL_INSN_FUNCTION_USAGE into
account. This patch fixes that.
Build and reg-tested on MIPS.
OK for stage1 if x86_64 bootstrap & reg-test succeeds?
Thanks,
- Tom
2014-01-15 Tom de Vries <t...@codesourcery.com>
* rtlanal.c (find_all_hard_reg_sets): Note INSN_CALL_FUNCTION_USAGE
clobbers.
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 7e27774..64f83ac 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1034,8 +1034,25 @@ find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset, bool implicit)
CLEAR_HARD_REG_SET (*pset);
note_stores (PATTERN (insn), record_hard_reg_sets, pset);
- if (implicit && CALL_P (insn))
- IOR_HARD_REG_SET (*pset, call_used_reg_set);
+ if (CALL_P (insn))
+ {
+ if (implicit)
+ IOR_HARD_REG_SET (*pset, call_used_reg_set);
+
+ for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
+ {
+ rtx op, reg;
+
+ if (GET_CODE (op = XEXP (link, 0)) == CLOBBER
+ && REG_P (reg = XEXP (op, 0)))
+ {
+ unsigned int i;
+
+ for (i = REGNO (reg) ; i < END_HARD_REGNO (reg); i++)
+ SET_HARD_REG_BIT (*pset, i);
+ }
+ }
+ }
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC)
record_hard_reg_sets (XEXP (link, 0), NULL, pset);