On 9/17/25 6:44 AM, [email protected] wrote:
From: Alfie Richards <[email protected]>
This change refactors FMV handling in the frontend to allows greater
reasoning about versions in shared code.
This is needed for allowing target_clones and target_versions to be used
together in a function set, as there is then two distinct concerns when
encountering two declarations that previously were conflated:
1. Are these two declarations completely disjoint FMV declarations
(ie. the sets of versions they define have no overlap). If so, they don't
conflict so there is no need to merge and both can be pushed.
2. For two declarations that aren't completely disjoint, are they matching
and therefore mergeable. (ie. two target_clone decls that define the same set
of versions, or an un-annotated declaration, and a target_clones definition
containing the default version). If so, continue to the existing merging logic
to try to merge these and diagnose if it's not possible.
If not, then diagnose the conflicting declarations.
To do this the common_function_versions function has been renamed
disjoint_function_versions (meaning, are the version sets defined by these
two decl's completely distinct from each other).
A new hook called same_function_version is introduces taking two
string_slice's (each representing a single version) and determining if they
define the same version.
A new function, called diagnose_versioned_decls is added, which checks
if two decls (with overlapping version sets) can be merged and diagnose when
they cannot be (only in terms of the attributes, the existing logic is used to
detect other mergeability conflicts like redefinition).
This only effects targets with TARGET_HAS_FMV_TARGET_ATTRIBUTE set to false.
(ie. aarch64 and riscv), the existing logic for i86 and ppc is unchanged.
This also means the same function version hook is only used for aarch64 and
riscv.
gcc/ChangeLog:
* attribs.h (common_function_versions): Removed.
* attribs.cc (common_function_versions): Removed.
* config/aarch64/aarch64.cc (aarch64_common_function_versions): Removed.
(aarch64_same_function_versions): New function to check if two version
strings imply the same version.
(TARGET_OPTION_FUNCTION_VERSIONS): Removed.
(TARGET_OPTION_SAME_FUNCTION_VERSIONS): New macro.
* config/i386/i386.cc (TARGET_OPTION_FUNCTION_VERSIONS): Removed.
* config/rs6000/rs6000.cc (TARGET_OPTION_FUNCTION_VERSIONS): Removed.
* config/riscv/riscv.cc (riscv_same_function_versions): New function
to check if two version strings imply the same version.
(riscv_common_function_versions): Removed.
(TARGET_OPTION_FUNCTION_VERSIONS): Removed.
(TARGET_OPTION_SAME_FUNCTION_VERSIONS): New macro.
* doc/tm.texi: Regenerated.
* target.def: Remove common_version hook and add same_function_version
hook.
* doc/tm.texi.in: Ditto.
* tree.cc (distinct_version_decls): New function.
(mergeable_version_decls): Ditto.
* tree.h (distinct_version_decls): New function.
(mergeable_version_decls): Ditto.
* hooks.h (hook_stringslice_stringslice_unreachable): New function.
* hooks.cc (hook_stringslice_stringslice_unreachable): New function.
gcc/cp/ChangeLog:
* class.cc (resolve_address_of_overloaded_function): Updated to use
dijoint_versions_decls instead of common_function_version hook.
* decl.cc (decls_match): Refacture to use disjoint_version_decls and
to pass through conflicting_version argument.
(maybe_version_functions): Updated to use
disjoint_version_decls instead of common_function_version hook.
(duplicate_decls): Add logic to handle conflicting unmergable decls
and improve diagnostics for conflicting versions.
* decl2.cc (check_classfn): Updated to use
disjoint_version_decls instead of common_function_version hook.
---
OK with the two nits below addressed.
Jeff
diff --git a/gcc/hooks.cc b/gcc/hooks.cc
index 865820d80b1..820c81e31e4 100644
--- a/gcc/hooks.cc
+++ b/gcc/hooks.cc
@@ -27,6 +27,7 @@
#include "coretypes.h"
#include "tm.h"
#include "hooks.h"
+#include "vec.h"
Looks like an extraneous change. If there's a non-obvious need (say for
the string_slice class), then it's fine. If it's truly an extraneous
change, then drop it.
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 2e114d01110..cad57fedc7a 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -15490,6 +15490,249 @@ get_target_version (const tree decl)
.strip ();
}
+/* Returns true if FN1 and FN2 define dijoint function versions in an FMV
s/dijoint/disjoint/