This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch][lto merge] Remove the comdat_group langhook


> That seems fine to me; for targets that don't support comdat groups the
> patch effectively just changes DECL_ONE_ONLY from a single bit to a word.
>
> I do wonder how much of a difference that makes to memory consumption. Also,
> if you're removing a bitfield you need to update the "unused bits" comment
> at the end of the struct.

Updated patch attached.

It looks like --enable-gather-detailed-mem-stats is broken on trunk.
Checking why. Do you have any suggestion for a good test for memory
use?

> Jason
>
>

Cheers,
-- 
Rafael Avila de Espindola

Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index a99b7df..6783292 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1560,7 +1560,7 @@ cgraph_function_versioning (struct cgraph_node *old_version_node,
      ??? We cannot use COMDAT linkage because there is no
      ABI support for this.  */
   DECL_EXTERNAL (new_version_node->decl) = 0;
-  DECL_ONE_ONLY (new_version_node->decl) = 0;
+  DECL_COMDAT_GROUP (new_version_node->decl) = NULL_TREE;
   TREE_PUBLIC (new_version_node->decl) = 0;
   DECL_COMDAT (new_version_node->decl) = 0;
   DECL_WEAK (new_version_node->decl) = 0;
@@ -1599,7 +1599,7 @@ save_inline_function_body (struct cgraph_node *node)
   tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL);
 
   DECL_EXTERNAL (first_clone->decl) = 0;
-  DECL_ONE_ONLY (first_clone->decl) = 0;
+  DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE;
   TREE_PUBLIC (first_clone->decl) = 0;
   DECL_COMDAT (first_clone->decl) = 0;
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5e7689b..33bf2f2 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7475,7 +7475,7 @@ ix86_file_end (void)
 			     error_mark_node);
 	  TREE_PUBLIC (decl) = 1;
 	  TREE_STATIC (decl) = 1;
-	  DECL_ONE_ONLY (decl) = 1;
+	  DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
 
 	  (*targetm.asm_out.unique_section) (decl, 0);
 	  switch_to_section (get_named_section (decl, NULL, 0));
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 1ce9d36..6723a85 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -78,8 +78,6 @@ extern bool cp_function_decl_explicit_p (tree decl);
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
 #undef LANG_HOOKS_WRITE_GLOBALS
 #define LANG_HOOKS_WRITE_GLOBALS cp_write_global_declarations
-#undef LANG_HOOKS_COMDAT_GROUP
-#define LANG_HOOKS_COMDAT_GROUP cxx_comdat_group
 #undef  LANG_HOOKS_BUILTIN_FUNCTION
 #define LANG_HOOKS_BUILTIN_FUNCTION cxx_builtin_function
 #undef  LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1f3d0c1..ebb6bb4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4380,7 +4380,7 @@ extern tree cxx_builtin_function		(tree decl);
 extern tree cxx_builtin_function_ext_scope	(tree decl);
 extern tree check_elaborated_type_specifier	(enum tag_types, tree, bool);
 extern void warn_extern_redeclared_static	(tree, tree);
-extern const char *cxx_comdat_group		(tree);
+extern tree cxx_comdat_group			(tree);
 extern bool cp_missing_noreturn_ok_p		(tree);
 extern void initialize_artificial_var		(tree, tree);
 extern tree check_var_type			(tree, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e06dce2..894187f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1835,7 +1835,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   /* Merge the storage class information.  */
   merge_weak (newdecl, olddecl);
 
-  DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl);
+  if (DECL_ONE_ONLY (olddecl))
+    DECL_COMDAT_GROUP (newdecl) = DECL_COMDAT_GROUP (olddecl);
+
   DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl);
   TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
   TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
@@ -12750,7 +12752,7 @@ cp_missing_noreturn_ok_p (tree decl)
 
 /* Return the COMDAT group into which DECL should be placed.  */
 
-const char *
+tree
 cxx_comdat_group (tree decl)
 {
   tree name;
@@ -12780,7 +12782,7 @@ cxx_comdat_group (tree decl)
       name = DECL_ASSEMBLER_NAME (decl);
     }
 
