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]

Re: [4/9] Make mode_for_size return an opt_mode


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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]