MIPS & register allocation question
Richard Sandiford
rdsandiford@googlemail.com
Wed Feb 27 22:28:00 GMT 2013
"Steve Ellcey " <sellcey@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) \
More information about the Gcc
mailing list