From: Anatoly Sokolov Date: Tue, 19 Jul 2011 22:34:31 +0000 (+0400) Subject: target.def (class_max_nregs): New hook. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a8c44c522d6c1924edc36dc7d803417b7e0dea12;p=gcc.git target.def (class_max_nregs): New hook. * target.def (class_max_nregs): New hook. * doc/tm.texi.in (TARGET_CLASS_MAX_NREGS): Document. * doc/tm.texi: Regenerate. * targhooks.c (default_class_max_nregs): New function. * targhooks.h (default_class_max_nregs): Declare. * ira.h (target_ira): Change type x_ira_reg_class_max_nregs and x_ira_reg_class_min_nregs arrays to unsigned char. * ira.c (setup_reg_class_nregs): Use TARGET_CLASS_MAX_NREGS target hook instead of CLASS_MAX_NREGS macro. * reginfo.c (restore_register_info): Ditto. * ira-conflicts.c (process_regs_for_copy): Use ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro. Change type rclass and aclass vars to reg_class_t. * ira-costs.c (record_reg_classes): Use ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro. Change type rclass var to reg_class_t. * reload.c (combine_reloads, find_reloads, find_reloads_address_1): Use ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro. * config/i386/i386.h (CLASS_MAX_NREGS): Remove. * config/i386/i386.c (ix86_class_max_nregs): New function. (ix86_register_move_cost): Use TARGET_CLASS_MAX_NREGS target hook instead of CLASS_MAX_NREGS macro. (TARGET_CLASS_MAX_NREGS): Define. * config/avr/avr.h (CLASS_MAX_NREGS): Remove. * config/avr/avr-protos.h (class_max_nregs): Remove declaration. * config/avr/avr.c (class_max_nregs): Remove function. * config/alpha/alpha.h (CLASS_MAX_NREGS): Remove. * config/spu/spu.h (CLASS_MAX_NREGS): Remove. * config/mep/mep.h (CLASS_MAX_NREGS): Remove. * config/m32r/m32r.h (CLASS_MAX_NREGS): Remove. * config/microblaze/microblaze.h (CLASS_MAX_NREGS): Remove. * config/xtensa/xtensa.h (CLASS_MAX_NREGS): Remove. * config/stormy16/stormy16.h (CLASS_MAX_NREGS): Remove. * config/lm32/lm32.h (CLASS_MAX_NREGS): Remove. * config/moxie/moxie.h (CLASS_MAX_NREGS): Remove. * config/iq2000/iq2000.h (CLASS_MAX_NREGS): Remove. * config/mn10300/mn10300.h (CLASS_MAX_NREGS): Remove. * config/score/score.h (CLASS_MAX_NREGS): Remove. * config/vax/vax.h (CLASS_MAX_NREGS): Remove. * config/h8300/h8300.h (CLASS_MAX_NREGS): Remove. * config/v850/v850.h (CLASS_MAX_NREGS): Remove. From-SVN: r176490 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1dd9ca8e12a..26eb56f7f96 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,48 @@ +2011-07-20 Anatoly Sokolov + + * target.def (class_max_nregs): New hook. + * doc/tm.texi.in (TARGET_CLASS_MAX_NREGS): Document. + * doc/tm.texi: Regenerate. + * targhooks.c (default_class_max_nregs): New function. + * targhooks.h (default_class_max_nregs): Declare. + * ira.h (target_ira): Change type x_ira_reg_class_max_nregs and + x_ira_reg_class_min_nregs arrays to unsigned char. + * ira.c (setup_reg_class_nregs): Use TARGET_CLASS_MAX_NREGS target + hook instead of CLASS_MAX_NREGS macro. + * reginfo.c (restore_register_info): Ditto. + * ira-conflicts.c (process_regs_for_copy): Use + ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro. + Change type rclass and aclass vars to reg_class_t. + * ira-costs.c (record_reg_classes): Use ira_reg_class_max_nregs + array instead of CLASS_MAX_NREGS macro. Change type rclass var to + reg_class_t. + * reload.c (combine_reloads, find_reloads, find_reloads_address_1): + Use ira_reg_class_max_nregs array instead of CLASS_MAX_NREGS macro. + + * config/i386/i386.h (CLASS_MAX_NREGS): Remove. + * config/i386/i386.c (ix86_class_max_nregs): New function. + (ix86_register_move_cost): Use TARGET_CLASS_MAX_NREGS target hook + instead of CLASS_MAX_NREGS macro. + (TARGET_CLASS_MAX_NREGS): Define. + * config/avr/avr.h (CLASS_MAX_NREGS): Remove. + * config/avr/avr-protos.h (class_max_nregs): Remove declaration. + * config/avr/avr.c (class_max_nregs): Remove function. + * config/alpha/alpha.h (CLASS_MAX_NREGS): Remove. + * config/spu/spu.h (CLASS_MAX_NREGS): Remove. + * config/mep/mep.h (CLASS_MAX_NREGS): Remove. + * config/m32r/m32r.h (CLASS_MAX_NREGS): Remove. + * config/microblaze/microblaze.h (CLASS_MAX_NREGS): Remove. + * config/xtensa/xtensa.h (CLASS_MAX_NREGS): Remove. + * config/stormy16/stormy16.h (CLASS_MAX_NREGS): Remove. + * config/lm32/lm32.h (CLASS_MAX_NREGS): Remove. + * config/moxie/moxie.h (CLASS_MAX_NREGS): Remove. + * config/iq2000/iq2000.h (CLASS_MAX_NREGS): Remove. + * config/mn10300/mn10300.h (CLASS_MAX_NREGS): Remove. + * config/score/score.h (CLASS_MAX_NREGS): Remove. + * config/vax/vax.h (CLASS_MAX_NREGS): Remove. + * config/h8300/h8300.h (CLASS_MAX_NREGS): Remove. + * config/v850/v850.h (CLASS_MAX_NREGS): Remove. + 2011-07-19 Eric Botcazou * cif-code.def (OVERWRITABLE): Fix typo and move around. diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index cc16cfa974e..07ffa9fe8b1 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -549,12 +549,6 @@ enum reg_class { : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Return the class of registers that cannot change mode from FROM to TO. */ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 718aa420c74..9b95caa0111 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -110,10 +110,6 @@ extern void out_shift_with_cnt (const char *templ, rtx insn, extern rtx avr_incoming_return_addr_rtx (void); #endif /* RTX_CODE */ -#ifdef HAVE_MACHINE_MODES -extern int class_max_nregs (enum reg_class rclass, enum machine_mode mode); -#endif /* HAVE_MACHINE_MODES */ - #ifdef REAL_VALUE_TYPE extern void asm_output_float (FILE *file, REAL_VALUE_TYPE n); #endif diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 209a5b92a04..ebfec0da024 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -1491,15 +1491,6 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn) } } -/* Return maximum number of consecutive registers of - class CLASS needed to hold a value of mode MODE. */ - -int -class_max_nregs (enum reg_class rclass ATTRIBUTE_UNUSED,enum machine_mode mode) -{ - return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); -} - /* Choose mode for jump insn: 1 - relative jump in range -63 <= x <= 62 ; 2 - relative jump in range -2046 <= x <= 2045 ; diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 9b27f703807..ddd30d6ee3a 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -312,8 +312,6 @@ enum reg_class { #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true -#define CLASS_MAX_NREGS(CLASS, MODE) class_max_nregs (CLASS, MODE) - #define STACK_PUSH_CODE POST_DEC #define STACK_GROWS_DOWNWARD diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 936aabfa229..82e55f6628b 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -357,14 +357,6 @@ enum reg_class { #define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS) #define BASE_REG_CLASS GENERAL_REGS -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ - -/* On the H8, this is the size of MODE in words. */ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Stack layout; function entry, exit and calling. */ /* Define this if pushing a word on the stack diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a87fb29d5e3..814250fa24e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -28263,6 +28263,32 @@ ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2, return inline_secondary_memory_needed (class1, class2, mode, strict); } +/* Implement the TARGET_CLASS_MAX_NREGS hook. + + On the 80386, this is the size of MODE in words, + except in the FP regs, where a single reg is always enough. */ + +static unsigned char +ix86_class_max_nregs (reg_class_t rclass, enum machine_mode mode) +{ + if (MAYBE_INTEGER_CLASS_P (rclass)) + { + if (mode == XFmode) + return (TARGET_64BIT ? 2 : 3); + else if (mode == XCmode) + return (TARGET_64BIT ? 4 : 6); + else + return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); + } + else + { + if (COMPLEX_MODE_P (mode)) + return 2; + else + return 1; + } +} + /* Return true if the registers in CLASS cannot represent the change from modes FROM to TO. */ @@ -28459,7 +28485,8 @@ ix86_register_move_cost (enum machine_mode mode, reg_class_t class1_i, /* In case of copying from general_purpose_register we may emit multiple stores followed by single load causing memory size mismatch stall. Count this as arbitrarily high cost of 20. */ - if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode)) + if (targetm.class_max_nregs (class1, mode) + > targetm.class_max_nregs (class2, mode)) cost += 20; /* In the case of FP/MMX moves, the registers actually overlap, and we @@ -34931,6 +34958,9 @@ ix86_autovectorize_vector_sizes (void) #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD ix86_secondary_reload +#undef TARGET_CLASS_MAX_NREGS +#define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs + #undef TARGET_PREFERRED_RELOAD_CLASS #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 4c7df9d1b1d..47c1388c9c0 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1357,19 +1357,6 @@ enum reg_class ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ : MODE) -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -/* On the 80386, this is the size of MODE in words, - except in the FP regs, where a single reg is always enough. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - (MAYBE_INTEGER_CLASS_P (CLASS) \ - ? ((MODE) == XFmode \ - ? (TARGET_64BIT ? 2 : 3) \ - : (MODE) == XCmode \ - ? (TARGET_64BIT ? 4 : 6) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) \ - : (COMPLEX_MODE_P (MODE) ? 2 : 1)) - /* Return a class of registers that cannot change FROM mode to TO mode. */ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index e909ef94b57..130acc9b384 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -228,9 +228,6 @@ enum reg_class ? (GR_REGS) \ : (CLASS)))) -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Basic Stack Layout. */ diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h index 75a24160fd9..5c516860bed 100644 --- a/gcc/config/lm32/lm32.h +++ b/gcc/config/lm32/lm32.h @@ -202,9 +202,6 @@ enum reg_class #define REGNO_REG_CLASS(REGNO) \ (G_REG_P(REGNO) ? GENERAL_REGS : NO_REGS) -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - #define INDEX_REG_CLASS NO_REGS #define BASE_REG_CLASS GENERAL_REGS diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 50b5b2aa1a3..0072b2f0da3 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -509,11 +509,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; #define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO) -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Return true if a value is inside a range. */ #define IN_RANGE_P(VALUE, LOW, HIGH) \ (((unsigned HOST_WIDE_INT)((VALUE) - (LOW))) \ diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h index f5de83f5d1d..dbb48143034 100644 --- a/gcc/config/mep/mep.h +++ b/gcc/config/mep/mep.h @@ -428,9 +428,6 @@ enum reg_class #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ mep_secondary_memory_needed (CLASS1, CLASS2, MODE) -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - #if 0 #define CONST_OK_FOR_LETTER_P(VALUE, C) mep_const_ok_for_letter_p (VALUE, C) diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h index a667acadaf8..92f0f60f1ff 100644 --- a/gcc/config/microblaze/microblaze.h +++ b/gcc/config/microblaze/microblaze.h @@ -388,9 +388,6 @@ extern enum reg_class microblaze_regno_to_class[]; #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ (GET_MODE_CLASS (MODE) == MODE_INT) -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + (UNITS_PER_WORD) - 1) / (UNITS_PER_WORD)) - /* Stack layout; function entry, exit and calling. */ #define STACK_GROWS_DOWNWARD diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index 7f70d5b25d2..79b20f5a4d8 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -388,12 +388,6 @@ enum reg_class #define LIMIT_RELOAD_CLASS(MODE, CLASS) \ (!TARGET_AM33 && (MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS) -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* A class that contains registers which the compiler must always access in a mode that is the same size as the mode in which it loaded the register. */ diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h index 86c66631441..d2a455b289c 100644 --- a/gcc/config/moxie/moxie.h +++ b/gcc/config/moxie/moxie.h @@ -189,11 +189,6 @@ enum reg_class accessible in mode MODE2 without copying. */ #define MODES_TIEABLE_P(MODE1, MODE2) 1 -/* A C expression for the maximum number of consecutive registers of - class CLASS needed to hold a value of mode MODE. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* The Overall Framework of an Assembler File */ #undef ASM_SPEC diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h index 1f9975600fe..3c8851a602f 100644 --- a/gcc/config/score/score.h +++ b/gcc/config/score/score.h @@ -418,11 +418,6 @@ extern enum reg_class score_char_to_class[256]; #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ score_secondary_reload_class (CLASS, MODE, X) -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ ? reg_classes_intersect_p (HI_REG, (CLASS)) : 0) diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index 16258911ef3..c69cf7efc4e 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -225,9 +225,6 @@ enum reg_class { #define INT_REG_OK_FOR_BASE_P(X,STRICT) \ ((!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X)))) -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* GCC assumes that modes are in the lowpart of a register, which is only true for SPU. */ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index 871e523a67b..43833625608 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -227,9 +227,6 @@ enum reg_class #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \ xstormy16_secondary_reload_class (CLASS, MODE, X) -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Basic Stack Layout. */ diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index 0784d89bf67..f5b64deab2b 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -341,12 +341,6 @@ enum reg_class #define REGNO_OK_FOR_INDEX_P(regno) 0 -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Convenience wrappers around insn_const_int_ok_for_constraint. */ #define CONST_OK_FOR_I(VALUE) \ diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index a3e9d83e8f8..0c835637ae1 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -219,11 +219,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define REG_CLASS_NAMES \ { "NO_REGS", "ALL_REGS" } -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - /* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET of length N_REG_CLASSES. */ @@ -242,12 +237,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define INDEX_REG_CLASS ALL_REGS #define BASE_REG_CLASS ALL_REGS -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -/* On the VAX, this is always the size of MODE in words, - since all registers are the same size. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) /* Stack layout; function entry, exit and calling. */ diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index d3ce1479443..b1a24c6d86d 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -450,15 +450,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; the RTL, as either incoming or outgoing arguments. */ #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -#define CLASS_UNITS(mode, size) \ - ((GET_MODE_SIZE (mode) + (size) - 1) / (size)) - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - (CLASS_UNITS (MODE, UNITS_PER_WORD)) - - /* Stack layout; function entry, exit and calling. */ #define STACK_GROWS_DOWNWARD diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 08acb351ba3..097531f7f6b 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2846,6 +2846,23 @@ the only effect of such implementation would be to slow down register allocation. @end deftypefn +@deftypefn {Target Hook} {unsigned char} TARGET_CLASS_MAX_NREGS (reg_class_t @var{rclass}, enum machine_mode @var{mode}) +A target hook returns the maximum number of consecutive registers +of class @var{rclass} needed to hold a value of mode @var{mode}. + +This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact, +the value returned by @code{TERGET_CLASS_MAX_NREGS (@var{rclass}, +@var{mode})} target hook should be the maximum value of +@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno} +values in the class @var{rclass}. + +This target hook helps control the handling of multiple-word values +in the reload pass. + +The default version of this target hook returns the size of @var{mode} +in words. +@end deftypefn + @defmac CLASS_MAX_NREGS (@var{class}, @var{mode}) A C expression for the maximum number of consecutive registers of class @var{class} needed to hold a value of mode @var{mode}. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 7990c763a73..01beeb47920 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2832,6 +2832,23 @@ the only effect of such implementation would be to slow down register allocation. @end deftypefn +@hook TARGET_CLASS_MAX_NREGS +A target hook returns the maximum number of consecutive registers +of class @var{rclass} needed to hold a value of mode @var{mode}. + +This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact, +the value returned by @code{TERGET_CLASS_MAX_NREGS (@var{rclass}, +@var{mode})} target hook should be the maximum value of +@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno} +values in the class @var{rclass}. + +This target hook helps control the handling of multiple-word values +in the reload pass. + +The default version of this target hook returns the size of @var{mode} +in words. +@end deftypefn + @defmac CLASS_MAX_NREGS (@var{class}, @var{mode}) A C expression for the maximum number of consecutive registers of class @var{class} needed to hold a value of mode @var{mode}. diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index be002839fa2..3df65709f6f 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -393,7 +393,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, int allocno_preferenced_hard_regno, cost, index, offset1, offset2; bool only_regs_p; ira_allocno_t a; - enum reg_class rclass, aclass; + reg_class_t rclass, aclass; enum machine_mode mode; ira_copy_t cp; @@ -438,7 +438,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, mode = ALLOCNO_MODE (a); aclass = ALLOCNO_CLASS (a); if (only_regs_p && insn != NULL_RTX - && reg_class_size[rclass] <= (unsigned) CLASS_MAX_NREGS (rclass, mode)) + && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode]) /* It is already taken into account in ira-costs.c. */ return false; index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno]; diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index da14089f913..39ef33a541c 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -930,15 +930,15 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, enum machine_mode mode = GET_MODE (ops[!i]); cost_classes_t cost_classes_ptr = regno_cost_classes[regno]; enum reg_class *cost_classes = cost_classes_ptr->classes; - enum reg_class rclass; + reg_class_t rclass; int nr; for (k = cost_classes_ptr->num - 1; k >= 0; k--) { rclass = cost_classes[k]; if (TEST_HARD_REG_BIT (reg_class_contents[rclass], other_regno) - && (reg_class_size[rclass] - == (unsigned) CLASS_MAX_NREGS (rclass, mode))) + && (reg_class_size[(int) rclass] + == ira_reg_class_max_nregs [(int) rclass][(int) mode])) { if (reg_class_size[rclass] == 1) op_costs[i]->cost[k] = -frequency; diff --git a/gcc/ira.c b/gcc/ira.c index 6cca90807df..b54762e8962 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1403,7 +1403,7 @@ setup_reg_class_nregs (void) for (cl = 0; cl < N_REG_CLASSES; cl++) ira_reg_class_max_nregs[cl][m] = ira_reg_class_min_nregs[cl][m] - = CLASS_MAX_NREGS ((enum reg_class) cl, (enum machine_mode) m); + = targetm.class_max_nregs ((reg_class_t) cl, (enum machine_mode) m); for (cl = 0; cl < N_REG_CLASSES; cl++) for (i = 0; (cl2 = alloc_reg_class_subclasses[cl][i]) != LIM_REG_CLASSES; diff --git a/gcc/ira.h b/gcc/ira.h index a31a03ca21b..60518ecb313 100644 --- a/gcc/ira.h +++ b/gcc/ira.h @@ -68,8 +68,8 @@ struct target_ira { /* Maps: register class x machine mode -> maximal/minimal number of hard registers of given class needed to store value of given mode. */ - int x_ira_reg_class_max_nregs[N_REG_CLASSES][MAX_MACHINE_MODE]; - int x_ira_reg_class_min_nregs[N_REG_CLASSES][MAX_MACHINE_MODE]; + unsigned char x_ira_reg_class_max_nregs[N_REG_CLASSES][MAX_MACHINE_MODE]; + unsigned char x_ira_reg_class_min_nregs[N_REG_CLASSES][MAX_MACHINE_MODE]; /* Array analogous to target hook TARGET_MEMORY_MOVE_COST. */ short x_ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2]; diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 1da4cb8f40a..537364192da 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -529,8 +529,7 @@ init_reg_sets_1 (void) SET_HARD_REG_BIT (ok_regs, j); for (i = 0; i < N_REG_CLASSES; i++) - if (((unsigned) CLASS_MAX_NREGS ((enum reg_class) i, - (enum machine_mode) m) + if ((targetm.class_max_nregs ((reg_class_t) i, (enum machine_mode) m) <= reg_class_size[i]) && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i])) { diff --git a/gcc/reload.c b/gcc/reload.c index b5e991e386d..c671765ba93 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -1767,9 +1767,9 @@ combine_reloads (void) && rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS && rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS && rld[i].when_needed != RELOAD_OTHER - && (CLASS_MAX_NREGS (rld[i].rclass, rld[i].inmode) - == CLASS_MAX_NREGS (rld[output_reload].rclass, - rld[output_reload].outmode)) + && (ira_reg_class_max_nregs [(int)rld[i].rclass][(int) rld[i].inmode] + == ira_reg_class_max_nregs [(int) rld[output_reload].rclass] + [(int) rld[output_reload].outmode]) && rld[i].inc == 0 && rld[i].reg_rtx == 0 #ifdef SECONDARY_MEMORY_NEEDED @@ -4542,7 +4542,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, > GET_MODE_SIZE (rld[i].inmode))) ? rld[i].outmode : rld[i].inmode; - rld[i].nregs = CLASS_MAX_NREGS (rld[i].rclass, rld[i].mode); + rld[i].nregs = ira_reg_class_max_nregs [rld[i].rclass][rld[i].mode]; } /* Special case a simple move with an input reload and a @@ -5992,8 +5992,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, else { enum reg_class rclass = context_reg_class; - if ((unsigned) CLASS_MAX_NREGS (rclass, GET_MODE (SUBREG_REG (x))) - > reg_class_size[rclass]) + if (ira_reg_class_max_nregs [rclass][GET_MODE (SUBREG_REG (x))] + > reg_class_size[(int) rclass]) { x = find_reloads_subreg_address (x, 0, opnum, ADDR_TYPE (type), diff --git a/gcc/target.def b/gcc/target.def index 3a0b413a80a..9ff97e690e9 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2245,6 +2245,14 @@ DEFHOOK bool, (reg_class_t rclass), default_class_likely_spilled_p) +/* Return the maximum number of consecutive registers + needed to represent mode MODE in a register of class RCLASS. */ +DEFHOOK +(class_max_nregs, + "", + unsigned char, (reg_class_t rclass, enum machine_mode mode), + default_class_max_nregs) + DEFHOOK (preferred_rename_class, "A target hook that places additional preference on the register\ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index f69b39626a6..16d0b189f65 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1309,6 +1309,19 @@ default_class_likely_spilled_p (reg_class_t rclass) return (reg_class_size[(int) rclass] == 1); } +/* The default implementation of TARGET_CLASS_MAX_NREGS. */ + +unsigned char +default_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED) +{ +#ifdef CLASS_MAX_NREGS + return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass, mode); +#else + return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); +#endif +} + /* Determine the debugging unwind mechanism for the target. */ enum unwind_info_type diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 62e888445bb..552407b21db 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -163,6 +163,7 @@ extern reg_class_t default_preferred_reload_class (rtx, reg_class_t); extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t); extern reg_class_t default_preferred_rename_class (reg_class_t rclass); extern bool default_class_likely_spilled_p (reg_class_t); +extern unsigned char default_class_max_nregs (reg_class_t, enum machine_mode); extern enum unwind_info_type default_debug_unwind_info (void);