This adds the assembler_name member to cgraph_function_version_info
to store the base assembler name for the function to be mangled. This is
used in later patches for refactoring FMV mangling.

gcc/c/ChangeLog:

        * c-decl.cc (start_decl): Record assembler_name.
        (start_function): Record assembler_name.

gcc/ChangeLog:

        * cgraph.cc (cgraph_node::record_function_versions): Record
        assembler_name.
        * cgraph.h (struct cgraph_function_version_info): Add assembler_name.

gcc/cp/ChangeLog:

        * decl.cc (maybe_mark_function_versioned): Record assember_name.
        (start_decl): Record assembler_name.
        (start_preparsed_function): Record assembler_name.
---
 gcc/c/c-decl.cc | 20 ++++++++++++++++++++
 gcc/cgraph.cc   | 10 ++++++++--
 gcc/cgraph.h    |  3 +++
 gcc/cp/decl.cc  | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 0dcbae9b26f..daa19f360e6 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5762,6 +5762,16 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
       && VAR_OR_FUNCTION_DECL_P (decl))
       objc_check_global_decl (decl);
 
+  /* Store the base assembler name for mangling later.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl)))
+    {
+      cgraph_node *node = cgraph_node::get_create (decl);
+      if (!node->function_version ())
+	node->insert_new_function_version ();
+      node->function_version ()->assembler_name = DECL_ASSEMBLER_NAME (decl);
+    }
+
   /* Add this decl to the current scope.
      TEM may equal DECL or it may be a previous decl of the same name.  */
   if (do_push)
@@ -10863,6 +10873,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
 
   current_function_decl = pushdecl (decl1);
 
+  /* Store the base assembler name for mangling later.  */
+  if (TREE_CODE (decl1) == FUNCTION_DECL
+      && lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl1)))
+    {
+      cgraph_node *node = cgraph_node::get_create (decl1);
+      if (!node->function_version ())
+	node->insert_new_function_version ();
+      node->function_version ()->assembler_name = DECL_ASSEMBLER_NAME (decl1);
+    }
+
   if (tree access = build_attr_access_from_parms (parms, false))
     decl_attributes (&current_function_decl, access, ATTR_FLAG_INTERNAL,
 		     old_decl);
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 1ea38d16e56..c2038be4671 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -252,10 +252,16 @@ cgraph_node::record_function_versions (tree decl1, tree decl2)
   decl2_v = decl2_node->function_version ();
 
   if (decl1_v == NULL)
-    decl1_v = decl1_node->insert_new_function_version ();
+    {
+      decl1_v = decl1_node->insert_new_function_version ();
+      decl1_v->assembler_name = DECL_ASSEMBLER_NAME (decl1);
+    }
 
   if (decl2_v == NULL)
-    decl2_v = decl2_node->insert_new_function_version ();
+    {
+      decl2_v = decl2_node->insert_new_function_version ();
+      decl2_v->assembler_name = DECL_ASSEMBLER_NAME (decl2);
+    }
 
   gcc_assert (decl1_v);
   gcc_assert (decl2_v);
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 065fcc742e8..d9177364b7a 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -856,6 +856,9 @@ struct GTY((for_user)) cgraph_function_version_info {
      dispatcher. The dispatcher decl is an alias to the resolver
      function decl.  */
   tree dispatcher_resolver;
+
+  /* The assmbly name of the function set before version mangling.  */
+  tree assembler_name;
 };
 
 #define DEFCIFCODE(code, type, string)	CIF_ ## code,
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 3b3b4481964..fdef98f8062 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -1273,6 +1273,12 @@ maybe_mark_function_versioned (tree decl)
 {
   if (!DECL_FUNCTION_VERSIONED (decl))
     {
+      cgraph_node *node = cgraph_node::get_create (decl);
+      if (!node->function_version ())
+	node->insert_new_function_version ();
+      if (!node->function_version ()->assembler_name)
+	node->function_version ()->assembler_name = DECL_ASSEMBLER_NAME (decl);
+
       DECL_FUNCTION_VERSIONED (decl) = 1;
       /* If DECL_ASSEMBLER_NAME has already been set, re-mangle
 	 to include the version marker.  */
@@ -6155,6 +6161,20 @@ start_decl (const cp_declarator *declarator,
 
   was_public = TREE_PUBLIC (decl);
 
+  /* Set the assembler string for any versioned function.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && (lookup_attribute (TARGET_HAS_FMV_TARGET_ATTRIBUTE ? "target"
+							    : "target_version",
+			    DECL_ATTRIBUTES (decl))
+	  || lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl))))
+    {
+      cgraph_node *node = cgraph_node::get_create (decl);
+      if (!node->function_version ())
+	node->insert_new_function_version ();
+      if (!node->function_version ()->assembler_name)
+	node->function_version ()->assembler_name = DECL_ASSEMBLER_NAME (decl);
+    }
+
   if ((DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL)
       && current_function_decl)
     {
@@ -18743,6 +18763,20 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   if (!DECL_OMP_DECLARE_REDUCTION_P (decl1))
     start_lambda_scope (decl1);
 
+  /* Set the assembler string for any versioned function.  */
+  if (TREE_CODE (decl1) == FUNCTION_DECL
+      && (lookup_attribute (TARGET_HAS_FMV_TARGET_ATTRIBUTE ? "target"
+							    : "target_version",
+			    DECL_ATTRIBUTES (decl1))
+	  || lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl1))))
+    {
+      cgraph_node *node = cgraph_node::get_create (decl1);
+      if (!node->function_version ())
+	node->insert_new_function_version ();
+      if (!node->function_version ()->assembler_name)
+	node->function_version ()->assembler_name = DECL_ASSEMBLER_NAME (decl1);
+    }
+
   return true;
 }
 

Reply via email to