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);

Reply via email to