-  return IDENTIFIER_POINTER (name);
+  return name;
 }
 
 #include "gt-cp-decl.h"
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8196b54..9264d3a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1508,7 +1508,7 @@ void
 comdat_linkage (tree decl)
 {
   if (flag_weak)
-    make_decl_one_only (decl);
+    make_decl_one_only (decl, cxx_comdat_group (decl));
   else if (TREE_CODE (decl) == FUNCTION_DECL
 	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
     /* We can just emit function and compiler-generated variables
@@ -1580,7 +1580,7 @@ maybe_make_one_only (tree decl)
       || (! DECL_EXPLICIT_INSTANTIATION (decl)
 	  && ! DECL_TEMPLATE_SPECIALIZATION (decl)))
     {
-      make_decl_one_only (decl);
+      make_decl_one_only (decl, cxx_comdat_group (decl));
 
       if (TREE_CODE (decl) == VAR_DECL)
 	{
@@ -1839,7 +1839,7 @@ constrain_visibility (tree decl, int visibility)
       if (!DECL_EXTERN_C_P (decl))
 	{
 	  TREE_PUBLIC (decl) = 0;
-	  DECL_ONE_ONLY (decl) = 0;
+	  DECL_COMDAT_GROUP (decl) = NULL_TREE;
 	  DECL_INTERFACE_KNOWN (decl) = 1;
 	  if (DECL_LANG_SPECIFIC (decl))
 	    DECL_NOT_REALLY_EXTERN (decl) = 1;
@@ -2497,7 +2497,7 @@ get_guard (tree decl)
       TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
       TREE_STATIC (guard) = TREE_STATIC (decl);
       DECL_COMMON (guard) = DECL_COMMON (decl);
-      DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl);
+      DECL_COMDAT_GROUP (guard) = DECL_COMDAT_GROUP (decl);
       if (TREE_PUBLIC (decl))
 	DECL_WEAK (guard) = DECL_WEAK (decl);
       DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index e632fe0..9d67b31 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -381,7 +381,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
   DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
     = DECL_VISIBILITY_SPECIFIED (function);
   if (DECL_ONE_ONLY (function))
-    make_decl_one_only (thunk_fndecl);
+    make_decl_one_only (thunk_fndecl, cxx_comdat_group (thunk_fndecl));
 
   if (flag_syntax_only)
     {
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 8c7b9e8..9d4a8c5 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -141,7 +141,12 @@ maybe_clone_body (tree fn)
       DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
       DECL_COMDAT (clone) = DECL_COMDAT (fn);
       DECL_WEAK (clone) = DECL_WEAK (fn);
-      DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
+
+      /* We don't copy the comdat group from fn to clone because the assembler
+	 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
+	 to it. By doing so, it also corrupted the comdat group. */
+      if (DECL_ONE_ONLY (fn))
+	DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
       DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
       DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
       DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index 5ccbcf1..bdedc06 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -838,7 +838,7 @@ dw2_force_const_mem (rtx x, bool is_public)
 	  DECL_IGNORED_P (decl) = 1;
 	  TREE_PUBLIC (decl) = 1;
 	  DECL_INITIAL (decl) = decl;
-	  make_decl_one_only (decl);
+	  make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
 	}
       else
 	{
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 4b6ce27..34ed4cd 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -58,7 +58,6 @@ extern void lhd_incomplete_type_error (const_tree, const_tree);
 extern tree lhd_type_promotes_to (tree);
 extern void lhd_register_builtin_type (tree, const char *);
 extern bool lhd_decl_ok_for_sibcall (const_tree);
-extern const char *lhd_comdat_group (tree);
 extern tree lhd_expr_size (const_tree);
 extern size_t lhd_tree_size (enum tree_code);
 extern HOST_WIDE_INT lhd_to_target_charset (HOST_WIDE_INT);
@@ -189,7 +188,6 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
 #define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL	lhd_decl_ok_for_sibcall
-#define LANG_HOOKS_COMDAT_GROUP lhd_comdat_group
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_const_tree_false
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING lhd_omp_predetermined_sharing
 #define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR hook_bool_tree_bool_false
@@ -209,7 +207,6 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
   LANG_HOOKS_WRITE_GLOBALS, \
   LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
-  LANG_HOOKS_COMDAT_GROUP, \
   LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
   LANG_HOOKS_OMP_PREDETERMINED_SHARING, \
   LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index fa9b8dd..59a73d2 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -300,14 +300,6 @@ lhd_decl_ok_for_sibcall (const_tree decl ATTRIBUTE_UNUSED)
   return true;
 }
 
-/* Return the COMDAT group into which DECL should be placed.  */
-
-const char *
-lhd_comdat_group (tree decl)
-{
-  return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-}
-
 /* lang_hooks.decls.final_write_globals: perform final processing on
    global variables.  */
 void
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 6c57ca2..1955557 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -173,15 +173,6 @@ struct lang_hooks_for_decls
   /* True if this decl may be called via a sibcall.  */
   bool (*ok_for_sibcall) (const_tree);
 
-  /* Return the COMDAT group into which this DECL should be placed.
-     It is known that the DECL belongs in *some* COMDAT group when
-     this hook is called.  The return value will be used immediately,
-     but not explicitly deallocated, so implementations should not use
-     xmalloc to allocate the string returned.  (Typically, the return
-     value will be the string already stored in an
-     IDENTIFIER_NODE.)  */
-  const char * (*comdat_group) (tree);
-
   /* True if OpenMP should privatize what this DECL points to rather
      than the DECL itself.  */
   bool (*omp_privatize_by_reference) (const_tree);
diff --git a/gcc/testsuite/g++.dg/abi/mangle11.C b/gcc/testsuite/g++.dg/abi/mangle11.C
index 6d09b51..a049a95 100644
--- a/gcc/testsuite/g++.dg/abi/mangle11.C
+++ b/gcc/testsuite/g++.dg/abi/mangle11.C
@@ -1,10 +1,10 @@
 // { dg-options "-Wabi -fabi-version=1" }
 
 template <typename Q>
-void f (typename Q::X) {} // { dg-warning "mangle" }
+void f (typename Q::X) {}
 
 struct S {
   typedef int X;
 };
 
-template void f<S> (int);
+template void f<S> (int); // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle12.C b/gcc/testsuite/g++.dg/abi/mangle12.C
index a3bd9ff..7176fcd 100644
--- a/gcc/testsuite/g++.dg/abi/mangle12.C
+++ b/gcc/testsuite/g++.dg/abi/mangle12.C
@@ -1,11 +1,11 @@
 // { dg-options "-Wabi -fabi-version=1" }
 
 template <template <typename> class Q>
-void f (typename Q<int>::X) {} // { dg-warning "mangle" }
+void f (typename Q<int>::X) {}
 
 template <typename Q>
 struct S {
   typedef int X;
 };
 
-template void f<S> (int); 
+template void f<S> (int);  // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle17.C b/gcc/testsuite/g++.dg/abi/mangle17.C
index 134b976..0a5fe9a 100644
--- a/gcc/testsuite/g++.dg/abi/mangle17.C
+++ b/gcc/testsuite/g++.dg/abi/mangle17.C
@@ -4,8 +4,8 @@ enum E { e = 3 };
 
 template <int I> struct S {};
 
-template <int I> void f (S<I + e + int (3.7)>) {} // { dg-warning "mangle" }
-template void f<7>(S<7 + e + int (3.7)>);  
+template <int I> void f (S<I + e + int (3.7)>) {}
+template void f<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" }
 
-template <int I> void g (S<I + e + int (3.7)>) {} // { dg-warning "mangle" }
-template void g<7>(S<7 + e + int (3.7)>); 
+template <int I> void g (S<I + e + int (3.7)>) {}
+template void g<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle20-2.C b/gcc/testsuite/g++.dg/abi/mangle20-2.C
index 38ac523..bf3d189 100644
--- a/gcc/testsuite/g++.dg/abi/mangle20-2.C
+++ b/gcc/testsuite/g++.dg/abi/mangle20-2.C
@@ -7,10 +7,10 @@
 // PR 9043
 // mangled array types in templates
 
-template <int I> void f(int (*)[2]) {} // { dg-warning "mangled name" }
+template <int I> void f(int (*)[2]) {}
 template <int I> void g(int (*)[I+2]) {}
 
-template void f<1>(int (*)[2]);  
+template void f<1>(int (*)[2]);  // { dg-warning "mangled name" }
 //  { dg-final { scan-assembler "\n_?_Z1fILi1EEvPALi2E_i\[: \t\n\]" } }
 template void g<1>(int (*)[3]);
 //  { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } }
diff --git a/gcc/tree.h b/gcc/tree.h
index 1e58d52..b4314f0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2873,6 +2873,8 @@ extern void decl_restrict_base_insert (tree, tree);
    something which is DECL_COMDAT.  */
 #define DECL_COMDAT(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag)
 
+#define DECL_COMDAT_GROUP(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group)
+
 /* A replaceable function is one which may be replaced at link-time
    with an entirely different definition, provided that the
    replacement has the same type.  For example, functions declared
@@ -2941,12 +2943,13 @@ extern void decl_restrict_base_insert (tree, tree);
 
 /* 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_WITH_VIS_CHECK (NODE)->decl_with_vis.one_only)
+#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE)
 
 struct GTY(()) tree_decl_with_vis {
  struct tree_decl_with_rtl common;
  tree assembler_name;
  tree section_name;
+ tree comdat_group;
 
  /* Belong to VAR_DECL exclusively.  */
  unsigned defer_output:1;
@@ -2966,12 +2969,11 @@ struct GTY(()) tree_decl_with_vis {
  ENUM_BITFIELD(symbol_visibility) visibility : 2;
  unsigned visibility_specified : 1;
  /* Belong to FUNCTION_DECL exclusively.  */
- unsigned one_only : 1;
  unsigned init_priority_p:1;
 
  /* Belongs to VAR_DECL exclusively.  */
  ENUM_BITFIELD(tls_model) tls_model : 3;
- /* 13 unused bits. */
+ /* 14 unused bits. */
 };
 
 /* In a VAR_DECL that's static,
@@ -4984,7 +4986,7 @@ extern unsigned int update_alignment_for_field (record_layout_info, tree,
                                                 unsigned int);
 /* varasm.c */
 extern void make_decl_rtl (tree);
-extern void make_decl_one_only (tree);
+extern void make_decl_one_only (tree, tree);
 extern int supports_one_only (void);
 extern void resolve_unique_section (tree, int, int);
 extern void mark_referenced (tree);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9dcae52..607a101 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -324,7 +324,7 @@ get_emutls_init_templ_addr (tree decl)
   DECL_WEAK (to) = DECL_WEAK (decl);
   if (DECL_ONE_ONLY (decl))
     {
-      make_decl_one_only (to);
+      make_decl_one_only (to, DECL_ASSEMBLER_NAME (to));
       TREE_STATIC (to) = TREE_STATIC (decl);
       TREE_PUBLIC (to) = TREE_PUBLIC (decl);
       DECL_VISIBILITY (to) = DECL_VISIBILITY (decl);
@@ -386,7 +386,7 @@ emutls_decl (tree decl)
       TREE_READONLY (to) = 0;
       SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
       if (DECL_ONE_ONLY (decl))
-	make_decl_one_only (to);
+	make_decl_one_only (to, DECL_ASSEMBLER_NAME (to));
       DECL_CONTEXT (to) = DECL_CONTEXT (decl);
       if (targetm.emutls.var_align_fixed)
 	/* If we're not allowed to change the proxy object's
@@ -5507,7 +5507,7 @@ supports_one_only (void)
    translation units without generating a linker error.  */
 
 void
-make_decl_one_only (tree decl)
+make_decl_one_only (tree decl, tree comdat_group)
 {
   gcc_assert (TREE_CODE (decl) == VAR_DECL
 	      || TREE_CODE (decl) == FUNCTION_DECL);
@@ -5519,7 +5519,7 @@ make_decl_one_only (tree decl)
 #ifdef MAKE_DECL_ONE_ONLY
       MAKE_DECL_ONE_ONLY (decl);
 #endif
-      DECL_ONE_ONLY (decl) = 1;
+      DECL_COMDAT_GROUP (decl) = comdat_group;
     }
   else if (TREE_CODE (decl) == VAR_DECL
       && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
@@ -5780,7 +5780,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
 	fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
       if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
 	fprintf (asm_out_file, ",%s,comdat",
-		 lang_hooks.decls.comdat_group (decl));
+		 IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl)));
     }
 
   putc ('\n', asm_out_file);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]