This is the mail archive of the gcc@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]

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.  */



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