diff mbox

RFA: PATCH to allow DECL_COMDAT_GROUP to be a DECL

Message ID 537A694D.7050506@redhat.com
State New
Headers show

Commit Message

Jason Merrill May 19, 2014, 8:27 p.m. UTC
I was playing around with this a few months ago but set it aside because 
we weren't in stage 1 at the time.  The way we currently set up comdat 
groups early means that we need to mangle decls early, significantly 
negating the earlier work to lazily set DECL_ASSEMBLER_NAME.  This patch 
improves this situation by allowing a DECL to be used as 
DECL_COMDAT_GROUP in cases where the group name is the same as the 
mangled name of the declaration.

Tested x86_64-pc-linux-gnu.  OK for trunk?

Comments

Jan Hubicka May 19, 2014, 10:10 p.m. UTC | #1
> I was playing around with this a few months ago but set it aside
> because we weren't in stage 1 at the time.  The way we currently set
> up comdat groups early means that we need to mangle decls early,
> significantly negating the earlier work to lazily set
> DECL_ASSEMBLER_NAME.  This patch improves this situation by allowing
> a DECL to be used as DECL_COMDAT_GROUP in cases where the group name
> is the same as the mangled name of the declaration.
> 
> Tested x86_64-pc-linux-gnu.  OK for trunk?

> commit 6f9182ed91a88bb993fe137f6decc15b25f466fd
> Author: Jason Merrill <jason@redhat.com>
> Date:   Mon May 19 15:41:24 2014 -0400
> 
>     	PR c++/47202
>     gcc/cp/
>     	* decl.c (cxx_comdat_group): Return a decl.
>     	* optimize.c (cdtor_comdat_group): Get its DECL_ASSEMBLER_NAME.
>     gcc/
>     	* cgraphunit.c (analyze_functions): Convert all DECL_COMDAT_GROUPs
>     	to IDENTIFIER_NODEs.
>     	* tree.h (DECL_COMDAT_GROUP_ID): New.
>     	* lto-streamer-out.c (write_symbol): Use it.
>     	* symtab.c (dump_symtab_node): Likewise.
>     	* trans-mem.c (ipa_tm_create_version_alias): Likewise.
> 
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index f5d9594..044af45 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -943,6 +943,14 @@ analyze_functions (void)
>    cgraph_state = CGRAPH_STATE_CONSTRUCTION;
>    input_location = UNKNOWN_LOCATION;
>  
> +  /* Convert all COMDAT group designators to IDENTIFIER_NODEs while we still
> +     have front end information.  */
> +  FOR_EACH_SYMBOL (node)
> +    if (DECL_COMDAT_GROUP (node->decl)
> +	&& DECL_P (DECL_COMDAT_GROUP (node->decl)))
> +      DECL_COMDAT_GROUP (node->decl)
> +	= DECL_ASSEMBLER_NAME (DECL_COMDAT_GROUP (node->decl));A

Instead of adding extra loop over whole symtab, what about converting them at a time
the symbols are inserted into the symbol table or in function_and_variable_visibility
that already does quite few changes into various flags?

Honza
diff mbox

Patch

commit 6f9182ed91a88bb993fe137f6decc15b25f466fd
Author: Jason Merrill <jason@redhat.com>
Date:   Mon May 19 15:41:24 2014 -0400

    	PR c++/47202
    gcc/cp/
    	* decl.c (cxx_comdat_group): Return a decl.
    	* optimize.c (cdtor_comdat_group): Get its DECL_ASSEMBLER_NAME.
    gcc/
    	* cgraphunit.c (analyze_functions): Convert all DECL_COMDAT_GROUPs
    	to IDENTIFIER_NODEs.
    	* tree.h (DECL_COMDAT_GROUP_ID): New.
    	* lto-streamer-out.c (write_symbol): Use it.
    	* symtab.c (dump_symtab_node): Likewise.
    	* trans-mem.c (ipa_tm_create_version_alias): Likewise.

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index f5d9594..044af45 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -943,6 +943,14 @@  analyze_functions (void)
   cgraph_state = CGRAPH_STATE_CONSTRUCTION;
   input_location = UNKNOWN_LOCATION;
 
