Turn DECL_SECTION_NAME into string

Jan Hubicka hubicka@ucw.cz
Thu Jun 12 04:33:00 GMT 2014


Hi,
this lenghtly patch makes the legwork to put section names out of tree representation.
Originally they were STRING_CST. I ended up implementing on-side reference counted
string voclabulary that is done in bit baroque way to be GGC and PCH safe (uff).
The memory savings on Firefox are about 60MB, becuase while reading symbol table we
now unify the many duplicated comdat group strings and also we free them after we bring
those local.

The old representation probably made sense when most of string came via __section__
attribute where they was readily parsed as string constants.

Bootstrapped/regtested x86_64-linux, comitted.

Honza

	* symtab.c (section_hash): New hash.
	(symtab_unregister_node): Clear section before freeing.
	(hash_section_hash_entry): New haser.
	(eq_sections): New function.
	(symtab_node::set_section_for_node): New method.
	(set_section_1): Update.
	(symtab_node::set_section): Take string instead of tree as parameter.
	(symtab_resolve_alias): Update.
	* cgraph.h (section_hash_entry_d): New structure.
	(section_hash_entry): New typedef.
	(cgraph_node): Change comdat_group_ to x_comdat_group,
	change section_ to x_section and turn into section_hash_entry;
	update accestors; put set_section_for_node offline.
	* tree.c (decl_section_name): Turn into string.
	(set_decl_section_name): Change parameter to be string.
	* tree.h (decl_section_name, set_decl_section_name): Update prototypes.
	* sdbout.c (sdbout_one_type): Update.
	* tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Update.
	* varasm.c (IN_NAMED_SECTION, get_named_section, resolve_unique_section,
	hot_function_section, get_named_text_section, USE_SELECT_SECTION_FOR_FUNCTIONS,
	default_function_rodata_section, make_decl_rtl, default_unique_section):
	Update.
	* config/c6x/c6x.c (c6x_in_small_data_p): Update.
	(c6x_elf_unique_section): Update.
	* config/nios2/nios2.c (nios2_in_small_data_p): Update.
	* config/pa/pa.c (pa_function_section): Update.
	* config/pa/pa.h (IN_NAMED_SECTION_P): Update.
	* config/ia64/ia64.c (ia64_in_small_data_p): Update.
	* config/arc/arc.c (arc_in_small_data_p): Update.
	* config/arm/unknown-elf.h (IN_NAMED_SECTION_P): Update.
	* config/mcore/mcore.c (mcore_unique_section): Update.
	* config/mips/mips.c (mips16_build_function_stub): Update.
	(mips16_build_call_stub): Update.
	(mips_function_rodata_section): Update.
	(mips_in_small_data_p): Update.
	* config/score/score.c (score_in_small_data_p): Update.
	* config/rx/rx.c (rx_in_small_data): Update.
	* config/rs6000/rs6000.c (rs6000_elf_in_small_data_p): Update.
	(rs6000_xcoff_asm_named_section): Update.
	(rs6000_xcoff_unique_section): Update.
	* config/frv/frv.c (frv_string_begins_with): Update.
	(frv_in_small_data_p): Update.
	* config/v850/v850.c (v850_encode_data_area): Update.
	* config/bfin/bfin.c (DECL_SECTION_NAME): Update.
	(bfin_handle_l1_data_attribute): Update.
	(bfin_handle_l2_attribute): Update.
	* config/mep/mep.c (mep_unique_section): Update.
	* config/microblaze/microblaze.c (microblaze_elf_in_small_data_p): Update.
	* config/h8300/h8300.c (h8300_handle_eightbit_data_attribute): Update.
	(h8300_handle_tiny_data_attribute): Update.
	* config/m32r/m32r.c (m32r_in_small_data_p): Update.
	(m32r_in_small_data_p): Update.
	* config/alpha/alpha.c (alpha_in_small_data_p): Update.
	* config/i386/i386.c (ix86_in_large_data_p): Update.
	* config/i386/winnt.c (i386_pe_unique_section): Update.
	* config/darwin.c (darwin_function_section): Update.
	* config/lm32/lm32.c (lm32_in_small_data_p): Update.
	* tree-emutls.c (get_emutls_init_templ_addr): Update.
	(new_emutls_decl): Update.
	* lto-cgraph.c (lto_output_node, input_node, input_varpool_node,
	input_varpool_node): Update.
	(ead_string_cst): Turn to ...
	(read_string): ... this one.
	* dwarf2out.c (secname_for_decl): Update.
	* asan.c (asan_protect_global): Update.

	* c-family/c-common.c (handle_section_attribute): Update handling for
	section names that are no longer trees.

	* java/class.c (build_utf8_ref): Update handling for section names
	that are no longer trees.
	(emit_register_classes_in_jcr_section): Update.

	* vtable-class-hierarchy.c: Update handling for section names
	that are no longer trees.
	* decl.c (duplicate_decls): Likewise.

	* gcc-interface/utils.c:  Update handling for section names
	that are no longer trees.
Index: sdbout.c
===================================================================
--- sdbout.c	(revision 211433)
+++ sdbout.c	(working copy)
@@ -1017,7 +1017,7 @@ static void
 sdbout_one_type (tree type)
 {
   if (current_function_decl != NULL_TREE
-      && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
+      && DECL_SECTION_NAME (current_function_decl) != NULL)
     ; /* Don't change section amid function.  */
   else
     switch_to_section (current_function_section ());
Index: tree-vect-data-refs.c
===================================================================
--- tree-vect-data-refs.c	(revision 211434)
+++ tree-vect-data-refs.c	(working copy)
@@ -5214,7 +5214,7 @@ vect_can_force_dr_alignment_p (const_tre
      section name is also used.  This is a common idiom used by many
      software projects.  */
   if (TREE_STATIC (decl) 
-      && DECL_SECTION_NAME (decl) != NULL_TREE
+      && DECL_SECTION_NAME (decl) != NULL
       && !symtab_get_node (decl)->implicit_section)
     return false;
 
Index: varasm.c
===================================================================
--- varasm.c	(revision 211434)
+++ varasm.c	(working copy)
@@ -173,7 +173,7 @@ static GTY(()) section *unnamed_sections
 /* Return a nonzero value if DECL has a section attribute.  */
 #define IN_NAMED_SECTION(DECL) \
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
-   && DECL_SECTION_NAME (DECL) != NULL_TREE)
+   && DECL_SECTION_NAME (DECL) != NULL)
 
 /* Hash table of named sections.  */
 static GTY((param_is (section))) htab_t section_htab;
