Hi! On Wed, Mar 01, 2023 at 05:50:47PM -0500, Jason Merrill wrote: > > And then there is a question whether we want to emit rtti for > > _Float{16,32,64,128}, _Float{32,64,128}x and decltype(0.0bf16) regardless > > of whether the target supports them at all or not. > > Emitting them always would have an advantage, if say bfloat16_t support > > isn't added for aarch64 for GCC 13 (it is still pending review), we wouldn't > > need to deal with symbol versioning for it in GCC 14 or later. > > On the other side, on some arches some types are very unlikely to be > > supported. And e.g. _Float128x isn't supported on any arch right now. > > A good point. Incidentally, it seems problematic for embedded users that > all the fundamental type_infos are emitted in the same .o, making it hard to > link in only the ones you care about. And new floating-point variants add > to that problem. So perhaps until that is addressed, it's better to avoid > adding a bunch more on targets that don't support them.
Ok, so here is a variant of the patch which still drops the fallback_* stuff, but for float*_type_node doesn't do the automatic fallback in generic code and leaves those to a target hook. So far lightly tested on x86_64-linux -m32/-m64: 2023-03-02 Jakub Jelinek <ja...@redhat.com> PR target/108883 gcc/ * target.h (emit_support_tinfos_callback): New typedef. * targhooks.h (default_emit_support_tinfos): Declare. * targhooks.cc (default_emit_support_tinfos): New function. * target.def (emit_support_tinfos): New target hook. * doc/tm.texi.in (emit_support_tinfos): Document it. * doc/tm.texi: Regenerated. * config/i386/i386.cc (ix86_emit_support_tinfos): New function. (TARGET_EMIT_SUPPORT_TINFOS): Redefine. gcc/cp/ * cp-tree.h (enum cp_tree_index): Remove CPTI_FALLBACK_DFLOAT*_TYPE enumerators. (fallback_dfloat32_type, fallback_dfloat64_type, fallback_dfloat128_type): Remove. * rtti.cc (emit_support_tinfo_1): If not emitted already, call emit_tinfo_decl and remove from unemitted_tinfo_decls right away. (emit_support_tinfos): Move &dfloat*_type_node from fundamentals array into new fundamentals_with_fallback array. Call emit_support_tinfo_1 on elements of that array too, with the difference that if the type is NULL, use a fallback REAL_TYPE for it temporarily. Drop the !targetm.decimal_float_supported_p () handling. Call targetm.emit_support_tinfos at the end. * mangle.cc (write_builtin_type): Remove references to fallback_dfloat*_type. Handle bfloat16_type_node mangling. --- gcc/target.h.jj 2023-02-17 12:45:08.056638510 +0100 +++ gcc/target.h 2023-03-02 12:06:59.248146213 +0100 @@ -260,6 +260,8 @@ enum poly_value_estimate_kind POLY_VALUE_LIKELY }; +typedef void (*emit_support_tinfos_callback) (tree); + extern bool verify_type_context (location_t, type_context_kind, const_tree, bool = false); --- gcc/targhooks.h.jj 2023-01-02 09:32:50.422880177 +0100 +++ gcc/targhooks.h 2023-03-02 12:06:22.559686384 +0100 @@ -98,6 +98,8 @@ extern int default_builtin_vectorization extern tree default_builtin_reciprocal (tree); +extern void default_emit_support_tinfos (emit_support_tinfos_callback); + extern HOST_WIDE_INT default_static_rtx_alignment (machine_mode); extern HOST_WIDE_INT default_constant_alignment (const_tree, HOST_WIDE_INT); extern HOST_WIDE_INT constant_alignment_word_strings (const_tree, --- gcc/targhooks.cc.jj 2023-01-02 09:32:52.591848839 +0100 +++ gcc/targhooks.cc 2023-03-02 12:01:39.576868114 +0100 @@ -752,6 +752,11 @@ default_builtin_reciprocal (tree) return NULL_TREE; } +void +default_emit_support_tinfos (emit_support_tinfos_callback) +{ +} + bool hook_bool_CUMULATIVE_ARGS_arg_info_false (cumulative_args_t, const function_arg_info &) --- gcc/target.def.jj 2023-02-22 15:58:50.252996452 +0100 +++ gcc/target.def 2023-03-02 12:01:52.002684436 +0100 @@ -2606,6 +2606,19 @@ types.", const char *, (const_tree type), hook_constcharptr_const_tree_null) +/* Temporarily add conditional target specific types for the purpose of + emitting C++ fundamental type tinfos. */ +DEFHOOK +(emit_support_tinfos, + "If your target defines any fundamental types which depend on ISA flags,\n\ +they might need C++ tinfo symbols in libsupc++/libstdc++ regardless of\n\ +ISA flags the library is compiled with.\n\ +This hook allows creating tinfo symbols even for those cases, by temporarily\n\ +creating corresponding fundamental type trees, calling the @var{callback}\n\ +function on it and setting the type back to @code{nullptr}.", + void, (emit_support_tinfos_callback callback), + default_emit_support_tinfos) + /* Make any adjustments to libfunc names needed for this target. */ DEFHOOK (init_libfuncs, --- gcc/doc/tm.texi.in.jj 2023-02-24 09:58:39.963508685 +0100 +++ gcc/doc/tm.texi.in 2023-03-02 11:47:50.044125831 +0100 @@ -1286,6 +1286,8 @@ pattern needs to support both a 32- and @hook TARGET_MANGLE_TYPE +@hook TARGET_EMIT_SUPPORT_TINFOS + @node Type Layout @section Layout of Source Language Data Types --- gcc/doc/tm.texi.jj 2023-02-24 09:58:39.951508859 +0100 +++ gcc/doc/tm.texi 2023-03-02 12:02:18.312295512 +0100 @@ -1525,6 +1525,15 @@ appropriate for a target that does not d types. @end deftypefn +@deftypefn {Target Hook} void TARGET_EMIT_SUPPORT_TINFOS (emit_support_tinfos_callback @var{callback}) +If your target defines any fundamental types which depend on ISA flags, +they might need C++ tinfo symbols in libsupc++/libstdc++ regardless of +ISA flags the library is compiled with. +This hook allows creating tinfo symbols even for those cases, by temporarily +creating corresponding fundamental type trees, calling the @var{callback} +function on it and setting the type back to @code{nullptr}. +@end deftypefn + @node Type Layout @section Layout of Source Language Data Types --- gcc/config/i386/i386.cc.jj 2023-02-22 15:58:50.109998489 +0100 +++ gcc/config/i386/i386.cc 2023-03-02 12:02:13.193371183 +0100 @@ -22775,6 +22775,27 @@ ix86_mangle_type (const_tree type) } } +/* Create C++ tinfo symbols for only conditionally available fundamental + types. */ + +static void +ix86_emit_support_tinfos (emit_support_tinfos_callback callback) +{ + extern tree ix86_float16_type_node; + extern tree ix86_bf16_type_node; + + if (!TARGET_SSE2) + { + gcc_checking_assert (!float16_type_node && !bfloat16_type_node); + float16_type_node = ix86_float16_type_node; + bfloat16_type_node = ix86_bf16_type_node; + callback (float16_type_node); + callback (bfloat16_type_node); + float16_type_node = NULL_TREE; + bfloat16_type_node = NULL_TREE; + } +} + static GTY(()) tree ix86_tls_stack_chk_guard_decl; static tree @@ -24954,6 +24975,9 @@ ix86_libgcc_floating_mode_supported_p #undef TARGET_MANGLE_TYPE #define TARGET_MANGLE_TYPE ix86_mangle_type +#undef TARGET_EMIT_SUPPORT_TINFOS +#define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos + #undef TARGET_STACK_PROTECT_GUARD #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard --- gcc/cp/cp-tree.h.jj 2023-03-02 08:49:09.569844225 +0100 +++ gcc/cp/cp-tree.h 2023-03-02 11:45:41.972008622 +0100 @@ -235,10 +235,6 @@ enum cp_tree_index CPTI_PSEUDO_CONTRACT_VIOLATION, - CPTI_FALLBACK_DFLOAT32_TYPE, - CPTI_FALLBACK_DFLOAT64_TYPE, - CPTI_FALLBACK_DFLOAT128_TYPE, - CPTI_MAX }; @@ -397,13 +393,6 @@ extern GTY(()) tree cp_global_trees[CPTI access nodes in tree.h. */ #define access_default_node null_node - -/* Variant of dfloat{32,64,128}_type_node only used for fundamental - rtti purposes if DFP is disabled. */ -#define fallback_dfloat32_type cp_global_trees[CPTI_FALLBACK_DFLOAT32_TYPE] -#define fallback_dfloat64_type cp_global_trees[CPTI_FALLBACK_DFLOAT64_TYPE] -#define fallback_dfloat128_type cp_global_trees[CPTI_FALLBACK_DFLOAT128_TYPE] - #include "name-lookup.h" --- gcc/cp/rtti.cc.jj 2023-02-28 11:28:56.579180090 +0100 +++ gcc/cp/rtti.cc 2023-03-02 11:49:41.380484925 +0100 @@ -1577,6 +1577,15 @@ emit_support_tinfo_1 (tree bltn) gcc_assert (TREE_PUBLIC (tinfo) && !DECL_COMDAT (tinfo)); DECL_INTERFACE_KNOWN (tinfo) = 1; } + + /* Emit it right away if not emitted already. */ + if (DECL_INITIAL (tinfo) == NULL_TREE) + { + gcc_assert (unemitted_tinfo_decls->last () == tinfo); + bool ok = emit_tinfo_decl (tinfo); + gcc_assert (ok); + unemitted_tinfo_decls->pop (); + } } } @@ -1602,12 +1611,18 @@ emit_support_tinfos (void) &long_integer_type_node, &long_unsigned_type_node, &long_long_integer_type_node, &long_long_unsigned_type_node, &float_type_node, &double_type_node, &long_double_type_node, - &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node, &bfloat16_type_node, &float16_type_node, &float32_type_node, &float64_type_node, &float128_type_node, &float32x_type_node, &float64x_type_node, &float128x_type_node, &nullptr_type_node, 0 }; + /* Similar, but for floating point types only which should get type info + regardless whether they are non-NULL or NULL. */ + static tree *const fundamentals_with_fallback[] = + { + &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node, + 0 + }; int ix; /* Look for a defined class. */ @@ -1627,8 +1642,20 @@ emit_support_tinfos (void) location_t saved_loc = input_location; input_location = BUILTINS_LOCATION; doing_runtime = 1; + tree fallback = NULL_TREE; for (ix = 0; fundamentals[ix]; ix++) emit_support_tinfo_1 (*fundamentals[ix]); + for (ix = 0; fundamentals_with_fallback[ix]; ix++) + if (*fundamentals_with_fallback[ix]) + emit_support_tinfo_1 (*fundamentals_with_fallback[ix]); + else + { + if (fallback == NULL_TREE) + fallback = make_node (REAL_TYPE); + *fundamentals_with_fallback[ix] = fallback; + emit_support_tinfo_1 (fallback); + *fundamentals_with_fallback[ix] = NULL_TREE; + } for (ix = 0; ix < NUM_INT_N_ENTS; ix ++) if (int_n_enabled_p[ix]) { @@ -1637,20 +1664,10 @@ emit_support_tinfos (void) } for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t)) emit_support_tinfo_1 (TREE_VALUE (t)); - /* For compatibility, emit DFP typeinfos even when DFP isn't enabled, - because we've emitted that in the past. */ - if (!targetm.decimal_float_supported_p ()) - { - gcc_assert (dfloat32_type_node == NULL_TREE - && dfloat64_type_node == NULL_TREE - && dfloat128_type_node == NULL_TREE); - fallback_dfloat32_type = make_node (REAL_TYPE); - fallback_dfloat64_type = make_node (REAL_TYPE); - fallback_dfloat128_type = make_node (REAL_TYPE); - emit_support_tinfo_1 (fallback_dfloat32_type); - emit_support_tinfo_1 (fallback_dfloat64_type); - emit_support_tinfo_1 (fallback_dfloat128_type); - } + + /* Emit additional typeinfos as requested by target. */ + targetm.emit_support_tinfos (emit_support_tinfo_1); + input_location = saved_loc; } --- gcc/cp/mangle.cc.jj 2023-02-28 11:28:56.532180773 +0100 +++ gcc/cp/mangle.cc 2023-03-02 11:45:41.973008607 +0100 @@ -2732,11 +2732,11 @@ write_builtin_type (tree type) write_char ('d'); else if (type == long_double_type_node) write_char ('e'); - else if (type == dfloat32_type_node || type == fallback_dfloat32_type) + else if (type == dfloat32_type_node) write_string ("Df"); - else if (type == dfloat64_type_node || type == fallback_dfloat64_type) + else if (type == dfloat64_type_node) write_string ("Dd"); - else if (type == dfloat128_type_node || type == fallback_dfloat128_type) + else if (type == dfloat128_type_node) write_string ("De"); else if (type == float16_type_node) write_string ("DF16_"); @@ -2752,6 +2752,8 @@ write_builtin_type (tree type) write_string ("DF64x"); else if (type == float128x_type_node) write_string ("DF128x"); + else if (type == bfloat16_type_node) + write_string ("DF16b"); else gcc_unreachable (); break; Jakub