Hi all,

I just pushed this 09/52 v2 with its following target changes
as r15-1594, thanks a lot for your comments/reviews/approvals!

BR,
Kewen

> Subject: [PATCH 09/52] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
>  mode_for_floating_type
> 
> Currently how we determine which mode will be used for a
> floating point type is that for a given type precision
> (size) call mode_for_size to get the first mode which has
> this size in the specified class.  On Powerpc, we have
> three modes (TF/KF/IF) having the same mode precision 128
> (see[1]), so the processing forces us to have to place TF
> at the first place, it would require us to make more
> adjustment in some generic code to avoid some unexpected
> mode conversions and it would be even worse if we get rid
> of TF eventually one day.  And as Joseph pointed out in [2],
> "floating types should have their mode, not a poorly
> defined precision value", as Joseph and Richi suggested,
> this patch is to introduce one hook mode_for_floating_type
> which returns the corresponding mode for type float, double
> or long double.  The default implementation returns SFmode
> for float and DFmode for double or long double.  For ports
> which need special treatment, there are some other patches
> for their own port specific implementation (referring to
> how {,LONG_}DOUBLE_TYPE_SIZE get used there).  For all
> generic uses of {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE, depending
> on the context, some of them are replaced with TYPE_PRECISION
> of the according type node, some other are replaced with
> GET_MODE_PRECISION on the mode from mode_for_floating_type.
> This patch also poisons {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE,
> so most defines of {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE in port
> specific are removed, but there are still some which are
> good to be kept for readability then they get renamed with
> port specific prefix.
> 
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651017.html
> [2] https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651209.html
> 
> gcc/ChangeLog:
> 
>       * coretypes.h (enum tree_index): Forward declaration.
>       * defaults.h (FLOAT_TYPE_SIZE): Remove.
>       (DOUBLE_TYPE_SIZE): Likewise.
>       (LONG_DOUBLE_TYPE_SIZE): Likewise.
>       * doc/rtl.texi: Update document by replacing {FLOAT,DOUBLE}_TYPE_SIZE
>       with C type {float,double}.
>       * doc/tm.texi.in: Document new hook mode_for_floating_type, remove
>       document entries for {FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE and
>       update document for WIDEST_HARDWARE_FP_SIZE.
>       * doc/tm.texi: Regenerate.
>       * emit-rtl.cc (init_emit_once): Replace DOUBLE_TYPE_SIZE by
>       calling targetm.c.mode_for_floating_type with TI_DOUBLE_TYPE.
>       * real.h (REAL_VALUE_TO_TARGET_LONG_DOUBLE): Use TYPE_PRECISION of
>       long_double_type_node to replace LONG_DOUBLE_TYPE_SIZE.
>       * system.h (FLOAT_TYPE_SIZE): Poison.
>       (DOUBLE_TYPE_SIZE): Likewise.
>       (LONG_DOUBLE_TYPE_SIZE): Likewise.
>       * target.def (mode_for_floating_type): New hook.
>       * targhooks.cc (default_mode_for_floating_type): New function.
>       (default_scalar_mode_supported_p): Update macros
>       {FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE by calling
>       targetm.c.mode_for_floating_type with
>       TI_{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE.
>       * targhooks.h (default_mode_for_floating_type): New declaration.
>       * tree-core.h (enum tree_index): Specify underlying type unsigned
>       to sync with forward declaration in coretypes.h.
>       (NUM_FLOATN_TYPES): Explicitly convert to int.
>       (NUM_FLOATNX_TYPES): Likewise.
>       (NUM_FLOATN_NX_TYPES): Likewise.
>       * tree.cc (build_common_tree_nodes): Update macros
>       {FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE by calling
>       targetm.c.mode_for_floating_type with
>       TI_{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE and set type mode accordingly.
> ---
>  gcc/coretypes.h    |  1 +
>  gcc/defaults.h     | 12 ------------
>  gcc/doc/rtl.texi   |  2 +-
>  gcc/doc/tm.texi    | 33 +++++++++++++--------------------
>  gcc/doc/tm.texi.in | 27 +++++++--------------------
>  gcc/emit-rtl.cc    |  3 ++-
>  gcc/real.h         |  7 ++++---
>  gcc/system.h       |  3 ++-
>  gcc/target.def     |  9 +++++++++
>  gcc/targhooks.cc   | 18 +++++++++++++++---
>  gcc/targhooks.h    |  1 +
>  gcc/tree-core.h    | 13 +++++++------
>  gcc/tree.cc        | 18 +++++++++++++++---
>  13 files changed, 77 insertions(+), 70 deletions(-)
> 
> diff --git a/gcc/coretypes.h b/gcc/coretypes.h
> index 1ac6f0abea3..00c1c58bd8c 100644
> --- a/gcc/coretypes.h
> +++ b/gcc/coretypes.h
> @@ -100,6 +100,7 @@ struct gimple;
>  typedef gimple *gimple_seq;
>  struct gimple_stmt_iterator;
>  class code_helper;
> +enum tree_index : unsigned;
> 
>  /* Forward declare rtx_code, so that we can use it in target hooks without
>     needing to pull in rtl.h.  */
> diff --git a/gcc/defaults.h b/gcc/defaults.h
> index 92f3e07f742..ac2d25852ab 100644
> --- a/gcc/defaults.h
> +++ b/gcc/defaults.h
> @@ -513,18 +513,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. 
>  If not, see
>  #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
>  #endif
> 
> -#ifndef FLOAT_TYPE_SIZE
> -#define FLOAT_TYPE_SIZE BITS_PER_WORD
> -#endif
> -
> -#ifndef DOUBLE_TYPE_SIZE
> -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
> -#endif
> -
> -#ifndef LONG_DOUBLE_TYPE_SIZE
> -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
> -#endif
> -
>  #ifndef DECIMAL32_TYPE_SIZE
>  #define DECIMAL32_TYPE_SIZE 32
>  #endif
> diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
> index aa10b5235b5..61981ae5a41 100644
> --- a/gcc/doc/rtl.texi
> +++ b/gcc/doc/rtl.texi
> @@ -1326,7 +1326,7 @@ whose size is @code{BITS_PER_WORD}, @code{SImode} on 
> 32-bit machines.
> 
>  The only modes which a machine description @i{must} support are
>  @code{QImode}, and the modes corresponding to @code{BITS_PER_WORD},
> -@code{FLOAT_TYPE_SIZE} and @code{DOUBLE_TYPE_SIZE}.
> +C type @code{float} and C type @code{double}.
>  The compiler will attempt to use @code{DImode} for 8-byte structures and
>  unions, but this can be prevented by overriding the definition of
>  @code{MAX_FIXED_MODE_SIZE}.  Alternatively, you can have the compiler
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index cd50078227d..305c4f3aed2 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -1044,6 +1044,14 @@ are zero or sign extended depending on if it is
>  @code{GET_MODE_ALIGNMENT (info->limb_mode)}.
>  @end deftypefn
> 
> +@deftypefn {Target Hook} machine_mode TARGET_C_MODE_FOR_FLOATING_TYPE (enum 
> tree_index @var{ti})
> +Return machine mode for a C floating point type which is indicated by
> + a given @code{enum tree_index} @var{ti}, @var{ti} should be
> + @code{TI_FLOAT_TYPE}, @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.
> + The default implementation returns @code{SFmode} for @code{TI_FLOAT_TYPE},
> + and @code{DFmode} for @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.
> +@end deftypefn
> +
>  @deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE 
> (const_tree @var{type}, machine_mode @var{mode}, int *@var{punsignedp}, 
> const_tree @var{funtype}, int @var{for_return})
>  Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or
>  function return values.  The target hook should return the new mode
> @@ -1610,23 +1618,6 @@ C99 type @code{_Bool} on the target machine.  If you 
> don't define
>  this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
>  @end defmac
> 
> -@defmac FLOAT_TYPE_SIZE
> -A C expression for the size in bits of the type @code{float} on the
> -target machine.  If you don't define this, the default is one word.
> -@end defmac
> -
> -@defmac DOUBLE_TYPE_SIZE
> -A C expression for the size in bits of the type @code{double} on the
> -target machine.  If you don't define this, the default is two
> -words.
> -@end defmac
> -
> -@defmac LONG_DOUBLE_TYPE_SIZE
> -A C expression for the size in bits of the type @code{long double} on
> -the target machine.  If you don't define this, the default is two
> -words.
> -@end defmac
> -
>  @defmac SHORT_FRACT_TYPE_SIZE
>  A C expression for the size in bits of the type @code{short _Fract} on
>  the target machine.  If you don't define this, the default is
> @@ -1687,9 +1678,11 @@ the libgcc @file{config.host}.
>  @defmac WIDEST_HARDWARE_FP_SIZE
>  A C expression for the size in bits of the widest floating-point format
>  supported by the hardware.  If you define this macro, you must specify a
> -value less than or equal to the value of @code{LONG_DOUBLE_TYPE_SIZE}.
> -If you do not define this macro, the value of @code{LONG_DOUBLE_TYPE_SIZE}
> -is the default.
> +value less than or equal to mode precision of the mode used for C type
> +@code{long double} (from hook @code{targetm.c.mode_for_floating_type}
> +with argument @code{TI_LONG_DOUBLE_TYPE}).  If you do not define this
> +macro, mode precision of the mode used for C type @code{long double} is
> +the default.
>  @end defmac
> 
>  @defmac DEFAULT_SIGNED_CHAR
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 058bd56487a..8de7e393a70 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -947,6 +947,8 @@ applied.
> 
>  @hook TARGET_C_BITINT_TYPE_INFO
> 
> +@hook TARGET_C_MODE_FOR_FLOATING_TYPE
> +
>  @hook TARGET_PROMOTE_FUNCTION_MODE
> 
>  @defmac PARM_BOUNDARY
> @@ -1351,23 +1353,6 @@ C99 type @code{_Bool} on the target machine.  If you 
> don't define
>  this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
>  @end defmac
> 
> -@defmac FLOAT_TYPE_SIZE
> -A C expression for the size in bits of the type @code{float} on the
> -target machine.  If you don't define this, the default is one word.
> -@end defmac
> -
> -@defmac DOUBLE_TYPE_SIZE
> -A C expression for the size in bits of the type @code{double} on the
> -target machine.  If you don't define this, the default is two
> -words.
> -@end defmac
> -
> -@defmac LONG_DOUBLE_TYPE_SIZE
> -A C expression for the size in bits of the type @code{long double} on
> -the target machine.  If you don't define this, the default is two
> -words.
> -@end defmac
> -
>  @defmac SHORT_FRACT_TYPE_SIZE
>  A C expression for the size in bits of the type @code{short _Fract} on
>  the target machine.  If you don't define this, the default is
> @@ -1428,9 +1413,11 @@ the libgcc @file{config.host}.
>  @defmac WIDEST_HARDWARE_FP_SIZE
>  A C expression for the size in bits of the widest floating-point format
>  supported by the hardware.  If you define this macro, you must specify a
> -value less than or equal to the value of @code{LONG_DOUBLE_TYPE_SIZE}.
> -If you do not define this macro, the value of @code{LONG_DOUBLE_TYPE_SIZE}
> -is the default.
> +value less than or equal to mode precision of the mode used for C type
> +@code{long double} (from hook @code{targetm.c.mode_for_floating_type}
> +with argument @code{TI_LONG_DOUBLE_TYPE}).  If you do not define this
> +macro, mode precision of the mode used for C type @code{long double} is
> +the default.
>  @end defmac
> 
>  @defmac DEFAULT_SIGNED_CHAR
> diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
> index 1856fa4884f..cb04aa1a8c6 100644
> --- a/gcc/emit-rtl.cc
> +++ b/gcc/emit-rtl.cc
> @@ -6366,7 +6366,8 @@ init_emit_once (void)
>    else
>      const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
> 
> -  double_mode = float_mode_for_size (DOUBLE_TYPE_SIZE).require ();
> +  mode = targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE);
> +  double_mode = as_a<scalar_float_mode> (mode);
> 
>    real_from_integer (&dconst0, double_mode, 0, SIGNED);
>    real_from_integer (&dconst1, double_mode, 1, SIGNED);
> diff --git a/gcc/real.h b/gcc/real.h
> index 2e40817a2d7..f28022769b3 100644
> --- a/gcc/real.h
> +++ b/gcc/real.h
> @@ -406,9 +406,10 @@ extern const struct real_format arm_bfloat_half_format;
>  #define REAL_VALUE_MINUS_ZERO(x)     real_isnegzero (&(x))
> 
>  /* IN is a REAL_VALUE_TYPE.  OUT is an array of longs.  */
> -#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT)                    \
> -  real_to_target (OUT, &(IN),                                                
> \
> -               float_mode_for_size (LONG_DOUBLE_TYPE_SIZE).require ())
> +#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT)                       \
> +  real_to_target (OUT, &(IN),                                                
>    \
> +               float_mode_for_size (TYPE_PRECISION                      \
> +                                    (long_double_type_node)).require ())
> 
>  #define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
>    real_to_target (OUT, &(IN), float_mode_for_size (64).require ())
> diff --git a/gcc/system.h b/gcc/system.h
> index 1028dcb1eb3..cbb14fb167d 100644
> --- a/gcc/system.h
> +++ b/gcc/system.h
> @@ -1000,7 +1000,8 @@ extern void fancy_abort (const char *, int, const char 
> *)
>       HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE                   \
>       SECONDARY_MEMORY_NEEDED CANNOT_CHANGE_MODE_CLASS                \
>       TRULY_NOOP_TRUNCATION FUNCTION_ARG_OFFSET CONSTANT_ALIGNMENT    \
> -     STARTING_FRAME_OFFSET
> +     STARTING_FRAME_OFFSET FLOAT_TYPE_SIZE DOUBLE_TYPE_SIZE          \
> +     LONG_DOUBLE_TYPE_SIZE
> 
>  /* Target macros only used for code built for the target, that have
>     moved to libgcc-tm.h or have never been present elsewhere.  */
> diff --git a/gcc/target.def b/gcc/target.def
> index c27df8095be..4780ba9c15b 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -6370,6 +6370,15 @@ are zero or sign extended depending on if it is\n\
>   bool, (int n, struct bitint_info *info),
>   default_bitint_type_info)
> 
> +DEFHOOK
> +(mode_for_floating_type,
> +"Return machine mode for a C floating point type which is indicated by\n\
> + a given @code{enum tree_index} @var{ti}, @var{ti} should be\n\
> + @code{TI_FLOAT_TYPE}, @code{TI_DOUBLE_TYPE} or 
> @code{TI_LONG_DOUBLE_TYPE}.\n\
> + The default implementation returns @code{SFmode} for 
> @code{TI_FLOAT_TYPE},\n\
> + and @code{DFmode} for @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.",
> + machine_mode, (enum tree_index ti), default_mode_for_floating_type)
> +
>  HOOK_VECTOR_END (c)
> 
>  /* Functions specific to the C++ frontend.  */
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index fb339bf75dd..5111e069f0c 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -298,6 +298,18 @@ default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED)
>    return VOIDmode;
>  }
> 
> +/* Return machine mode for a floating type which is indicated
> +   by the given enum tree_index.  */
> +
> +machine_mode
> +default_mode_for_floating_type (enum tree_index ti)
> +{
> +  if (ti == TI_FLOAT_TYPE)
> +    return SFmode;
> +  gcc_assert (ti == TI_DOUBLE_TYPE || ti == TI_LONG_DOUBLE_TYPE);
> +  return DFmode;
> +}
> +
>  /* The generic C++ ABI specifies this is a 64-bit value.  */
>  tree
>  default_cxx_guard_type (void)
> @@ -449,11 +461,11 @@ default_scalar_mode_supported_p (scalar_mode mode)
>        return false;
> 
>      case MODE_FLOAT:
> -      if (precision == FLOAT_TYPE_SIZE)
> +      if (mode == targetm.c.mode_for_floating_type (TI_FLOAT_TYPE))
>       return true;
> -      if (precision == DOUBLE_TYPE_SIZE)
> +      if (mode == targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE))
>       return true;
> -      if (precision == LONG_DOUBLE_TYPE_SIZE)
> +      if (mode == targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE))
>       return true;
>        return false;
> 
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index 85f3817c176..fdc17c3b7c0 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -289,6 +289,7 @@ extern unsigned int default_min_arithmetic_precision 
> (void);
>  extern enum flt_eval_method
>  default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED);
>  extern bool default_bitint_type_info (int, struct bitint_info *);
> +extern machine_mode default_mode_for_floating_type (enum tree_index);
>  extern HOST_WIDE_INT default_stack_clash_protection_alloca_probe_range 
> (void);
>  extern void default_select_early_remat_modes (sbitmap);
>  extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *);
> diff --git a/gcc/tree-core.h b/gcc/tree-core.h
> index 9fa74342919..0b5000acb80 100644
> --- a/gcc/tree-core.h
> +++ b/gcc/tree-core.h
> @@ -624,7 +624,7 @@ enum cv_qualifier {
>  };
> 
>  /* Standard named or nameless data types of the C compiler.  */
> -enum tree_index {
> +enum tree_index : unsigned {
>    TI_ERROR_MARK,
>    TI_INTQI_TYPE,
>    TI_INTHI_TYPE,
> @@ -691,17 +691,18 @@ enum tree_index {
>    TI_FLOAT64_TYPE,
>    TI_FLOAT128_TYPE,
>    TI_FLOATN_TYPE_LAST = TI_FLOAT128_TYPE,
> -#define NUM_FLOATN_TYPES (TI_FLOATN_TYPE_LAST - TI_FLOATN_TYPE_FIRST + 1)
> +#define NUM_FLOATN_TYPES ((int) (TI_FLOATN_TYPE_LAST         \
> +                              - TI_FLOATN_TYPE_FIRST + 1))
>    TI_FLOAT32X_TYPE,
>    TI_FLOATNX_TYPE_FIRST = TI_FLOAT32X_TYPE,
>    TI_FLOAT64X_TYPE,
>    TI_FLOAT128X_TYPE,
>    TI_FLOATNX_TYPE_LAST = TI_FLOAT128X_TYPE,
>    TI_FLOATN_NX_TYPE_LAST = TI_FLOAT128X_TYPE,
> -#define NUM_FLOATNX_TYPES (TI_FLOATNX_TYPE_LAST - TI_FLOATNX_TYPE_FIRST + 1)
> -#define NUM_FLOATN_NX_TYPES (TI_FLOATN_NX_TYPE_LAST          \
> -                          - TI_FLOATN_NX_TYPE_FIRST          \
> -                          + 1)
> +#define NUM_FLOATNX_TYPES ((int) (TI_FLOATNX_TYPE_LAST               \
> +                               - TI_FLOATNX_TYPE_FIRST + 1))
> +#define NUM_FLOATN_NX_TYPES ((int) (TI_FLOATN_NX_TYPE_LAST   \
> +                               - TI_FLOATN_NX_TYPE_FIRST + 1))
> 
>    /* Type used by certain backends for __float128, which in C++ should be
>       distinct type from _Float128 for backwards compatibility reasons.  */
> diff --git a/gcc/tree.cc b/gcc/tree.cc
> index 6564b002dc1..bc5175f591e 100644
> --- a/gcc/tree.cc
> +++ b/gcc/tree.cc
> @@ -9596,15 +9596,27 @@ build_common_tree_nodes (bool signed_char)
>    pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
> 
>    float_type_node = make_node (REAL_TYPE);
> -  TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
> +  machine_mode float_type_mode
> +    = targetm.c.mode_for_floating_type (TI_FLOAT_TYPE);
> +  SET_TYPE_MODE (float_type_node, float_type_mode);
> +  TYPE_PRECISION (float_type_node)
> +    = GET_MODE_PRECISION (float_type_mode).to_constant ();
>    layout_type (float_type_node);
> 
>    double_type_node = make_node (REAL_TYPE);
> -  TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
> +  machine_mode double_type_mode
> +    = targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE);
> +  SET_TYPE_MODE (double_type_node, double_type_mode);
> +  TYPE_PRECISION (double_type_node)
> +    = GET_MODE_PRECISION (double_type_mode).to_constant ();
>    layout_type (double_type_node);
> 
>    long_double_type_node = make_node (REAL_TYPE);
> -  TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
> +  machine_mode long_double_type_mode
> +    = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE);
> +  SET_TYPE_MODE (long_double_type_node, long_double_type_mode);
> +  TYPE_PRECISION (long_double_type_node)
> +    = GET_MODE_PRECISION (long_double_type_mode).to_constant ();
>    layout_type (long_double_type_node);
> 
>    for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
> --
> 2.43.0
> 

Reply via email to