This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] -fuse-caller-save - Implement TARGET_FN_OTHER_HARD_REG_USAGE hook for MIPS


Richard,

This patch implements the target hook TARGET_FN_OTHER_HARD_REG_USAGE (posted here: http://gcc.gnu.org/ml/gcc-patches/2013-03/msg01318.html) for MIPS, to address the issue that $6 is sometimes used in split calls.

Build and reg-tested on MIPS.

OK for stage1?

Thanks,
  - Tom

2013-11-12  Chung-Lin Tang  <cltang@codesourcery.com>
            Tom de Vries  <tom@codesourcery.com>

	* config/mips/mips.c (POST_CALL_TMP_REG): Define.
	(mips_split_call): Use POST_CALL_TMP_REG.
	(mips_fn_other_hard_reg_usage): New function.
	(TARGET_FN_OTHER_HARD_REG_USAGE): Define targhook using new function.

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 36ba6df..3f60f5b 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -175,6 +175,11 @@ along with GCC; see the file COPYING3.  If not see
 /* Return the usual opcode for a nop.  */
 #define MIPS_NOP 0
 
+/* Temporary register that is used after a call, and suitable for both
+   MIPS16 and non-MIPS16 code.  $4 and $5 are used for returning complex double
+   values in soft-float code, so $6 is the first suitable candidate.  */
+#define POST_CALL_TMP_REG (GP_ARG_FIRST + 2)
+
 /* Classifies an address.
 
    ADDRESS_REG
@@ -6990,10 +6995,8 @@ mips_split_call (rtx insn, rtx call_pattern)
 {
   emit_call_insn (call_pattern);
   if (!find_reg_note (insn, REG_NORETURN, 0))
-    /* Pick a temporary register that is suitable for both MIPS16 and
-       non-MIPS16 code.  $4 and $5 are used for returning complex double
-       values in soft-float code, so $6 is the first suitable candidate.  */
-    mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2));
+    mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode,
+						      POST_CALL_TMP_REG));
 }
 
 /* Return true if a call to DECL may need to use JALX.  */
@@ -18699,6 +18702,32 @@ mips_case_values_threshold (void)
   else
     return default_case_values_threshold ();
 }
+
+/* Implement TARGET_FN_OTHER_HARD_REG_USAGE.  */
+
+static void
+mips_fn_other_hard_reg_usage (struct hard_reg_set_container *fn_used_regs)
+{
+  /* POST_CALL_TMP_REG is used in splitting calls after register allocation.
+     With -fno-use-caller-save, the register is available because register
+     allocation ensures that members of call_used_regs are not live across
+     calls.
+     With -fuse-caller-save that's not the case, so we're missing a clobber on
+     the unsplit call insn to tell register allocation that the register is used
+     by the split call insn(s) after register allocation (we don't need the
+     clobber for a non-returning call, but we don't expect there will be a
+     penalty if we add the clobber for both returning and non-returning calls).
+
+     For the sake of simplicity we don't add the individual clobbers, but we use
+     this hook to mark the reg as clobbered.  This is a bit ugly, since this
+     hook is called during the final pass on a function, and we're expressing
+     here that the insn after a call to this function will clobber a register.
+
+     The condition is the pass-independent part of TARGET_SPLIT_CALLS.  */
+  if (TARGET_EXPLICIT_RELOCS
+      && TARGET_CALL_CLOBBERED_GP)
+    SET_HARD_REG_BIT (fn_used_regs->set, POST_CALL_TMP_REG);
+}
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
@@ -18933,6 +18962,9 @@ mips_case_values_threshold (void)
 #undef TARGET_CASE_VALUES_THRESHOLD
 #define TARGET_CASE_VALUES_THRESHOLD mips_case_values_threshold
 
+#undef TARGET_FN_OTHER_HARD_REG_USAGE
+#define TARGET_FN_OTHER_HARD_REG_USAGE mips_fn_other_hard_reg_usage
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-mips.h"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]