Message ID | f9227ec78e18c99ef94405fe46a8373156869a5f.1717134752.git.linkw@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook | expand |
On Mon, Jun 3, 2024 at 5:02 AM Kewen Lin <linkw@linux.ibm.com> wrote: > > 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..d85b6dcbf1a 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 type @code{double}. type type OK with that fixed and no comments from others. Richard. > 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..07bf8ed9e0e 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 tree_index 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..f6e2372f262 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 tree_index 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 >
Hi Richi, on 2024/6/3 14:49, Richard Biener wrote: > On Mon, Jun 3, 2024 at 5:02 AM Kewen Lin <linkw@linux.ibm.com> wrote: >> >> 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..d85b6dcbf1a 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 type @code{double}. > > type type Oops, thanks for catching, will fix it. > > OK with that fixed and no comments from others. Thanks! BR, Kewen
On Sun, 2 Jun 2024, Kewen Lin wrote: > +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 tree_index 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. Identifiers such as tree_index and TI_LONG_DOUBLE_TYPE should be enclosed in @code{} in documentation (in this case it would be better to say "with argument @code{TI_LONG_DOUBLE_TYPE}" rather than mentioning the tree_index type of the argument). > @@ -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 tree_index 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. Likewise.
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..d85b6dcbf1a 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 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..07bf8ed9e0e 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 tree_index 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..f6e2372f262 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 tree_index 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++)