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: pre-compute HARD_REGNO_MODE_OK on ppc


As promised.  This pre-calculates HARD_REGNO_MODE_OK, since it's
called from many critical paths.

Tested on powerpc-linux-gnualtivec.  All languages except Ada.

Ok?

Aldy

P.S. Yes, I looked at Arc-- this is just cleaner, and memory is a lot
cheaper these days.

	* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_p): New.
	(rs6000_hard_regno_mode_ok): New.
	(rs6000_init_hard_regno_mode_ok): New.
	(rs6000_override_options): Call rs6000_init_hard_regno_mode_ok.

	* config/rs6000/rs6000.h (HARD_REGNO_NREGS): Use precomputed
	result.

Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.633
diff -c -p -r1.633 rs6000.c
*** config/rs6000/rs6000.c	4 May 2004 02:24:51 -0000	1.633
--- config/rs6000/rs6000.c	4 May 2004 16:28:31 -0000
*************** const char *rs6000_debug_name;
*** 215,220 ****
--- 215,223 ----
  int rs6000_debug_stack;		/* debug stack applications */
  int rs6000_debug_arg;		/* debug argument handling */
  
+ /* Value is 1 if register/mode pair is accepatable.  */
+ unsigned int *rs6000_hard_regno_mode_ok_p;
+ 
  /* Opaque types.  */
  static GTY(()) tree opaque_V2SI_type_node;
  static GTY(()) tree opaque_V2SF_type_node;
*************** static const char alt_reg_names[][8] =
*** 644,649 ****
--- 647,709 ----
  
  struct gcc_target targetm = TARGET_INITIALIZER;
  
+ 
+ /* Value is 1 if hard register REGNO can hold a value of machine-mode
+    MODE.  */
+ static int
+ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
+ {
+   /* The GPRs can hold any mode, but values bigger than one register
+      cannot go past R31.  */
+   if (INT_REGNO_P (regno))
+     return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
+ 
+   /* ...but GPRs can hold SIMD data on the SPE in one register.  */
+   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+     return 1;
+ 
+   /* The float registers can only hold floating modes and DImode.  */
+   if (FP_REGNO_P (regno))
+     return
+       (GET_MODE_CLASS (mode) == MODE_FLOAT
+        && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
+       || (GET_MODE_CLASS (mode) == MODE_INT
+ 	  && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
+ 
+   /* The CR register can only hold CC modes.  */
+   if (CR_REGNO_P (regno))
+     return GET_MODE_CLASS (mode) == MODE_CC;
+ 
+   if (XER_REGNO_P (regno))
+     return mode == PSImode;
+ 
+   /* AltiVec only in AldyVec registers.  */
+   if (ALTIVEC_REGNO_P (regno))
+     return ALTIVEC_VECTOR_MODE (mode);
+ 
+   /* We cannot put TImode anywhere except general register and it must be
+      able to fit within the register set.  */
+ 
+   return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
+ }
+ 
+ /* Initialize rs6000_hard_regno_mode_ok_p table.  */
+ static void
+ rs6000_init_hard_regno_mode_ok (void)
+ {
+   int r, m;
+ 
+   rs6000_hard_regno_mode_ok_p
+     = (unsigned int *) xmalloc (sizeof (int *)
+ 				* NUM_MACHINE_MODES
+ 				* FIRST_PSEUDO_REGISTER);
+ 
+   for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+     for (m = 0; m < NUM_MACHINE_MODES; ++m)
+       if (rs6000_hard_regno_mode_ok (r, m))
+ 	rs6000_hard_regno_mode_ok_p[m * FIRST_PSEUDO_REGISTER + r] = 1;
+ }
+ 
  /* Override command line options.  Mostly we process the processor
     type and sometimes adjust other TARGET_ options.  */
  
*************** rs6000_override_options (const char *def
*** 746,751 ****
--- 806,814 ----
  		     | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
  		     | MASK_MFCRF)
    };
+ 
+   rs6000_init_hard_regno_mode_ok ();
+ 
   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
  #ifdef OS_MISSING_POWERPC64
    if (OS_MISSING_POWERPC64)
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.321
diff -c -p -r1.321 rs6000.h
*** config/rs6000/rs6000.h	4 May 2004 02:24:51 -0000	1.321
--- config/rs6000/rs6000.h	4 May 2004 16:28:33 -0000
*************** extern const char *rs6000_warn_altivec_l
*** 1026,1051 ****
          ((TARGET_SPE && SPE_VECTOR_MODE (MODE))		\
  	 || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
  
! /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
!    For POWER and PowerPC, the GPRs can hold any mode, but values bigger
!    than one register cannot go past R31.  The float
!    registers only can hold floating modes and DImode, and CR register only
!    can hold CC modes.  We cannot put TImode anywhere except general
!    register and it must be able to fit within the register set.  */
  
! #define HARD_REGNO_MODE_OK(REGNO, MODE)					\
!   (INT_REGNO_P (REGNO) ?						\
!      INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)	        \
!    : FP_REGNO_P (REGNO) ?						\
!      ((GET_MODE_CLASS (MODE) == MODE_FLOAT				\
!        && FP_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1))	\
!       || (GET_MODE_CLASS (MODE) == MODE_INT				\
! 	  && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))		\
!    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
!    : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
!    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
!    : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
!    : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
  
  /* Value is 1 if it is a good idea to tie two pseudo registers
     when one has mode MODE1 and one has mode MODE2.
--- 1026,1036 ----
          ((TARGET_SPE && SPE_VECTOR_MODE (MODE))		\
  	 || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
  
! /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.  */
  
! extern unsigned int *rs6000_hard_regno_mode_ok_p;
! #define HARD_REGNO_MODE_OK(REGNO, MODE) \
!   rs6000_hard_regno_mode_ok_p[(int)(MODE) * FIRST_PSEUDO_REGISTER + (REGNO)]
  
  /* Value is 1 if it is a good idea to tie two pseudo registers
     when one has mode MODE1 and one has mode MODE2.


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