This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
rearranging REG_ALLOC_ORDER in gcc/config/rs6000/rs6000.h
- From: <gp at qnx dot com>
- To: <gcc at gcc dot gnu dot org>
- Date: Tue, 10 Jun 2003 18:56:41 -0000
- Subject: rearranging REG_ALLOC_ORDER in gcc/config/rs6000/rs6000.h
Hi.
We have found that re-arranging the REG_ALLOC_ORDER in rs6000.h so that all
the FP registers come after the integer registers greatly reduces the
tendency of the compiler to generate code that moves 8-byte quantites through
the FP registers. This is good for code that may run both on targets both
with and without an FPU, minimizing the performance hit of using an fpu-
emulator.
Consider:
uint64_t a=1,b=2;
a=b;
The current ordering produces:
...
2c: c8 1f 00 10 lfd f0,16(r31)
30: d8 1f 00 08 stfd f0,8(r31)
...
The new ordering produces:
...
2c: 81 3f 00 10 lwz r9,16(r31)
30: 81 5f 00 14 lwz r10,20(r31)
34: 91 3f 00 08 stw r9,8(r31)
38: 91 5f 00 0c stw r10,12(r31)
...
We have it implemented with a "-mno-fp-moves" arg to cc1, because you may not
always want this behavior. Here is the diff I have of rs6000.h and
rs6000.c. The main issue I see is that I am using the last bit in the target
flags (for gcc-3.2.3 - I am having trouble with cvs checkout of the head
branch to see what is available there).
Comments? Does this look useful enough for me to put together a patch for
patches-gcc? Is there another mechanism, or are there more bits available
now?
Thanks.
GP
Index: rs6000.h
===================================================================
RCS file: /product/tools/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.3.20.1.2.2
retrieving revision 1.3.20.1.2.3
diff -c -r1.3.20.1.2.2 -r1.3.20.1.2.3
*** rs6000.h 28 Apr 2003 21:35:40 -0000 1.3.20.1.2.2
--- rs6000.h 10 Jun 2003 18:12:59 -0000 1.3.20.1.2.3
***************
*** 225,230 ****
--- 225,233 ----
0x00800000 -> 0x40000000, and 0x80000000 is not available
because target_flags is signed. */
+ /* Try not to use fp registers to move 8-byte things around */
+ #define MASK_NO_FP_MOVES 0x00400000
+
#define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2)
#define TARGET_POWERPC (target_flags & MASK_POWERPC)
***************
*** 245,250 ****
--- 248,254 ----
#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG)
#define TARGET_ALTIVEC (target_flags & MASK_ALTIVEC)
#define TARGET_AIX_STRUCT_RET (target_flags & MASK_AIX_STRUCT_RET)
+ #define TARGET_NO_FP_MOVES (target_flags & MASK_NO_FP_MOVES)
#define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
***************
*** 369,374 ****
--- 373,382 ----
""},\
{"no-svr4-struct-return", MASK_AIX_STRUCT_RET | MASK_AIX_STRUCT_RET_SET,\
""},\
+ {"fp-moves", - MASK_NO_FP_MOVES,\
+ N_("Use FP regs to move 8 byte values around.")},\
+ {"no-fp-moves", MASK_NO_FP_MOVES,\
+ N_("Try not to use FP regs to move 8 byte values
around.")},\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT | MASK_SCHED_PROLOG,
\
""}}
***************
*** 810,815 ****
--- 818,853 ----
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
18, 17, 16, 15, 14, 13, 12, \
64, 66, 65, \
+ 73, 1, 2, 67, 76, \
+ /* AltiVec registers. */ \
+ 77, 78, \
+ 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
+ 79, \
+ 96, 95, 94, 93, 92, 91, \
+ 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, \
+ 97, 109 \
+ }
+
+ /*
+ Alternative register ordering; we move all the FP registers to be
+ after the integer registers; this will greatly reduce the tendency
+ of the compiler to generate code that moves 8-byte quantites through the
+ FP registers. Good for code that may run both on targets with/without an
FPU.
+ */
+
+ #define RS6000_REG_ALT_ALLOC_ORDER \
+ {69, 74, 75, 68, 70, 71, 72, \
+ 0, \
+ 9, 11, 10, 8, 7, 6, 5, 4, \
+ 3, \
+ 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
+ 18, 17, 16, 15, 14, 13, 12, \
+ 32, \
+ 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, \
+ 33, \
+ 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, \
+ 64, 66, 65, \
73, 1, 2, 67, 76, \
/* AltiVec registers. */ \
77, 78, \
Index: rs6000.c
===================================================================
RCS file: /product/tools/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.3.20.1.2.3
retrieving revision 1.3.20.1.2.4
diff -c -r1.3.20.1.2.3 -r1.3.20.1.2.4
*** rs6000.c 28 Apr 2003 21:35:40 -0000 1.3.20.1.2.3
--- rs6000.c 10 Jun 2003 18:12:59 -0000 1.3.20.1.2.4
***************
*** 201,206 ****
--- 203,213 ----
"vrsave"
};
+ #ifdef RS6000_REG_ALT_ALLOC_ORDER
+ static int rs6000_reg_alt_alloc_order[FIRST_PSEUDO_REGISTER] =
+ RS6000_REG_ALT_ALLOC_ORDER;
+ #endif
+
#ifdef TARGET_REGNAMES
static const char alt_reg_names[][8] =
{
***************
*** 536,541 ****
--- 543,555 ----
/* Handle -mabi= options. */
rs6000_parse_abi_options ();
+ if (TARGET_NO_FP_MOVES)
+ {
+ #ifdef RS6000_REG_ALT_ALLOC_ORDER
+ memmove ((char *)reg_alloc_order, (char *)rs6000_reg_alt_alloc_order,
sizeof (rs6000_reg_alt_alloc_order));
+ #endif
+ }
+
#ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the
alternate names now. */