patch: pre-compute HARD_REGNO_MODE_OK on ppc
Aldy Hernandez
aldyh@redhat.com
Tue May 4 16:45:00 GMT 2004
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.
More information about the Gcc-patches
mailing list