c++, v3: Emit fundamental tinfos for _Float16/decltype(0.0bf16) types on ia32 with -mno-sse2 [PR108883]
_Float16 and decltype(0.0bf16) types are on x86 supported only with
-msse2. On x86_64 that is the default, but on ia32 it is not.
We should still emit fundamental type tinfo for those types in
libsupc++.a/libstdc++.*, regardless of whether libsupc++/libstdc++
is compiled with -msse2 or not, as user programs can be compiled
with different ISA flags from libsupc++/libstdc++ and if they
are compiled with -msse2 and use std::float16_t or std::bfloat16_t
and need RTTI for it, it should work out of the box. Furthermore,
libstdc++ ABI on ia32 shouldn't depend on whether the library
is compiled with -mno-sse or -msse2.
Unfortunately, just hacking up libsupc++ Makefile/configure so that
a single source is compiled with -msse2 isn't appropriate, because
that TU emits also code and the code should be able to run on CPUs
which libstdc++ supports. We could add [[gnu::attribute ("no-sse2")]]
there perhaps conditionally, but it all gets quite ugly.
The following patch instead adds a target hook which allows the backend
to temporarily tweak registered types such that emit_support_tinfos
emits whatever is needed.
Additionally, it makes emit_support_tinfos_1 call emit_tinfo_decl
immediately, so that temporarily created dummy types for emit_support_tinfo
purposes only can be nullified again afterwards. And removes the
previous fallback_* types used for dfloat*_type_node tinfos even when
decimal types aren't supported.
2023-03-03 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.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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_MAX];
|
||||
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"
|
||||
|
||||
|
||||
+5
-3
@@ -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;
|
||||
|
||||
+32
-15
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1525,6 +1525,15 @@ appropriate for a target that does not define any new fundamental
|
||||
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 each 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
|
||||
|
||||
|
||||
@@ -1286,6 +1286,8 @@ pattern needs to support both a 32- and a 64-bit mode.
|
||||
|
||||
@hook TARGET_MANGLE_TYPE
|
||||
|
||||
@hook TARGET_EMIT_SUPPORT_TINFOS
|
||||
|
||||
@node Type Layout
|
||||
@section Layout of Source Language Data Types
|
||||
|
||||
|
||||
@@ -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 each corresponding fundamental type trees, calling the\n\
|
||||
@var{callback} 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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 &)
|
||||
|
||||
@@ -98,6 +98,8 @@ extern int default_builtin_vectorization_cost (enum vect_cost_for_stmt, tree, in
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user