c++, v3: Emit fundamental tinfos for _Float16/decltype(0.0bf16) types on ia32 with -mno-sse2 [PR108883]

Message ID ZACGi5t6N65DipZA@tucnak
State New
Headers
Series c++, v3: Emit fundamental tinfos for _Float16/decltype(0.0bf16) types on ia32 with -mno-sse2 [PR108883] |

Commit Message

Jakub Jelinek March 2, 2023, 11:20 a.m. UTC
  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  <jakub@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.



	Jakub
  

Comments

Jason Merrill March 2, 2023, 4:32 p.m. UTC | #1
On 3/2/23 06:20, Jakub Jelinek wrote:
> 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  <jakub@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\

"each corresponding fundamental type tree"?

OK with that change.

> +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
>
  

Patch

--- 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;