+  /* Convert all COMDAT group designators to IDENTIFIER_NODEs while we still
+     have front end information.  */
+  FOR_EACH_SYMBOL (node)
+    if (DECL_COMDAT_GROUP (node->decl)
+	&& DECL_P (DECL_COMDAT_GROUP (node->decl)))
+      DECL_COMDAT_GROUP (node->decl)
+	= DECL_ASSEMBLER_NAME (DECL_COMDAT_GROUP (node->decl));
+
   /* Ugly, but the fixup can not happen at a time same body alias is created;
      C++ FE is confused about the COMDAT groups being right.  */
   if (cpp_implicit_aliases_done)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a29e3e3..2d6b6cf 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14443,18 +14443,17 @@  cp_missing_noreturn_ok_p (tree decl)
   return DECL_MAIN_P (decl);
 }
 
-/* Return the COMDAT group into which DECL should be placed.  */
+/* Return the decl used to identify the COMDAT group into which DECL should
+   be placed.  */
 
 tree
 cxx_comdat_group (tree decl)
 {
-  tree name;
-
   /* Virtual tables, construction virtual tables, and virtual table
      tables all go in a single COMDAT group, named after the primary
      virtual table.  */
   if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
-    name = DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (DECL_CONTEXT (decl)));
+    decl = CLASSTYPE_VTABLES (DECL_CONTEXT (decl));
   /* For all other DECLs, the COMDAT group is the mangled name of the
      declaration itself.  */
   else
@@ -14472,10 +14471,9 @@  cxx_comdat_group (tree decl)
 	  else
 	    break;
 	}
-      name = DECL_ASSEMBLER_NAME (decl);
     }
 
-  return name;
+  return decl;
 }
 
 /* Returns the return type for FN as written by the user, which may include
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index b089432..0d9a68a 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -170,6 +170,8 @@  cdtor_comdat_group (tree complete, tree base)
     complete_name = cxx_comdat_group (complete);
   if (base_name == NULL)
     base_name = cxx_comdat_group (base);
+  complete_name = DECL_ASSEMBLER_NAME (complete_name);
+  base_name = DECL_ASSEMBLER_NAME (base_name);
   gcc_assert (IDENTIFIER_LENGTH (complete_name)
 	      == IDENTIFIER_LENGTH (base_name));
   grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 6f2bf9c..9da79fa 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -2331,7 +2331,7 @@  write_symbol (struct streamer_tree_cache_d *cache,
     size = 0;
 
   if (DECL_ONE_ONLY (t))
-    comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t));
+    comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP_ID (t));
   else
     comdat = "";
 
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 6b9b77a..bc13667 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -641,7 +641,7 @@  dump_symtab_base (FILE *f, symtab_node *node)
     fprintf (f, " comdat");
   if (DECL_COMDAT_GROUP (node->decl))
     fprintf (f, " comdat_group:%s",
-	     IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->decl)));
+	     IDENTIFIER_POINTER (DECL_COMDAT_GROUP_ID (node->decl)));
   if (DECL_ONE_ONLY (node->decl))
     fprintf (f, " one_only");
   if (DECL_SECTION_NAME (node->decl))
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index f73f454..1da02ab 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -4852,7 +4852,7 @@  ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
 
   /* Perform the same remapping to the comdat group.  */
   if (DECL_ONE_ONLY (new_decl))
-    DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
+    DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP_ID (old_decl));
 
   new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
   new_node->tm_clone = true;
diff --git a/gcc/tree.h b/gcc/tree.h
index f9c2ca9..6c34153 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2322,9 +2322,18 @@  extern void decl_value_expr_insert (tree, tree);
 #define DECL_COMDAT(NODE) \
   (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag)
 
+/* When the target supports COMDAT groups, this indicates which group the
+   DECL is associated with.  This can be either an IDENTIFIER_NODE or a
+   decl, in which case its DECL_ASSEMBLER_NAME identifies the group.  */
 #define DECL_COMDAT_GROUP(NODE) \
   (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group)
 
+/* The identifier for the COMDAT group.  */
+#define DECL_COMDAT_GROUP_ID(NODE) \
+  (DECL_COMDAT_GROUP (NODE) && DECL_P (DECL_COMDAT_GROUP (NODE))	\
+   ? DECL_ASSEMBLER_NAME (DECL_COMDAT_GROUP (NODE))			\
+   : DECL_COMDAT_GROUP (NODE))
+
 /* Used in TREE_PUBLIC decls to indicate that copies of this DECL in
    multiple translation units should be merged.  */
 #define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE)