[3/3] WIP/RFC: Fix name mangling for target_clones

Message ID 36b6307f-10f5-c03e-0263-0671d3219eb9@e124511.cambridge.arm.com
State Accepted
Headers
Series target_version and aarch64 function multiversioning |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Andrew Carlotti Oct. 18, 2023, 3:44 p.m. UTC
  This is a partial patch to make the mangling of function version names
for target_clones match those generated using the target or
target_version attributes.  It modifies the name of function versions,
but does not yet rename the resolved symbol, resulting in a duplicate
symbol name (and an error at assembly time).


Is this sort of approach ok?  Should I create an extra target hook to be called
here, so that the target_clones mangling can be target-specific but not
necessarily the same as for target attribute versioning?
  

Patch

diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 8af6b23d8c0306920e0fdcb3559ef047a16689f4..15672c02c6f9d6043a36bf081067f08d1ab834e5 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -1033,11 +1033,6 @@  cgraph_node::create_version_clone_with_body
   else
     new_decl = copy_node (old_decl);
 
-  /* Generate a new name for the new version. */
-  tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
-		: clone_function_name (old_decl, suffix));
-  DECL_NAME (new_decl) = fnname;
-  SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
   SET_DECL_RTL (new_decl, NULL);
 
   DECL_VIRTUAL_P (new_decl) = 0;
@@ -1065,6 +1060,24 @@  cgraph_node::create_version_clone_with_body
 	return NULL;
     }
 
+  /* Generate a new name for the new version. */
+  if (version_decl)
+    {
+      tree fnname = (clone_function_name_numbered (old_decl, suffix));
+      DECL_NAME (new_decl) = fnname;
+      SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
+    }
+  else
+    {
+      /* Add target version mangling.  We assume that the target hook will
+	 produce the same mangled name as it would have produced if the decl
+	 had already been versioned when the hook was previously called.  */
+      tree fnname = DECL_ASSEMBLER_NAME (old_decl);
+      DECL_NAME (new_decl) = fnname;
+      fnname = targetm.mangle_decl_assembler_name (new_decl, fnname);
+      SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
+    }
+
   /* When the old decl was a con-/destructor make sure the clone isn't.  */
   DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
   DECL_STATIC_DESTRUCTOR (new_decl) = 0;
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 3db57c2b13d612a37240d9dcf58ad21b2286633c..d9aec9a5ab532701b4a1877b440f3a553ffa28e2 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -162,7 +162,12 @@  create_dispatcher_calls (struct cgraph_node *node)
 	}
     }
 
-  tree fname = clone_function_name (node->decl, "default");
+  /* Add version mangling to default decl name.  We assume that the target
+     hook will produce the same mangled name as it would have produced if the
+     decl had already been versioned when the hook was previously called.  */
+  tree fname = DECL_ASSEMBLER_NAME (node->decl);
+  DECL_NAME (node->decl) = fname;
+  fname = targetm.mangle_decl_assembler_name (node->decl, fname);
   symtab->change_decl_assembler_name (node->decl, fname);
 
   if (node->definition)