@@ -411,7 +411,7 @@ get_named_section (tree decl, const char
   if (name == NULL)
     {
       gcc_assert (decl && DECL_P (decl) && DECL_SECTION_NAME (decl));
-      name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      name = DECL_SECTION_NAME (decl);
     }
 
   flags = targetm.section_type_flags (decl, name, reloc);
@@ -433,7 +433,7 @@ void
 resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
 			int flag_function_or_data_sections)
 {
-  if (DECL_SECTION_NAME (decl) == NULL_TREE
+  if (DECL_SECTION_NAME (decl) == NULL
       && targetm_common.have_named_sections
       && (flag_function_or_data_sections
 	  || DECL_COMDAT_GROUP (decl)))
@@ -483,7 +483,7 @@ static section *
 hot_function_section (tree decl)
 {
   if (decl != NULL_TREE
-      && DECL_SECTION_NAME (decl) != NULL_TREE
+      && DECL_SECTION_NAME (decl) != NULL
       && targetm_common.have_named_sections)
     return get_named_section (decl, NULL, 0);
   else
@@ -508,13 +508,13 @@ get_named_text_section (tree decl,
     {
       if (named_section_suffix)
 	{
-	  tree dsn = DECL_SECTION_NAME (decl);
+	  const char *dsn = DECL_SECTION_NAME (decl);
 	  const char *stripped_name;
 	  char *name, *buffer;
 
-	  name = (char *) alloca (TREE_STRING_LENGTH (dsn) + 1);
-	  memcpy (name, TREE_STRING_POINTER (dsn),
-		  TREE_STRING_LENGTH (dsn) + 1);
+	  name = (char *) alloca (strlen (dsn) + 1);
+	  memcpy (name, dsn,
+		  strlen (dsn) + 1);
 
 	  stripped_name = targetm.strip_name_encoding (name);
 
@@ -620,7 +620,7 @@ function_section_1 (tree decl, bool forc
 
 #ifdef USE_SELECT_SECTION_FOR_FUNCTIONS
   if (decl != NULL_TREE
-      && DECL_SECTION_NAME (decl) != NULL_TREE)
+      && DECL_SECTION_NAME (decl) != NULL)
     {
       if (targetm.asm_out.function_section)
 	section = targetm.asm_out.function_section (decl, freq,
@@ -694,7 +694,7 @@ default_function_rodata_section (tree de
 {
   if (decl != NULL_TREE && DECL_SECTION_NAME (decl))
     {
-      const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      const char *name = DECL_SECTION_NAME (decl);
 
       if (DECL_COMDAT_GROUP (decl) && HAVE_COMDAT_GROUP)
         {
@@ -1380,7 +1380,7 @@ make_decl_rtl (tree decl)
      we take care of recomputing the DECL_RTL after visibility is changed.  */
   if (TREE_CODE (decl) == VAR_DECL
       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
-      && DECL_SECTION_NAME (decl) != NULL_TREE
+      && DECL_SECTION_NAME (decl) != NULL
       && DECL_INITIAL (decl) == NULL_TREE
       && DECL_COMMON (decl))
     DECL_COMMON (decl) = 0;
@@ -6471,7 +6471,7 @@ default_unique_section (tree decl, int r
 
   string = ACONCAT ((linkonce, prefix, ".", name, NULL));
 
-  set_decl_section_name (decl, build_string (strlen (string), string));
+  set_decl_section_name (decl, string);
 }
 
 /* Like compute_reloc_for_constant, except for an RTX.  The return value
Index: symtab.c
===================================================================
--- symtab.c	(revision 211434)
+++ symtab.c	(working copy)
@@ -57,6 +57,10 @@ const char * const ld_plugin_symbol_reso
   "prevailing_def_ironly_exp"
 };
 
+
+/* Hash table used to hold sections.  */
+static GTY((param_is (section_hash_entry))) htab_t section_hash;
+
 /* Hash table used to convert assembler names into nodes.  */
 static GTY((param_is (symtab_node))) htab_t assembler_name_hash;
 
@@ -307,6 +311,9 @@ symtab_unregister_node (symtab_node *nod
   ipa_remove_all_references (&node->ref_list);
   ipa_remove_all_referring (&node->ref_list);
 
+  /* Remove reference to section.  */
+  node->set_section_for_node (NULL);
+
   symtab_remove_from_same_comdat_group (node);
 
   if (node->previous)
@@ -1081,22 +1088,92 @@ fixup_same_cpp_alias_visibility (symtab_
   node->externally_visible = target->externally_visible;
 }
 
+/* Hash sections by their names.  */
+
+static hashval_t
+hash_section_hash_entry (const void *p)
+{
+  const section_hash_entry *n = (const section_hash_entry *) p;
+  return htab_hash_string (n->name);
+}
+
+/* Return true if section P1 name equals to P2.  */
+
+static int
+eq_sections (const void *p1, const void *p2)
+{
+  const section_hash_entry *n1 = (const section_hash_entry *) p1;
+  const char *name = (const char *)p2;
+  return n1->name == name || !strcmp (n1->name, name);
+}
+
+/* Set section, do not recurse into aliases.
+   When one wants to change section of symbol and its aliases,
+   use set_section  */
+
+void
+symtab_node::set_section_for_node (const char *section)
+{
+  const char *current = get_section ();
+  void **slot;
+
+  if (current == section
+      || (current && section
+	  && !strcmp (current, section)))
+    return;
+
+  if (current)
+    {
+      x_section->ref_count--;
+      if (!x_section->ref_count)
+	{
+	  slot = htab_find_slot_with_hash (section_hash, x_section->name,
+					   htab_hash_string (x_section->name),
+					   INSERT);
+	  ggc_free (x_section);
+	  htab_clear_slot (section_hash, slot);
+	}
+      x_section = NULL;
+    }
+  if (!section)
+    {
+      implicit_section = false;
+      return;
+    }
+  if (!section_hash)
+    section_hash = htab_create_ggc (10, hash_section_hash_entry,
+				    eq_sections, NULL);
+  slot = htab_find_slot_with_hash (section_hash, section,
+				   htab_hash_string (section),
+				   INSERT);
+  if (*slot)
+    x_section = (section_hash_entry *)*slot;
+  else
+    {
+      int len = strlen (section);
+      *slot = x_section = ggc_cleared_alloc<section_hash_entry> ();
+      x_section->name = ggc_vec_alloc<char> (len + 1);
+      memcpy (x_section->name, section, len + 1);
+    }
+  x_section->ref_count++;
+}
+
 /* Worker for set_section.  */
 
 static bool
 set_section_1 (struct symtab_node *n, void *s)
 {
-  n->set_section_for_node ((tree)s);
+  n->set_section_for_node ((char *)s);
   return false;
 }
 
 /* Set section of symbol and its aliases.  */
 
 void
-symtab_node::set_section (tree section)
+symtab_node::set_section (const char *section)
 {
   gcc_assert (!this->alias);
-  symtab_for_node_and_aliases (this, set_section_1, section, true);
+  symtab_for_node_and_aliases (this, set_section_1, const_cast<char *>(section), true);
 }
 
 /* Worker for symtab_resolve_alias.  */
@@ -1156,7 +1233,8 @@ symtab_resolve_alias (symtab_node *node,
       error ("section of alias %q+D must match section of its target",
 	     node->decl);
     }
-  symtab_for_node_and_aliases (node, set_section_1, target->get_section_name (), true);
+  symtab_for_node_and_aliases (node, set_section_1,
+			       const_cast<char *>(target->get_section ()), true);
   if (target->implicit_section)
     symtab_for_node_and_aliases (node,
 				 set_implicit_section, NULL, true);
Index: config/c6x/c6x.c
===================================================================
--- config/c6x/c6x.c	(revision 211433)
+++ config/c6x/c6x.c	(working copy)
@@ -868,7 +868,7 @@ c6x_in_small_data_p (const_tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
 
       if (strcmp (section, ".neardata") == 0
 	  || strncmp (section, ".neardata.", 10) == 0
@@ -1060,7 +1060,7 @@ c6x_elf_unique_section (tree decl, int r
 
       string = ACONCAT ((linkonce, prefix, ".", name, NULL));
 
-      set_decl_section_name (decl, build_string (strlen (string), string));
+      set_decl_section_name (decl, string);
       return;
     }
   default_unique_section (decl, reloc);
Index: config/nios2/nios2.c
===================================================================
--- config/nios2/nios2.c	(revision 211433)
+++ config/nios2/nios2.c	(working copy)
@@ -1628,7 +1628,7 @@ nios2_in_small_data_p (const_tree exp)
     {
       if (DECL_SECTION_NAME (exp))
 	{
-	  const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+	  const char *section = DECL_SECTION_NAME (exp);
 	  if (nios2_section_threshold > 0
 	      && nios2_small_section_name_p (section))
 	    return true;
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 211433)
+++ config/pa/pa.c	(working copy)
@@ -10262,10 +10262,10 @@ pa_function_section (tree decl, enum nod
   /* Force nested functions into the same section as the containing
      function.  */
   if (decl
-      && DECL_SECTION_NAME (decl) == NULL_TREE
+      && DECL_SECTION_NAME (decl) == NULL
       && DECL_CONTEXT (decl) != NULL_TREE
       && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL
-      && DECL_SECTION_NAME (DECL_CONTEXT (decl)) == NULL_TREE)
+      && DECL_SECTION_NAME (DECL_CONTEXT (decl)) == NULL)
     return function_section (DECL_CONTEXT (decl));
 
   /* Otherwise, use the default function section.  */
Index: config/pa/pa.h
===================================================================
--- config/pa/pa.h	(revision 211433)
+++ config/pa/pa.h	(working copy)
@@ -955,7 +955,7 @@ do {									     \
 /* Return a nonzero value if DECL has a section attribute.  */
 #define IN_NAMED_SECTION_P(DECL) \
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
-   && DECL_SECTION_NAME (DECL) != NULL_TREE)
+   && DECL_SECTION_NAME (DECL) != NULL)
 
 /* Define this macro if references to a symbol must be treated
    differently depending on something about the variable or
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 211433)
+++ config/ia64/ia64.c	(working copy)
@@ -9893,7 +9893,7 @@ ia64_in_small_data_p (const_tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
 
       if (strcmp (section, ".sdata") == 0
 	  || strncmp (section, ".sdata.", 7) == 0
Index: config/arc/arc.c
===================================================================
--- config/arc/arc.c	(revision 211433)
+++ config/arc/arc.c	(working copy)
@@ -6277,7 +6277,7 @@ arc_in_small_data_p (const_tree decl)
       const char *name;
 
       /* Reject anything that isn't in a known small-data section.  */
-      name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      name = DECL_SECTION_NAME (decl);
       if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
 	return false;
 
Index: config/arm/unknown-elf.h
===================================================================
--- config/arm/unknown-elf.h	(revision 211433)
+++ config/arm/unknown-elf.h	(working copy)
@@ -50,7 +50,7 @@
 /* Return a nonzero value if DECL has a section attribute.  */
 #define IN_NAMED_SECTION_P(DECL)					\
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL)	\
-   && DECL_SECTION_NAME (DECL) != NULL_TREE)
+   && DECL_SECTION_NAME (DECL) != NULL)
 
 #undef  ASM_OUTPUT_ALIGNED_BSS
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)   	\
Index: config/mcore/mcore.c
===================================================================
--- config/mcore/mcore.c	(revision 211433)
+++ config/mcore/mcore.c	(working copy)
@@ -3089,7 +3089,7 @@ mcore_unique_section (tree decl, int rel
   
   sprintf (string, "%s%s", prefix, name);
 
-  set_decl_section_name (decl, build_string (len, string));
+  set_decl_section_name (decl, string);
 }
 
 int
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 211433)
+++ config/mips/mips.c	(working copy)
@@ -6618,7 +6618,7 @@ mips16_build_function_stub (void)
   stubdecl = build_decl (BUILTINS_LOCATION,
 			 FUNCTION_DECL, get_identifier (stubname),
 			 build_function_type_list (void_type_node, NULL_TREE));
-  set_decl_section_name (stubdecl, build_string (strlen (secname), secname));
+  set_decl_section_name (stubdecl, secname);
   DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
 				       RESULT_DECL, NULL_TREE, void_type_node);
 
@@ -6872,7 +6872,7 @@ mips16_build_call_stub (rtx retval, rtx
 			     FUNCTION_DECL, stubid,
 			     build_function_type_list (void_type_node,
 						       NULL_TREE));
-      set_decl_section_name (stubdecl, build_string (strlen (secname), secname));
+      set_decl_section_name (stubdecl, secname);
       DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
 					   RESULT_DECL, NULL_TREE,
 					   void_type_node);
@@ -8490,7 +8490,7 @@ mips_function_rodata_section (tree decl)
 
   if (decl && DECL_SECTION_NAME (decl))
     {
-      const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      const char *name = DECL_SECTION_NAME (decl);
       if (DECL_COMDAT_GROUP (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
 	{
 	  char *rname = ASTRDUP (name);
@@ -8530,7 +8530,7 @@ mips_in_small_data_p (const_tree decl)
       const char *name;
 
       /* Reject anything that isn't in a known small-data section.  */
-      name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      name = DECL_SECTION_NAME (decl);
       if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
 	return false;
 
Index: config/score/score.c
===================================================================
--- config/score/score.c	(revision 211433)
+++ config/score/score.c	(working copy)
@@ -668,7 +668,7 @@ score_in_small_data_p (const_tree decl)
   if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
     {
       const char *name;
-      name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      name = DECL_SECTION_NAME (decl);
       if (strcmp (name, ".sdata") != 0
           && strcmp (name, ".sbss") != 0)
         return true;
Index: config/rx/rx.c
===================================================================
--- config/rx/rx.c	(revision 211433)
+++ config/rx/rx.c	(working copy)
@@ -2219,7 +2219,7 @@ static bool
 rx_in_small_data (const_tree decl)
 {
   int size;
-  const_tree section;
+  const char * section;
 
   if (rx_small_data_limit == 0)
     return false;
@@ -2238,11 +2238,7 @@ rx_in_small_data (const_tree decl)
 
   section = DECL_SECTION_NAME (decl);
   if (section)
-    {
-      const char * const name = TREE_STRING_POINTER (section);
-
-      return (strcmp (name, "D_2") == 0) || (strcmp (name, "B_2") == 0);
-    }
+    return (strcmp (section, "D_2") == 0) || (strcmp (section, "B_2") == 0);
 
   size = int_size_in_bytes (TREE_TYPE (decl));
 
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 211433)
+++ config/rs6000/rs6000.c	(working copy)
@@ -28508,7 +28508,7 @@ rs6000_elf_in_small_data_p (const_tree d
 
   if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      const char *section = DECL_SECTION_NAME (decl);
       if (compare_section_name (section, ".sdata")
 	  || compare_section_name (section, ".sdata2")
 	  || compare_section_name (section, ".gnu.linkonce.s")
@@ -29277,7 +29277,7 @@ rs6000_xcoff_asm_named_section (const ch
 
 #define IN_NAMED_SECTION(DECL) \
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
-   && DECL_SECTION_NAME (DECL) != NULL_TREE)
+   && DECL_SECTION_NAME (DECL) != NULL)
 
 static section *
 rs6000_xcoff_select_section (tree decl, int reloc,
@@ -29342,7 +29342,7 @@ rs6000_xcoff_unique_section (tree decl,
 
   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   name = (*targetm.strip_name_encoding) (name);
-  set_decl_section_name (decl, build_string (strlen (name), name));
+  set_decl_section_name (decl, name);
 }
 
 /* Select section for constant in constant pool.
Index: config/frv/frv.c
===================================================================
--- config/frv/frv.c	(revision 211433)
+++ config/frv/frv.c	(working copy)
@@ -263,7 +263,7 @@ static frv_stack_t *frv_stack_cache = (f
 static void frv_option_override			(void);
 static bool frv_legitimate_address_p		(enum machine_mode, rtx, bool);
 static int frv_default_flags_for_cpu		(void);
-static int frv_string_begins_with		(const_tree, const char *);
+static int frv_string_begins_with		(const char *, const char *);
 static FRV_INLINE bool frv_small_data_reloc_p	(rtx, int);
 static void frv_print_operand			(FILE *, rtx, int);
 static void frv_print_operand_address		(FILE *, rtx);
@@ -773,13 +773,12 @@ frv_option_override (void)
 /* Return true if NAME (a STRING_CST node) begins with PREFIX.  */
 
 static int
-frv_string_begins_with (const_tree name, const char *prefix)
+frv_string_begins_with (const char *name, const char *prefix)
 {
   const int prefix_len = strlen (prefix);
 
   /* Remember: NAME's length includes the null terminator.  */
-  return (TREE_STRING_LENGTH (name) > prefix_len
-	  && strncmp (TREE_STRING_POINTER (name), prefix, prefix_len) == 0);
+  return (strncmp (name, prefix, prefix_len) == 0);
 }
 
 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
@@ -9475,7 +9474,7 @@ static bool
 frv_in_small_data_p (const_tree decl)
 {
   HOST_WIDE_INT size;
-  const_tree section_name;
+  const char *section_name;
 
   /* Don't apply the -G flag to internal compiler structures.  We
      should leave such structures in the main data section, partly
Index: config/v850/v850.c
===================================================================
--- config/v850/v850.c	(revision 211433)
+++ config/v850/v850.c	(working copy)
@@ -2190,7 +2190,7 @@ v850_encode_data_area (tree decl, rtx sy
     {
       if (DECL_SECTION_NAME (decl))
 	{
-	  const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+	  const char *name = DECL_SECTION_NAME (decl);
 	  
 	  if (streq (name, ".zdata") || streq (name, ".zbss"))
 	    v850_set_data_area (decl, DATA_AREA_ZDA);
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 211433)
+++ config/bfin/bfin.c	(working copy)
@@ -4760,8 +4760,8 @@ bfin_handle_l1_text_attribute (tree *nod
 
   /* The decl may have already been given a section attribute
      from a previous declaration. Ensure they match.  */
-  else if (DECL_SECTION_NAME (decl) != NULL_TREE
-	   && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+  else if (DECL_SECTION_NAME (decl) != NULL
+	   && strcmp (DECL_SECTION_NAME (decl),
 		      ".l1.text") != 0)
     {
       error ("section of %q+D conflicts with previous declaration",
@@ -4769,7 +4769,7 @@ bfin_handle_l1_text_attribute (tree *nod
       *no_add_attrs = true;
     }
   else
-    set_decl_section_name (decl, build_string (9, ".l1.text"));
+    set_decl_section_name (decl, ".l1.text");
 
   return NULL_TREE;
 }
@@ -4811,8 +4811,8 @@ bfin_handle_l1_data_attribute (tree *nod
 
       /* The decl may have already been given a section attribute
 	 from a previous declaration. Ensure they match.  */
-      if (DECL_SECTION_NAME (decl) != NULL_TREE
-	  && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+      if (DECL_SECTION_NAME (decl) != NULL
+	  && strcmp (DECL_SECTION_NAME (decl),
 		     section_name) != 0)
 	{
 	  error ("section of %q+D conflicts with previous declaration",
@@ -4820,8 +4820,7 @@ bfin_handle_l1_data_attribute (tree *nod
 	  *no_add_attrs = true;
 	}
       else
-	DECL_SECTION_NAME (decl)
-	  = build_string (strlen (section_name) + 1, section_name);
+	set_decl_section_name (decl, section_name);
     }
 
  return NULL_TREE;
@@ -4838,8 +4837,8 @@ bfin_handle_l2_attribute (tree *node, tr
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
-      if (DECL_SECTION_NAME (decl) != NULL_TREE
-	  && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+      if (DECL_SECTION_NAME (decl) != NULL
+	  && strcmp (DECL_SECTION_NAME (decl),
 		     ".l2.text") != 0)
 	{
 	  error ("section of %q+D conflicts with previous declaration",
@@ -4847,12 +4846,12 @@ bfin_handle_l2_attribute (tree *node, tr
 	  *no_add_attrs = true;
 	}
       else
-	set_decl_section_name (decl, build_string (9, ".l2.text"));
+	set_decl_section_name (decl, ".l2.text");
     }
   else if (TREE_CODE (decl) == VAR_DECL)
     {
-      if (DECL_SECTION_NAME (decl) != NULL_TREE
-	  && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+      if (DECL_SECTION_NAME (decl) != NULL
+	  && strcmp (DECL_SECTION_NAME (decl),
 		     ".l2.data") != 0)
 	{
 	  error ("section of %q+D conflicts with previous declaration",
@@ -4860,7 +4859,7 @@ bfin_handle_l2_attribute (tree *node, tr
 	  *no_add_attrs = true;
 	}
       else
-	set_decl_section_name (decl, build_string (9, ".l2.data"));
+	set_decl_section_name (decl, ".l2.data");
     }
 
   return NULL_TREE;
Index: config/mep/mep.c
===================================================================
--- config/mep/mep.c	(revision 211433)
+++ config/mep/mep.c	(working copy)
@@ -4658,7 +4658,7 @@ mep_unique_section (tree decl, int reloc
 
   sprintf (string, "%s%s", prefix, name);
 
-  set_decl_section_name (decl, build_string (len, string));
+  set_decl_section_name (decl, string);
 }
 
 /* Given a decl, a section name, and whether the decl initializer
Index: config/microblaze/microblaze.c
===================================================================
--- config/microblaze/microblaze.c	(revision 211433)
+++ config/microblaze/microblaze.c	(working copy)
@@ -3067,7 +3067,7 @@ microblaze_elf_in_small_data_p (const_tr
 
   if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      const char *section = DECL_SECTION_NAME (decl);
       if (strcmp (section, ".sdata") == 0
 	  || strcmp (section, ".sdata2") == 0
 	  || strcmp (section, ".sbss") == 0
Index: config/h8300/h8300.c
===================================================================
--- config/h8300/h8300.c	(revision 211433)
+++ config/h8300/h8300.c	(working copy)
@@ -5461,7 +5461,7 @@ h8300_handle_eightbit_data_attribute (tr
 
   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
     {
-      set_decl_section_name (decl, build_string (7, ".eight"));
+      set_decl_section_name (decl, ".eight");
     }
   else
     {
@@ -5485,7 +5485,7 @@ h8300_handle_tiny_data_attribute (tree *
 
   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
     {
-      set_decl_section_name (decl, build_string (6, ".tiny"));
+      set_decl_section_name (decl, ".tiny");
     }
   else
     {
Index: config/m32r/m32r.c
===================================================================
--- config/m32r/m32r.c	(revision 211433)
+++ config/m32r/m32r.c	(working copy)
@@ -463,7 +463,7 @@ m32r_encode_section_info (tree decl, rtx
 static bool
 m32r_in_small_data_p (const_tree decl)
 {
-  const_tree section;
+  const char *section;
 
   if (TREE_CODE (decl) != VAR_DECL)
     return false;
@@ -474,8 +474,7 @@ m32r_in_small_data_p (const_tree decl)
   section = DECL_SECTION_NAME (decl);
   if (section)
     {
-      const char *const name = TREE_STRING_POINTER (section);
-      if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0)
+      if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0)
 	return true;
     }
   else
Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c	(revision 211433)
+++ config/alpha/alpha.c	(working copy)
@@ -682,7 +682,7 @@ alpha_in_small_data_p (const_tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
       if (strcmp (section, ".sdata") == 0
 	  || strcmp (section, ".sbss") == 0)
 	return true;
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 211433)
+++ config/i386/i386.c	(working copy)
@@ -5028,7 +5028,7 @@ ix86_in_large_data_p (tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
       if (strcmp (section, ".ldata") == 0
 	  || strcmp (section, ".lbss") == 0)
 	return true;
@@ -5193,7 +5193,7 @@ x86_64_elf_unique_section (tree decl, in
 
 	  string = ACONCAT ((linkonce, prefix, ".", name, NULL));
 
-	  set_decl_section_name (decl, build_string (strlen (string), string));
+	  set_decl_section_name (decl, string);
 	  return;
 	}
     }
Index: config/i386/winnt.c
===================================================================
--- config/i386/winnt.c	(revision 211433)
+++ config/i386/winnt.c	(working copy)
@@ -438,7 +438,7 @@ i386_pe_unique_section (tree decl, int r
   string = XALLOCAVEC (char, len + 1);
   sprintf (string, "%s%s", prefix, name);
 
-  set_decl_section_name (decl, build_string (len, string));
+  set_decl_section_name (decl, string);
 }
 
 /* Local and global relocs can be placed always into readonly memory for
Index: config/darwin.c
===================================================================
--- config/darwin.c	(revision 211433)
+++ config/darwin.c	(working copy)
@@ -3604,7 +3604,7 @@ darwin_function_section (tree decl, enum
 
   /* If there is a specified section name, we should not be trying to
      override.  */
-  if (decl && DECL_SECTION_NAME (decl) != NULL_TREE)
+  if (decl && DECL_SECTION_NAME (decl) != NULL)
     return get_named_section (decl, NULL, 0);
 
   /* We always put unlikely executed stuff in the cold section.  */
Index: config/lm32/lm32.c
===================================================================
--- config/lm32/lm32.c	(revision 211433)
+++ config/lm32/lm32.c	(working copy)
@@ -791,7 +791,7 @@ lm32_in_small_data_p (const_tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
       if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0)
 	return true;
     }
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(revision 211433)
+++ c-family/c-common.c	(working copy)
@@ -7426,8 +7426,8 @@ handle_section_attribute (tree *node, tr
 
 	  /* The decl may have already been given a section attribute
 	     from a previous declaration.  Ensure they match.  */
-	  else if (DECL_SECTION_NAME (decl) != NULL_TREE
-		   && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+	  else if (DECL_SECTION_NAME (decl) != NULL
+		   && strcmp (DECL_SECTION_NAME (decl),
 			      TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
 	    {
 	      error ("section of %q+D conflicts with previous declaration",
@@ -7442,7 +7442,8 @@ handle_section_attribute (tree *node, tr
 	      *no_add_attrs = true;
 	    }
 	  else
-	    set_decl_section_name (decl, TREE_VALUE (args));
+	    set_decl_section_name (decl,
+				   TREE_STRING_POINTER (TREE_VALUE (args)));
 	}
       else
 	{
Index: java/class.c
===================================================================
--- java/class.c	(revision 211433)
+++ java/class.c	(working copy)
@@ -991,7 +991,7 @@ build_utf8_ref (tree name)
 		       | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
 	  sprintf (buf, ".rodata.jutf8.%d", decl_size);
 	  switch_to_section (get_section (buf, flags, NULL));
-	  set_decl_section_name (decl, build_string (strlen (buf), buf));
+	  set_decl_section_name (decl, buf);
 	}
     }
 
@@ -2815,8 +2815,7 @@ emit_register_classes_in_jcr_section (vo
   DECL_ARTIFICIAL (cdecl) = 1;
   DECL_IGNORED_P (cdecl) = 1;
   DECL_PRESERVE_P (cdecl) = 1;
-  set_decl_section_name (cdecl, build_string (strlen (JCR_SECTION_NAME),
-					      JCR_SECTION_NAME));
+  set_decl_section_name (cdecl, JCR_SECTION_NAME);
   pushdecl_top_level (cdecl);
   relayout_decl (cdecl);
   rest_of_decl_compilation (cdecl, 1, 0);
Index: c/c-decl.c
===================================================================
--- c/c-decl.c	(revision 211433)
+++ c/c-decl.c	(working copy)
@@ -2305,7 +2305,7 @@ merge_decls (tree newdecl, tree olddecl,
 	 must be done later in decl_attributes since we are called
 	 before attributes are assigned.  */
       if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC (olddecl))
-	  && DECL_SECTION_NAME (newdecl) == NULL_TREE
+	  && DECL_SECTION_NAME (newdecl) == NULL
 	  && DECL_SECTION_NAME (olddecl))
 	set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl));
 
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 211434)
+++ cgraph.h	(working copy)
@@ -37,6 +37,19 @@ enum symtab_type
   SYMTAB_VARIABLE
 };
 
+/* Section names are stored as reference counted strings in GGC safe hashtable
+   (to make them survive through PCH).  */
+
+struct GTY(()) section_hash_entry_d
+{
+  int ref_count;
+  char *name;  /* As long as this datastructure stays in GGC, we can not put
+		  string at the tail of structure of GGC dies in horrible
+		  way  */
+};
+
+typedef struct section_hash_entry_d section_hash_entry;
+
 /* Base of all entries in the symbol table.
    The symtab_node is inherited by cgraph and varpol nodes.  */
 class GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),
@@ -147,14 +160,14 @@ public:
   /* Return comdat group.  */
   tree get_comdat_group ()
     {
-      return comdat_group_;
+      return x_comdat_group;
     }
 
   tree get_comdat_group_id ()
     {
-      if (comdat_group_ && TREE_CODE (comdat_group_) != IDENTIFIER_NODE)
-	comdat_group_ = DECL_ASSEMBLER_NAME (comdat_group_);
-      return comdat_group_;
+      if (x_comdat_group && TREE_CODE (x_comdat_group) != IDENTIFIER_NODE)
+	x_comdat_group = DECL_ASSEMBLER_NAME (x_comdat_group);
+      return x_comdat_group;
     }
 
   /* Set comdat group.  */
@@ -162,32 +175,15 @@ public:
     {
       gcc_checking_assert (!group || TREE_CODE (group) == IDENTIFIER_NODE
 			   || DECL_P (group));
-      comdat_group_ = group;
-    }
-
-  /* Return section as STRING_CST.  */
-  tree get_section_name ()
-    {
-      return section_;
+      x_comdat_group = group;
     }
 
   /* Return section as string.  */
   const char * get_section ()
     {
-      if (!section_)
+      if (!x_section)
 	return NULL;
-      return TREE_STRING_POINTER (section_);
-    }
-
-  /* Set section, do not recurse into aliases.
-     When one wants to change section of symbol and its aliases,
-     use set_section  */
-  void set_section_for_node (tree section)
-    {
-      gcc_checking_assert (!section || TREE_CODE (section) == STRING_CST);
-      section_ = section;
-      if (!section)
-	implicit_section = false;
+      return x_section->name;
     }
 
   /* Vectors of referring and referenced entities.  */
@@ -204,13 +200,14 @@ public:
   PTR GTY ((skip)) aux;
 
   /* Comdat group the symbol is in.  Can be private if GGC allowed that.  */
-  tree comdat_group_;
+  tree x_comdat_group;
 
   /* Section name. Again can be private, if allowed.  */
-  tree section_;
+  section_hash_entry *x_section;
 
   /* Set section for symbol and its aliases.  */
-  void set_section (tree section);
+  void set_section (const char *section);
+  void set_section_for_node (const char *section);
 };
 
 enum availability
Index: tree.c
===================================================================
--- tree.c	(revision 211434)
+++ tree.c	(working copy)
@@ -628,19 +628,19 @@ decl_comdat_group_id (const_tree node)
 
 /* When the target supports named section, return its name as IDENTIFIER_NODE
    or NULL if it is in no section.  */
-tree
+const char *
 decl_section_name (const_tree node)
 {
   struct symtab_node *snode = symtab_get_node (node);
   if (!snode)
     return NULL;
-  return snode->get_section_name ();
+  return snode->get_section ();
 }
 
 /* Set section section name of NODE to VALUE (that is expected to
    be identifier node)  */
 void
-set_decl_section_name (tree node, tree value)
+set_decl_section_name (tree node, const char *value)
 {
   struct symtab_node *snode;
 
Index: tree.h
===================================================================
--- tree.h	(revision 211434)
+++ tree.h	(working copy)
@@ -3427,8 +3427,8 @@ tree_operand_check_code (const_tree __t,
 extern tree decl_assembler_name (tree);
 extern tree decl_comdat_group (const_tree);
 extern tree decl_comdat_group_id (const_tree);
-extern tree decl_section_name (const_tree);
-extern void set_decl_section_name (tree, tree);
+extern const char *decl_section_name (const_tree);
+extern void set_decl_section_name (tree, const char *);
 
 /* Compute the number of bytes occupied by 'node'.  This routine only
    looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH.  */
Index: tree-emutls.c
===================================================================
--- tree-emutls.c	(revision 211433)
+++ tree-emutls.c	(working copy)
@@ -264,10 +264,7 @@ get_emutls_init_templ_addr (tree decl)
 
   if (targetm.emutls.tmpl_section)
     {
-      set_decl_section_name
-	(to,
-         build_string (strlen (targetm.emutls.tmpl_section),
-		       targetm.emutls.tmpl_section));
+      set_decl_section_name (to, targetm.emutls.tmpl_section);
     }
   else
     set_decl_section_name (to, DECL_SECTION_NAME (decl));
@@ -325,10 +322,7 @@ new_emutls_decl (tree decl, tree alias_o
   /* If the target wants the control variables grouped, do so.  */
   if (!DECL_COMMON (to) && targetm.emutls.var_section)
     {
-      set_decl_section_name 
-        (to,
-         build_string (strlen (targetm.emutls.var_section),
-		       targetm.emutls.var_section));
+      set_decl_section_name (to, targetm.emutls.var_section);
     }
 
   /* If this variable is defined locally, then we need to initialize the
Index: cp/vtable-class-hierarchy.c
===================================================================
--- cp/vtable-class-hierarchy.c	(revision 211434)
+++ cp/vtable-class-hierarchy.c	(working copy)
@@ -1247,8 +1247,7 @@ vtable_find_or_create_map_decl (tree bas
       /* Put these mmap variables in thr .vtable_map_vars section, so
          we can find and protect them.  */
 
-      set_decl_section_name (var_decl, build_string (strlen (".vtable_map_vars"),
-                                                     ".vtable_map_vars"));
+      set_decl_section_name (var_decl, ".vtable_map_vars");
       symtab_get_node (var_decl)->implicit_section = true;
       DECL_INITIAL (var_decl) = initial_value;
 
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 211433)
+++ cp/decl.c	(working copy)
@@ -2020,8 +2020,8 @@ duplicate_decls (tree newdecl, tree oldd
 	 done later in decl_attributes since we are called before attributes
 	 are assigned.  */
       if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC (olddecl))
-	  && DECL_SECTION_NAME (newdecl) == NULL_TREE
-	  && DECL_SECTION_NAME (olddecl) != NULL_TREE)
+	  && DECL_SECTION_NAME (newdecl) == NULL
+	  && DECL_SECTION_NAME (olddecl) != NULL)
 	set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl));
 
       if (TREE_CODE (newdecl) == FUNCTION_DECL)
Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c	(revision 211434)
+++ lto-cgraph.c	(working copy)
@@ -504,7 +504,6 @@ lto_output_node (struct lto_simple_outpu
   section = node->get_section ();
   if (!section)
     section = "";
-  lto_output_data_stream (ob->main_stream, section, strlen (section) + 1);
 
   streamer_write_hwi_stream (ob->main_stream, node->tp_first_run);
 
@@ -546,6 +545,7 @@ lto_output_node (struct lto_simple_outpu
   bp_pack_enum (&bp, ld_plugin_symbol_resolution,
 	        LDPR_NUM_KNOWN, node->resolution);
   streamer_write_bitpack (&bp);
+  lto_output_data_stream (ob->main_stream, section, strlen (section) + 1);
 
   if (node->thunk.thunk_p && !boundary_p)
     {
@@ -1006,13 +1006,13 @@ read_identifier (struct lto_input_block
   return id;
 }
 
-/* Return identifier encoded in IB as a plain string.  */
+/* Return string encoded in IB, NULL if string is empty.  */
 
-static tree
-read_string_cst (struct lto_input_block *ib)
+static const char *
+read_string (struct lto_input_block *ib)
 {
   unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
-  tree id;
+  const char *str;
 
   if (ib->data[ib->p + len])
     lto_section_overrun (ib);
@@ -1021,9 +1021,9 @@ read_string_cst (struct lto_input_block
       ib->p++;
       return NULL;
     }
-  id = build_string (len, ib->data + ib->p);
+  str = ib->data + ib->p;
   ib->p += len + 1;
-  return id;
+  return str;
 }
 
 /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
@@ -1116,7 +1116,7 @@ input_node (struct lto_file_decl_data *f
   int order;
   int i, count;
   tree group;
-  tree section;
+  const char *section;
 
   order = streamer_read_hwi (ib) + order_base;
   clone_ref = streamer_read_hwi (ib);
@@ -1165,7 +1165,6 @@ input_node (struct lto_file_decl_data *f
   group = read_identifier (ib);
   if (group)
     ref2 = streamer_read_hwi (ib);
-  section = read_string_cst (ib);
 
   /* Make sure that we have not read this node before.  Nodes that
      have already been read will have their tag stored in the 'aux'
@@ -1192,6 +1191,7 @@ input_node (struct lto_file_decl_data *f
     }
   else
     node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
+  section = read_string (ib);
   if (section)
     node->set_section_for_node (section);
 
@@ -1226,7 +1226,7 @@ input_varpool_node (struct lto_file_decl
   int ref = LCC_NOT_FOUND;
   int order;
   tree group;
-  tree section;
+  const char *section;
 
   order = streamer_read_hwi (ib) + order_base;
   decl_index = streamer_read_uhwi (ib);
@@ -1275,7 +1275,7 @@ input_varpool_node (struct lto_file_decl
     }
   else
     node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
-  section = read_string_cst (ib);
+  section = read_string (ib);
   if (section)
     node->set_section_for_node (section);
   node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution,
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 211433)
+++ dwarf2out.c	(working copy)
@@ -13614,15 +13614,9 @@ secname_for_decl (const_tree decl)
   if (VAR_OR_FUNCTION_DECL_P (decl)
       && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl) || TREE_STATIC (decl))
       && DECL_SECTION_NAME (decl))
-    {
-      tree sectree = DECL_SECTION_NAME (decl);
-      secname = TREE_STRING_POINTER (sectree);
-    }
+    secname = DECL_SECTION_NAME (decl);
   else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
-    {
-      tree sectree = DECL_SECTION_NAME (current_function_decl);
-      secname = TREE_STRING_POINTER (sectree);
-    }
+    secname = DECL_SECTION_NAME (current_function_decl);
   else if (cfun && in_cold_section_p)
     secname = crtl->subsections.cold_section_label;
   else
Index: ada/gcc-interface/utils.c
===================================================================
--- ada/gcc-interface/utils.c	(revision 211433)
+++ ada/gcc-interface/utils.c	(working copy)
@@ -2476,9 +2476,7 @@ process_attributes (tree *node, struct a
       case ATTR_LINK_SECTION:
 	if (targetm_common.have_named_sections)
 	  {
-	    tree name = build_string (IDENTIFIER_LENGTH (attr->name),
-				      IDENTIFIER_POINTER (attr->name));
-	    set_decl_section_name (*node, name);
+	    set_decl_section_name (*node, attr->name);
 	    DECL_COMMON (*node) = 0;
 	  }
 	else
Index: asan.c
===================================================================
--- asan.c	(revision 211434)
+++ asan.c	(working copy)
@@ -1288,7 +1288,7 @@ asan_protect_global (tree decl)
 	 into user section from multiple TUs are then assumed
 	 to be an array of such vars, putting padding in there
 	 breaks this assumption.  */
-      || (DECL_SECTION_NAME (decl) != NULL_TREE
+      || (DECL_SECTION_NAME (decl) != NULL
 	  && !symtab_get_node (decl)->implicit_section)
       || DECL_SIZE (decl) == 0
       || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT



More information about the Gcc-patches mailing list