Message ID | 87d176itmx.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Make more use of opt_mode | expand |
On Mon, Sep 4, 2017 at 1:35 PM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > ...to make it consistent with int_mode_for_size etc. > > require () seems like the right choice in replace_reg_with_saved_mem > because we use the chosen mode for saving and restoring registers, > which cannot be done in BLKmode. Similarly require () seems like > the right choice in calls related to secondary memory reloads (the ones > in config/, and in get_secondary_mem) because the reload must always > have a defined mode, which e.g. determines the size of the slot. > > We can use require () in simplify_subreg_concatn and assemble_integer > because it isn't meaningful to create a subreg with BLKmode (for one > thing, we couldn't tell then whether it was partial, paradoxical, etc.). > > make_fract_type and make_accum_type must find a mode because that's > what distinguishes accumulator FIXED_POINT_TYPEs from fractional > FIXED_POINT_TYPEs. Ok. Richard. > 2017-09-04 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > * machmode.h (opt_machine_mode): New type. > (opt_mode<T>): Allow construction from anything that can be > converted to a T. > (is_a, as_a, dyn_cast): Add overloads for opt_mode. > (mode_for_size): Return an opt_machine_mode. > * stor-layout.c (mode_for_size): Likewise. > (mode_for_size_tree): Update call accordingly. > (bitwise_mode_for_mode): Likewise. > (make_fract_type): Likewise. > (make_accum_type): Likewise. > * caller-save.c (replace_reg_with_saved_mem): Update call > accordingly. > * config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * expmed.c (extract_bit_field_1): Likewise. > * reload.c (get_secondary_mem): Likewise. > * varasm.c (assemble_integer): Likewise. > * lower-subreg.c (simplify_subreg_concatn): Likewise. Move > early-out. > > Index: gcc/machmode.h > =================================================================== > --- gcc/machmode.h 2017-09-04 12:18:47.820398622 +0100 > +++ gcc/machmode.h 2017-09-04 12:18:50.674859598 +0100 > @@ -20,6 +20,8 @@ Software Foundation; either version 3, o > #ifndef HAVE_MACHINE_MODES > #define HAVE_MACHINE_MODES > > +typedef opt_mode<machine_mode> opt_machine_mode; > + > extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES]; > extern const unsigned short mode_precision[NUM_MACHINE_MODES]; > extern const unsigned char mode_inner[NUM_MACHINE_MODES]; > @@ -237,6 +239,8 @@ #define POINTER_BOUNDS_MODE_P(MODE) > > ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {} > ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {} > + template<typename U> > + ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {} > ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {} > > machine_mode else_void () const; > @@ -325,6 +329,13 @@ is_a (machine_mode m) > return T::includes_p (m); > } > > +template<typename T, typename U> > +inline bool > +is_a (const opt_mode<U> &m) > +{ > + return T::includes_p (m.else_void ()); > +} > + > /* Assert that mode M has type T, and return it in that form. */ > > template<typename T> > @@ -335,6 +346,13 @@ as_a (machine_mode m) > return typename mode_traits<T>::from_int (m); > } > > +template<typename T, typename U> > +inline T > +as_a (const opt_mode<U> &m) > +{ > + return as_a <T> (m.else_void ()); > +} > + > /* Convert M to an opt_mode<T>. */ > > template<typename T> > @@ -346,6 +364,13 @@ dyn_cast (machine_mode m) > return opt_mode<T> (); > } > > +template<typename T, typename U> > +inline opt_mode<T> > +dyn_cast (const opt_mode<U> &m) > +{ > + return dyn_cast <T> (m.else_void ()); > +} > + > /* Return true if mode M has type T, storing it as a T in *RESULT > if so. */ > > @@ -627,11 +652,7 @@ GET_MODE_2XWIDER_MODE (const T &m) > extern const unsigned char mode_complex[NUM_MACHINE_MODES]; > #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE]) > > -/* Return the mode for data of a given size SIZE and mode class CLASS. > - If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. > - The value is BLKmode if no other mode is found. */ > - > -extern machine_mode mode_for_size (unsigned int, enum mode_class, int); > +extern opt_machine_mode mode_for_size (unsigned int, enum mode_class, int); > > /* Return the machine mode to use for a MODE_INT of SIZE bits, if one > exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE > Index: gcc/stor-layout.c > =================================================================== > --- gcc/stor-layout.c 2017-09-04 12:18:44.944553324 +0100 > +++ gcc/stor-layout.c 2017-09-04 12:18:50.675762071 +0100 > @@ -291,19 +291,19 @@ finalize_size_functions (void) > vec_free (size_functions); > } > > -/* Return the machine mode to use for a nonscalar of SIZE bits. The > - mode must be in class MCLASS, and have exactly that many value bits; > - it may have padding as well. If LIMIT is nonzero, modes of wider > - than MAX_FIXED_MODE_SIZE will not be used. */ > +/* Return a machine mode of class MCLASS with SIZE bits of precision, > + if one exists. The mode may have padding bits as well the SIZE > + value bits. If LIMIT is nonzero, disregard modes wider than > + MAX_FIXED_MODE_SIZE. */ > > -machine_mode > +opt_machine_mode > mode_for_size (unsigned int size, enum mode_class mclass, int limit) > { > machine_mode mode; > int i; > > if (limit && size > MAX_FIXED_MODE_SIZE) > - return BLKmode; > + return opt_machine_mode (); > > /* Get the first mode which has this size, in the specified class. */ > FOR_EACH_MODE_IN_CLASS (mode, mclass) > @@ -316,7 +316,7 @@ mode_for_size (unsigned int size, enum m > && int_n_enabled_p[i]) > return int_n_data[i].m; > > - return BLKmode; > + return opt_machine_mode (); > } > > /* Similar, except passed a tree node. */ > @@ -333,11 +333,11 @@ mode_for_size_tree (const_tree size, enu > ui = uhwi; > if (uhwi != ui) > return BLKmode; > - return mode_for_size (ui, mclass, limit); > + return mode_for_size (ui, mclass, limit).else_blk (); > } > > -/* Similar, but never return BLKmode; return the narrowest mode that > - contains at least the requested number of value bits. */ > +/* Return the narrowest mode of class MCLASS that contains at least > + SIZE bits. Abort if no such mode exists. */ > > machine_mode > smallest_mode_for_size (unsigned int size, enum mode_class mclass) > @@ -426,9 +426,8 @@ bitwise_mode_for_mode (machine_mode mode > if (COMPLEX_MODE_P (mode)) > { > machine_mode trial = mode; > - if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT) > - trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false); > - if (trial != BLKmode > + if ((GET_MODE_CLASS (trial) == MODE_COMPLEX_INT > + || mode_for_size (bitsize, MODE_COMPLEX_INT, false).exists (&trial)) > && have_regs_of_mode[GET_MODE_INNER (trial)]) > return trial; > } > @@ -438,16 +437,15 @@ bitwise_mode_for_mode (machine_mode mode > if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE) > { > machine_mode trial = mode; > - if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) > - trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0); > - if (trial != BLKmode > + if ((GET_MODE_CLASS (trial) == MODE_VECTOR_INT > + || mode_for_size (bitsize, MODE_VECTOR_INT, 0).exists (&trial)) > && have_regs_of_mode[trial] > && targetm.vector_mode_supported_p (trial)) > return trial; > } > > /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE. */ > - return mode_for_size (bitsize, MODE_INT, true); > + return mode_for_size (bitsize, MODE_INT, true).else_blk (); > } > > /* Find a type that can be used for efficient bitwise operations on MODE. > @@ -2543,13 +2541,9 @@ make_fract_type (int precision, int unsi > TYPE_SATURATING (type) = 1; > > /* Lay out the type: set its alignment, size, etc. */ > - if (unsignedp) > - { > - TYPE_UNSIGNED (type) = 1; > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UFRACT, 0)); > - } > - else > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_FRACT, 0)); > + TYPE_UNSIGNED (type) = unsignedp; > + enum mode_class mclass = unsignedp ? MODE_UFRACT : MODE_FRACT; > + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); > layout_type (type); > > return type; > @@ -2569,13 +2563,9 @@ make_accum_type (int precision, int unsi > TYPE_SATURATING (type) = 1; > > /* Lay out the type: set its alignment, size, etc. */ > - if (unsignedp) > - { > - TYPE_UNSIGNED (type) = 1; > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UACCUM, 0)); > - } > - else > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_ACCUM, 0)); > + TYPE_UNSIGNED (type) = unsignedp; > + enum mode_class mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM; > + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); > layout_type (type); > > return type; > Index: gcc/caller-save.c > =================================================================== > --- gcc/caller-save.c 2017-09-04 11:49:42.884500727 +0100 > +++ gcc/caller-save.c 2017-09-04 12:18:50.672152181 +0100 > @@ -1161,7 +1161,7 @@ replace_reg_with_saved_mem (rtx *loc, > gcc_assert (smode != VOIDmode); > if (hard_regno_nregs [regno][smode] > 1) > smode = mode_for_size (GET_MODE_SIZE (mode) / nregs, > - GET_MODE_CLASS (mode), 0); > + GET_MODE_CLASS (mode), 0).require (); > XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i); > } > } > Index: gcc/config/alpha/alpha.h > =================================================================== > --- gcc/config/alpha/alpha.h 2017-09-04 11:50:08.504926375 +0100 > +++ gcc/config/alpha/alpha.h 2017-09-04 12:18:50.672152181 +0100 > @@ -508,7 +508,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1,C > #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \ > : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ > - : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) > + : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require ()) > > /* Return the class of registers that cannot change mode from FROM to TO. */ > > Index: gcc/config/i386/i386.h > =================================================================== > --- gcc/config/i386/i386.h 2017-09-04 11:50:08.515731048 +0100 > +++ gcc/config/i386/i386.h 2017-09-04 12:18:50.672152181 +0100 > @@ -1548,7 +1548,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, > for integral modes that can be moved using 32 bit move. */ > #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \ > - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ > + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ > : MODE) > > /* Return a class of registers that cannot change FROM mode to TO mode. */ > Index: gcc/config/s390/s390.h > =================================================================== > --- gcc/config/s390/s390.h 2017-09-04 11:50:24.561571751 +0100 > +++ gcc/config/s390/s390.h 2017-09-04 12:18:50.673054653 +0100 > @@ -624,9 +624,9 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, > > /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit > because the movsi and movsf patterns don't handle r/f moves. */ > -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > - (GET_MODE_BITSIZE (MODE) < 32 \ > - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ > +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > + (GET_MODE_BITSIZE (MODE) < 32 \ > + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ > : (MODE)) > > > Index: gcc/config/sparc/sparc.h > =================================================================== > --- gcc/config/sparc/sparc.h 2017-09-04 11:50:24.563372530 +0100 > +++ gcc/config/sparc/sparc.h 2017-09-04 12:18:50.673054653 +0100 > @@ -1077,13 +1077,13 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, > /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 > because the movsi and movsf patterns don't handle r/f moves. > For v8 we copy the default definition. */ > -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > - (TARGET_ARCH64 \ > - ? (GET_MODE_BITSIZE (MODE) < 32 \ > - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ > - : MODE) \ > - : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ > - ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0) \ > +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > + (TARGET_ARCH64 \ > + ? (GET_MODE_BITSIZE (MODE) < 32 \ > + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ > + : MODE) \ > + : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ > + ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require () \ > : MODE)) > > /* Return the maximum number of consecutive registers > Index: gcc/expmed.c > =================================================================== > --- gcc/expmed.c 2017-09-04 11:50:08.544543511 +0100 > +++ gcc/expmed.c 2017-09-04 12:18:50.673054653 +0100 > @@ -1711,14 +1711,9 @@ extract_bit_field_1 (rtx str_rtx, unsign > > /* Get the mode of the field to use for atomic access or subreg > conversion. */ > - mode1 = mode; > - if (SCALAR_INT_MODE_P (tmode)) > - { > - machine_mode try_mode = mode_for_size (bitsize, > - GET_MODE_CLASS (tmode), 0); > - if (try_mode != BLKmode) > - mode1 = try_mode; > - } > + if (!SCALAR_INT_MODE_P (tmode) > + || !mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0).exists (&mode1)) > + mode1 = mode; > gcc_assert (mode1 != BLKmode); > > /* Extraction of a full MODE1 value can be done with a subreg as long > Index: gcc/reload.c > =================================================================== > --- gcc/reload.c 2017-09-04 11:49:42.941500722 +0100 > +++ gcc/reload.c 2017-09-04 12:18:50.675762071 +0100 > @@ -578,7 +578,8 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSE > mode = SECONDARY_MEMORY_NEEDED_MODE (mode); > #else > if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode)) > - mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0); > + mode = mode_for_size (BITS_PER_WORD, > + GET_MODE_CLASS (mode), 0).require (); > #endif > > /* If we already have made a MEM for this operand in MODE, return it. */ > Index: gcc/varasm.c > =================================================================== > --- gcc/varasm.c 2017-09-04 11:49:42.944500722 +0100 > +++ gcc/varasm.c 2017-09-04 12:18:50.676664544 +0100 > @@ -2780,8 +2780,8 @@ assemble_integer (rtx x, unsigned int si > else > mclass = MODE_INT; > > - omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0); > - imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0); > + omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0).require (); > + imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0).require (); > > for (i = 0; i < size; i += subsize) > { > Index: gcc/lower-subreg.c > =================================================================== > --- gcc/lower-subreg.c 2017-09-04 12:18:41.572976650 +0100 > +++ gcc/lower-subreg.c 2017-09-04 12:18:50.674859598 +0100 > @@ -616,20 +616,18 @@ simplify_subreg_concatn (machine_mode ou > part = XVECEXP (op, 0, byte / inner_size); > partmode = GET_MODE (part); > > + final_offset = byte % inner_size; > + if (final_offset + GET_MODE_SIZE (outermode) > inner_size) > + return NULL_RTX; > + > /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of > regular CONST_VECTORs. They have vector or integer modes, depending > on the capabilities of the target. Cope with them. */ > if (partmode == VOIDmode && VECTOR_MODE_P (innermode)) > partmode = GET_MODE_INNER (innermode); > else if (partmode == VOIDmode) > - { > - enum mode_class mclass = GET_MODE_CLASS (innermode); > - partmode = mode_for_size (inner_size * BITS_PER_UNIT, mclass, 0); > - } > - > - final_offset = byte % inner_size; > - if (final_offset + GET_MODE_SIZE (outermode) > inner_size) > - return NULL_RTX; > + partmode = mode_for_size (inner_size * BITS_PER_UNIT, > + GET_MODE_CLASS (innermode), 0).require (); > > return simplify_gen_subreg (outermode, part, partmode, final_offset); > }
Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-09-04 12:18:47.820398622 +0100 +++ gcc/machmode.h 2017-09-04 12:18:50.674859598 +0100 @@ -20,6 +20,8 @@ Software Foundation; either version 3, o #ifndef HAVE_MACHINE_MODES #define HAVE_MACHINE_MODES +typedef opt_mode<machine_mode> opt_machine_mode; + extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES]; extern const unsigned short mode_precision[NUM_MACHINE_MODES]; extern const unsigned char mode_inner[NUM_MACHINE_MODES]; @@ -237,6 +239,8 @@ #define POINTER_BOUNDS_MODE_P(MODE) ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {} ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {} + template<typename U> + ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {} ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {} machine_mode else_void () const; @@ -325,6 +329,13 @@ is_a (machine_mode m) return T::includes_p (m); } +template<typename T, typename U> +inline bool +is_a (const opt_mode<U> &m) +{ + return T::includes_p (m.else_void ()); +} + /* Assert that mode M has type T, and return it in that form. */ template<typename T> @@ -335,6 +346,13 @@ as_a (machine_mode m) return typename mode_traits<T>::from_int (m); } +template<typename T, typename U> +inline T +as_a (const opt_mode<U> &m) +{ + return as_a <T> (m.else_void ()); +} + /* Convert M to an opt_mode<T>. */ template<typename T> @@ -346,6 +364,13 @@ dyn_cast (machine_mode m) return opt_mode<T> (); } +template<typename T, typename U> +inline opt_mode<T> +dyn_cast (const opt_mode<U> &m) +{ + return dyn_cast <T> (m.else_void ()); +} + /* Return true if mode M has type T, storing it as a T in *RESULT if so. */ @@ -627,11 +652,7 @@ GET_MODE_2XWIDER_MODE (const T &m) extern const unsigned char mode_complex[NUM_MACHINE_MODES]; #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE]) -/* Return the mode for data of a given size SIZE and mode class CLASS. - If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. - The value is BLKmode if no other mode is found. */ - -extern machine_mode mode_for_size (unsigned int, enum mode_class, int); +extern opt_machine_mode mode_for_size (unsigned int, enum mode_class, int); /* Return the machine mode to use for a MODE_INT of SIZE bits, if one exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c 2017-09-04 12:18:44.944553324 +0100 +++ gcc/stor-layout.c 2017-09-04 12:18:50.675762071 +0100 @@ -291,19 +291,19 @@ finalize_size_functions (void) vec_free (size_functions); } -/* Return the machine mode to use for a nonscalar of SIZE bits. The - mode must be in class MCLASS, and have exactly that many value bits; - it may have padding as well. If LIMIT is nonzero, modes of wider - than MAX_FIXED_MODE_SIZE will not be used. */ +/* Return a machine mode of class MCLASS with SIZE bits of precision, + if one exists. The mode may have padding bits as well the SIZE + value bits. If LIMIT is nonzero, disregard modes wider than + MAX_FIXED_MODE_SIZE. */ -machine_mode +opt_machine_mode mode_for_size (unsigned int size, enum mode_class mclass, int limit) { machine_mode mode; int i; if (limit && size > MAX_FIXED_MODE_SIZE) - return BLKmode; + return opt_machine_mode (); /* Get the first mode which has this size, in the specified class. */ FOR_EACH_MODE_IN_CLASS (mode, mclass) @@ -316,7 +316,7 @@ mode_for_size (unsigned int size, enum m && int_n_enabled_p[i]) return int_n_data[i].m; - return BLKmode; + return opt_machine_mode (); } /* Similar, except passed a tree node. */ @@ -333,11 +333,11 @@ mode_for_size_tree (const_tree size, enu ui = uhwi; if (uhwi != ui) return BLKmode; - return mode_for_size (ui, mclass, limit); + return mode_for_size (ui, mclass, limit).else_blk (); } -/* Similar, but never return BLKmode; return the narrowest mode that - contains at least the requested number of value bits. */ +/* Return the narrowest mode of class MCLASS that contains at least + SIZE bits. Abort if no such mode exists. */ machine_mode smallest_mode_for_size (unsigned int size, enum mode_class mclass) @@ -426,9 +426,8 @@ bitwise_mode_for_mode (machine_mode mode if (COMPLEX_MODE_P (mode)) { machine_mode trial = mode; - if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT) - trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false); - if (trial != BLKmode + if ((GET_MODE_CLASS (trial) == MODE_COMPLEX_INT + || mode_for_size (bitsize, MODE_COMPLEX_INT, false).exists (&trial)) && have_regs_of_mode[GET_MODE_INNER (trial)]) return trial; } @@ -438,16 +437,15 @@ bitwise_mode_for_mode (machine_mode mode if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE) { machine_mode trial = mode; - if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) - trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0); - if (trial != BLKmode + if ((GET_MODE_CLASS (trial) == MODE_VECTOR_INT + || mode_for_size (bitsize, MODE_VECTOR_INT, 0).exists (&trial)) && have_regs_of_mode[trial] && targetm.vector_mode_supported_p (trial)) return trial; } /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE. */ - return mode_for_size (bitsize, MODE_INT, true); + return mode_for_size (bitsize, MODE_INT, true).else_blk (); } /* Find a type that can be used for efficient bitwise operations on MODE. @@ -2543,13 +2541,9 @@ make_fract_type (int precision, int unsi TYPE_SATURATING (type) = 1; /* Lay out the type: set its alignment, size, etc. */ - if (unsignedp) - { - TYPE_UNSIGNED (type) = 1; - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UFRACT, 0)); - } - else - SET_TYPE_MODE (type, mode_for_size (precision, MODE_FRACT, 0)); + TYPE_UNSIGNED (type) = unsignedp; + enum mode_class mclass = unsignedp ? MODE_UFRACT : MODE_FRACT; + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); layout_type (type); return type; @@ -2569,13 +2563,9 @@ make_accum_type (int precision, int unsi TYPE_SATURATING (type) = 1; /* Lay out the type: set its alignment, size, etc. */ - if (unsignedp) - { - TYPE_UNSIGNED (type) = 1; - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UACCUM, 0)); - } - else - SET_TYPE_MODE (type, mode_for_size (precision, MODE_ACCUM, 0)); + TYPE_UNSIGNED (type) = unsignedp; + enum mode_class mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM; + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); layout_type (type); return type; Index: gcc/caller-save.c =================================================================== --- gcc/caller-save.c 2017-09-04 11:49:42.884500727 +0100 +++ gcc/caller-save.c 2017-09-04 12:18:50.672152181 +0100 @@ -1161,7 +1161,7 @@ replace_reg_with_saved_mem (rtx *loc, gcc_assert (smode != VOIDmode); if (hard_regno_nregs [regno][smode] > 1) smode = mode_for_size (GET_MODE_SIZE (mode) / nregs, - GET_MODE_CLASS (mode), 0); + GET_MODE_CLASS (mode), 0).require (); XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i); } } Index: gcc/config/alpha/alpha.h =================================================================== --- gcc/config/alpha/alpha.h 2017-09-04 11:50:08.504926375 +0100 +++ gcc/config/alpha/alpha.h 2017-09-04 12:18:50.672152181 +0100 @@ -508,7 +508,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1,C #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \ : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ - : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) + : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require ()) /* Return the class of registers that cannot change mode from FROM to TO. */ Index: gcc/config/i386/i386.h =================================================================== --- gcc/config/i386/i386.h 2017-09-04 11:50:08.515731048 +0100 +++ gcc/config/i386/i386.h 2017-09-04 12:18:50.672152181 +0100 @@ -1548,7 +1548,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, for integral modes that can be moved using 32 bit move. */ #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \ - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ : MODE) /* Return a class of registers that cannot change FROM mode to TO mode. */ Index: gcc/config/s390/s390.h =================================================================== --- gcc/config/s390/s390.h 2017-09-04 11:50:24.561571751 +0100 +++ gcc/config/s390/s390.h 2017-09-04 12:18:50.673054653 +0100 @@ -624,9 +624,9 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit because the movsi and movsf patterns don't handle r/f moves. */ -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ - (GET_MODE_BITSIZE (MODE) < 32 \ - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ + (GET_MODE_BITSIZE (MODE) < 32 \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ : (MODE)) Index: gcc/config/sparc/sparc.h =================================================================== --- gcc/config/sparc/sparc.h 2017-09-04 11:50:24.563372530 +0100 +++ gcc/config/sparc/sparc.h 2017-09-04 12:18:50.673054653 +0100 @@ -1077,13 +1077,13 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 because the movsi and movsf patterns don't handle r/f moves. For v8 we copy the default definition. */ -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ - (TARGET_ARCH64 \ - ? (GET_MODE_BITSIZE (MODE) < 32 \ - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ - : MODE) \ - : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ - ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0) \ +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ + (TARGET_ARCH64 \ + ? (GET_MODE_BITSIZE (MODE) < 32 \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ + : MODE) \ + : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ + ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require () \ : MODE)) /* Return the maximum number of consecutive registers Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-09-04 11:50:08.544543511 +0100 +++ gcc/expmed.c 2017-09-04 12:18:50.673054653 +0100 @@ -1711,14 +1711,9 @@ extract_bit_field_1 (rtx str_rtx, unsign /* Get the mode of the field to use for atomic access or subreg conversion. */ - mode1 = mode; - if (SCALAR_INT_MODE_P (tmode)) - { - machine_mode try_mode = mode_for_size (bitsize, - GET_MODE_CLASS (tmode), 0); - if (try_mode != BLKmode) - mode1 = try_mode; - } + if (!SCALAR_INT_MODE_P (tmode) + || !mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0).exists (&mode1)) + mode1 = mode; gcc_assert (mode1 != BLKmode); /* Extraction of a full MODE1 value can be done with a subreg as long Index: gcc/reload.c =================================================================== --- gcc/reload.c 2017-09-04 11:49:42.941500722 +0100 +++ gcc/reload.c 2017-09-04 12:18:50.675762071 +0100 @@ -578,7 +578,8 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSE mode = SECONDARY_MEMORY_NEEDED_MODE (mode); #else if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode)) - mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0); + mode = mode_for_size (BITS_PER_WORD, + GET_MODE_CLASS (mode), 0).require (); #endif /* If we already have made a MEM for this operand in MODE, return it. */ Index: gcc/varasm.c =================================================================== --- gcc/varasm.c 2017-09-04 11:49:42.944500722 +0100 +++ gcc/varasm.c 2017-09-04 12:18:50.676664544 +0100 @@ -2780,8 +2780,8 @@ assemble_integer (rtx x, unsigned int si else mclass = MODE_INT; - omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0); - imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0); + omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0).require (); + imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0).require (); for (i = 0; i < size; i += subsize) { Index: gcc/lower-subreg.c =================================================================== --- gcc/lower-subreg.c 2017-09-04 12:18:41.572976650 +0100 +++ gcc/lower-subreg.c 2017-09-04 12:18:50.674859598 +0100 @@ -616,20 +616,18 @@ simplify_subreg_concatn (machine_mode ou part = XVECEXP (op, 0, byte / inner_size); partmode = GET_MODE (part); + final_offset = byte % inner_size; + if (final_offset + GET_MODE_SIZE (outermode) > inner_size) + return NULL_RTX; + /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of regular CONST_VECTORs. They have vector or integer modes, depending on the capabilities of the target. Cope with them. */ if (partmode == VOIDmode && VECTOR_MODE_P (innermode)) partmode = GET_MODE_INNER (innermode); else if (partmode == VOIDmode) - { - enum mode_class mclass = GET_MODE_CLASS (innermode); - partmode = mode_for_size (inner_size * BITS_PER_UNIT, mclass, 0); - } - - final_offset = byte % inner_size; - if (final_offset + GET_MODE_SIZE (outermode) > inner_size) - return NULL_RTX; + partmode = mode_for_size (inner_size * BITS_PER_UNIT, + GET_MODE_CLASS (innermode), 0).require (); return simplify_gen_subreg (outermode, part, partmode, final_offset); }