"Steve Ellcey " <sell...@imgtec.com> writes:
> I was looking at MIPS register allocation and I noticed an odd thing.
> There is a definition of REG_ALLOC_ORDER in mips.h but in 
> mips_order_regs_for_local_alloc (mips.c), we do not use this ordering,
> we just have:
>
>   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>     reg_alloc_order[i] = i;
>
> I was wondering why we don't use something like ARM has.
> I.e.:
>
>   const int mips_reg_alloc_order[] = REG_ALLOC_ORDER;
>   memcpy(reg_alloc_order, mips_reg_alloc_order, sizeof (reg_alloc_order));

Yeah, it's one of those historical accidents.  Chung-Lin did some good
archaeology on it:

   http://gcc.gnu.org/ml/gcc/2011-01/msg00093.html

FWIW, after seeing that, I tried the patch below.  Disabling
ADJUST_REG_ALLOC_ORDER seemed to be a very mixed bag sizewise though --
certainly not the consistent win that I hoped -- and I wasn't set up to
do proper speed testing.  In the end I'm afraid I just let it drop.

Thanks,
Richard


Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h       2011-09-17 10:18:14.000000000 +0100
+++ gcc/config/mips/mips-protos.h       2011-09-17 19:22:49.000000000 +0100
@@ -248,7 +248,6 @@ extern bool mips_expand_ext_as_unaligned
 extern bool mips_expand_ins_as_unaligned_store (rtx, rtx, HOST_WIDE_INT,
                                                HOST_WIDE_INT);
 extern bool mips_mem_fits_mode_p (enum machine_mode mode, rtx x);
-extern void mips_order_regs_for_local_alloc (void);
 extern HOST_WIDE_INT mips_debugger_offset (rtx, HOST_WIDE_INT);
 
 extern void mips_push_asm_switch (struct mips_asm_switch *);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c      2011-09-17 08:59:21.000000000 +0100
+++ gcc/config/mips/mips.c      2011-09-17 19:22:49.000000000 +0100
@@ -15900,28 +15900,6 @@ mips_expand_vector_init (rtx target, rtx
   emit_move_insn (target, mem);
 }
 
-/* When generating MIPS16 code, we want to allocate $24 (T_REG) before
-   other registers for instructions for which it is possible.  This
-   encourages the compiler to use CMP in cases where an XOR would
-   require some register shuffling.  */
-
-void
-mips_order_regs_for_local_alloc (void)
-{
-  int i;
-
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    reg_alloc_order[i] = i;
-
-  if (TARGET_MIPS16)
-    {
-      /* It really doesn't matter where we put register 0, since it is
-         a fixed register anyhow.  */
-      reg_alloc_order[0] = 24;
-      reg_alloc_order[24] = 0;
-    }
-}
-
 /* Implement EH_USES.  */
 
 bool
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h      2011-09-17 08:51:17.000000000 +0100
+++ gcc/config/mips/mips.h      2011-09-17 10:18:04.000000000 +0100
@@ -1930,9 +1930,18 @@ #define REG_ALLOC_ORDER                                  
                \
      of the extra accumulators available with -mdspr2.  In some cases, \
      it can also help to reduce register pressure.  */                 \
   64, 65,176,177,178,179,180,181,                                      \
-  /* Call-clobbered GPRs.  */                                          \
-  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,           \
-  24, 25, 31,                                                          \
+  /* Call-clobbered GPRs.  Put $24 first, because when M16_REGS and    \
+     T_REG have equal cost, we prefer to use T_REG.  In particular,    \
+     it means that CMP+branch sequences will generally be preferred    \
+     to XOR+branch sequences; the former are shorter, and using T_REG  \
+     reduces the register pressure on the main MIPS16 registers.       \
+     This does not seem to adversely affect non-MIPS16 code.           \
+                                                                       \
+     Normally we'd keep register pairs together, but in this case,     \
+     it's better not to.  $25 is not a MIPS16 register, and in         \
+     abicalls code, we'd prefer to leave it free for its ABI use.  */  \
+  24, 2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,           \
+  25, 1,  31,                                                          \
   /* The global pointer.  This is call-clobbered for o32 and o64       \
      abicalls, call-saved for n32 and n64 abicalls, and a program      \
      invariant otherwise.  Putting it between the call-clobbered       \
@@ -1964,13 +1973,6 @@ #define REG_ALLOC_ORDER                                  
                \
   182,183,184,185,186,187                                              \
 }
 
-/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order
-   to be rearranged based on a particular function.  On the mips16, we
-   want to allocate $24 (T_REG) before other registers for
-   instructions for which it is possible.  */
-
-#define ADJUST_REG_ALLOC_ORDER mips_order_regs_for_local_alloc ()
-
 /* True if VALUE is an unsigned 6-bit number.  */
 
 #define UIMM6_OPERAND(VALUE) \

Reply via email to