From: Alfie Richards <[email protected]>
This changes the hook from being symmetric, to explicitly taking a version
string from the old decl and one from the new decl.
Additionally, it documents that we support emitting a diagnostic if the strings
do imply the same version, but are incompatible.
This is a change required for adding priority version support in aarch64.
gcc/ChangeLog:
* target.def: (TARGET_OPTION_SAME_FUNCTION_VERSIONS) Update
documentation.
* tree.cc (disjoint_version_decls): Change to use the correct decl in
call to hook.
* doc/tm.texi: Regenerate.
---
gcc/doc/tm.texi | 6 ++++--
gcc/target.def | 10 ++++++----
gcc/tree.cc | 22 +++++++++++++++++-----
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 989e01fbd18..d044084f91f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10997,9 +10997,11 @@ changed via the optimize attribute or pragma, see
@code{TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE}
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_OPTION_SAME_FUNCTION_VERSIONS
(string_slice @var{fn1}, string_slice @var{fn2})
+@deftypefn {Target Hook} bool TARGET_OPTION_SAME_FUNCTION_VERSIONS
(string_slice @var{old_str}, string_slice @var{new_str})
This target hook returns @code{true} if the target/target-version strings
-@var{fn1} and @var{fn2} imply the same function version.
+@var{old_str} and @var{new_str} imply the same function version.
+Can also produce a diagnostic if the version strings do imply the same
+version, but are incompatible.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_OPTION_FUNCTIONS_B_RESOLVABLE_FROM_A
(tree @var{decl_a}, tree @var{decl_v}, tree @var{base})
diff --git a/gcc/target.def b/gcc/target.def
index 3e58dcf54a9..58be3eaa9f4 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -6925,13 +6925,15 @@ changed via the optimize attribute or pragma, see\n\
void, (void),
hook_void_void)
-/* This function returns true if FN1 and FN2 define the same version of a
- function. */
+/* This function returns true if OLD_STR and NEW_STR define the same version
+ of a function. */
DEFHOOK
(same_function_versions,
"This target hook returns @code{true} if the target/target-version strings\n\
-@var{fn1} and @var{fn2} imply the same function version.",
- bool, (string_slice fn1, string_slice fn2),
+@var{old_str} and @var{new_str} imply the same function version.\n\
+Can also produce a diagnostic if the version strings do imply the same\n\
+version, but are incompatible.",
+ bool, (string_slice old_str, string_slice new_str),
hook_stringslice_stringslice_unreachable)
/* Checks if we can be certain that function DECL_A could resolve DECL_B. */
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 966da8052a4..16d9e454d77 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -15557,8 +15557,12 @@ disjoint_version_decls (tree fn1, tree fn2)
{
/* As this is symmetric, can remove the case where fn2 is target clone
and fn1 is target version by swapping here. */
+ bool swapped = false;
if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (fn2)))
- std::swap (fn1, fn2);
+ {
+ swapped = true;
+ std::swap (fn1, fn2);
+ }
if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (fn1)))
{
@@ -15571,8 +15575,12 @@ disjoint_version_decls (tree fn1, tree fn2)
for (string_slice v1 : fn1_versions)
{
for (string_slice v2 : fn2_versions)
- if (targetm.target_option.same_function_versions (v1, v2))
- return false;
+ {
+ if (swapped)
+ std::swap (v1, v2);
+ if (targetm.target_option.same_function_versions (v1, v2))
+ return false;
+ }
}
return true;
}
@@ -15589,8 +15597,12 @@ disjoint_version_decls (tree fn1, tree fn2)
if (!v2.is_valid ())
v2 = "default";
for (string_slice v1 : fn1_versions)
- if (targetm.target_option.same_function_versions (v1, v2))
- return false;
+ {
+ if (swapped)
+ std::swap (v1, v2);
+ if (targetm.target_option.same_function_versions (v1, v2))
+ return false;
+ }
return true;
}
}
--
2.34.1