On Mon, Jun 9, 2014 at 4:34 AM, Jan Hubicka <hubi...@ucw.cz> wrote:
> Hi,
> this patch follows the change to move DECL_COMDAT_GROUP by moving 
> DECL_SECTION_NAME
> into symtab nodes instead of keeping it in decl_with_vis. (I pla to proceed 
> with
> other symbol table related fields).
>
> It follows exactly same path as the previous patch. Notable change is adding
> of node removal into duplicate_decl in c-decl.c.
>
> Memory usage wise the patch is small win for non-WPA, at WPA we actually
> consume bit more memory (about 800K on Firefox).  We have more symtab nodes
> than declarations because of inline clonning.  This will be solved by fixing
> memory representation of symbol nodes (I plan to move rare items into on side
> hashtables).  With accessors API it should be easy.

What I wondered about for some time is why 'clones' need to use the
same structs as their origins.  They share some bits with their origin
and they apply some changes.  Thus I think it would be nice to change
the inheritance of a symtab entry to sth like

  symbol - cgraph-node-base - cgraph-node
     |                                      \
     |                                       cgraph-clone
     varpool-node-base - varpool-node
                                 \
                                  varpool-clone (do we have those?)

Richard.

> Bootstrapped/regtested x86_64-linux, slightly earlier version of patch was
> tested also at PPC (linux/AIX)
>
> Honza
>
>         * symtab.c (dump_symtab_base): Update dumping.
>         (symtab_make_decl_local): Clear only DECL_COMDAT.
>         * tree-vect-data-refs.c (Check that variable is static before
>         tampering with sections.
>         * cgraphclones.c (duplicate_thunk_for_node): Do not clear section 
> name.
>         (cgraph_create_virtual_clone): Likewise.
>         * tree.c (decl_comdat_group, decl_comdat_group_id): Constify argument.
>         (decl_section_name, set_decl_section_name): New accessors.
>         (find_decls_types_r): Do not walk section name
>         * tree.h (DECL_SECTION_NAME): Implement using
>         decl_section_name.
>         (decl_comdat_group, decl_comdat_group_id): Constify.
>         (decl_section_name, set_decl_section_name): Update.
>         * varpool.c (varpool_finalize_named_section_flags): Use
>         get_section.
>         * cgraph.c (cgraph_add_thunk): Reset node instead of rebuilding.
>         (cgraph_make_node_local_1): Clear section and comdat group.
>         * cgraph.h (set_comdat_group): Sanity check.
>         (get_section, set_section): New.
>         * ipa-comdats.c (ipa_comdats): Use get_section.
>         * ipa.c (ipa_discover_readonly_nonaddressable_var): Likewise.
>         * lto-streamer-out.c: Do not follow section names.
>         * c-family/c-common.c (handle_section_attribute):
>         Update.
>         * lto-cgraph.c (lto_output_node): Output section.
>         (lto_output_varpool_node): Likewise.
>         (read_comdat_group): Rename to ...
>         (read_identifier): ... this one.
>         (read_string_cst): New function.
>         (input_node, input_varpool_node): Input section names.
>         * tree-emutls.c (get_emutls_init_templ_addr): Update.
>         (new_emutls_decl): Update.
>         (secname_for_decl): Check section names only of static
>         vars.
>         * config/mep/mep.c (mep_unique_section): Use set_decl_section_name.
>         * config/i386/winnt.c (i386_pe_unique_section): Likewise.
>         * config/i386/i386.c (x86_64_elf_unique_section): Likewise.
>         * config/c6x/c6x.c (c6x_elf_unique_section): Likewise.
>         * config/rs6000/rs6000.c (rs6000_xcoff_unique_section): Likewise.
>         * config/mcore/mcore.c (mcore_unique_section): Likewise.
>         * config/mips/mips.c (mips16_build_function_stub): Likewise.
>         * config/v850/v850.c (v850_insert_attributes): Likewise.
>         * config/h8300/h8300.c: (h8300_handle_eightbit_data_attribute):
>         Likewise.
>         (h8300_handle_tiny_data_attribute): Likewise.
>         * config/bfin/bfin.c (bfin_handle_l1_text_attribute): Likewise.
>         (bfin_handle_l2_attribute): Likewise.
>
>         * lto.c (mentions_vars_p_decl_with_vis, compare_tree_sccs_1,
>         lto_fixup_prevailing_decls): Skip section names.
>
>         * go/go-gcc.cc (global_variable_set_init): Use
>         set_decl_section_name.
>         * tree-streamer-in.c (lto_input_ts_decl_with_vis_tree_pointers): Do 
> not read section name.
>
>         * gcc-interface/utils.c (process_attributes): Use it.
>
>         * c-decl.c (merge_decls): Use set_decl_section_name.
>         (duplicate_decls): Remove node if it exists.
>
>         * class.c (build_utf8_ref): Use set_decl_section_name.
>         (emit_register_classes_in_jcr_section): Likewise.
>         (emit_register_classes_in_jcr_section): Likewise.
>
>         * method.c (use_thunk): Use set_decl_section_name.
>         * optimize.c (maybe_clone_body): Use set_decl_section_name.
>         * decl.c (duplicate_decls): Likewise.
>         * vtable-class-hierarchy.c: Likewise.
> Index: ipa-visibility.c
> ===================================================================
> --- ipa-visibility.c    (revision 211362)
> +++ ipa-visibility.c    (working copy)
> @@ -512,6 +512,7 @@ function_and_variable_visibility (bool w
>                      next = next->same_comdat_group)
>                 {
>                   next->set_comdat_group (NULL);
> +                 next->set_section (NULL);
>                   symtab_make_decl_local (next->decl);
>                   next->unique_name = ((next->resolution == 
> LDPR_PREVAILING_DEF_IRONLY
>                                         || next->unique_name
> @@ -526,6 +527,8 @@ function_and_variable_visibility (bool w
>             }
>           if (TREE_PUBLIC (node->decl))
>             node->set_comdat_group (NULL);
> +         if (DECL_COMDAT (node->decl))
> +           node->set_section (NULL);
>           symtab_make_decl_local (node->decl);
>         }
>
> @@ -643,6 +646,7 @@ function_and_variable_visibility (bool w
>                      next = next->same_comdat_group)
>                 {
>                   next->set_comdat_group (NULL);
> +                 next->set_section (NULL);
>                   symtab_make_decl_local (next->decl);
>                   next->unique_name = ((next->resolution == 
> LDPR_PREVAILING_DEF_IRONLY
>                                         || next->unique_name
> @@ -653,6 +657,8 @@ function_and_variable_visibility (bool w
>             }
>           if (TREE_PUBLIC (vnode->decl))
>             vnode->set_comdat_group (NULL);
> +         if (DECL_COMDAT (vnode->decl))
> +           vnode->set_section (NULL);
>           symtab_make_decl_local (vnode->decl);
>           vnode->resolution = LDPR_PREVAILING_DEF_IRONLY;
>         }
> Index: c-family/c-common.c
> ===================================================================
> --- c-family/c-common.c (revision 211362)
> +++ c-family/c-common.c (working copy)
> @@ -7442,7 +7442,7 @@ handle_section_attribute (tree *node, tr
>               *no_add_attrs = true;
>             }
>           else
> -           DECL_SECTION_NAME (decl) = TREE_VALUE (args);
> +           set_decl_section_name (decl, TREE_VALUE (args));
>         }
>        else
>         {
> Index: java/class.c
> ===================================================================
> --- java/class.c        (revision 211362)
> +++ 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));
> -         DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
> +         set_decl_section_name (decl, build_string (strlen (buf), buf));
>         }
>      }
>
> @@ -2805,8 +2805,6 @@ emit_register_classes_in_jcr_section (vo
>    cdecl = build_decl (UNKNOWN_LOCATION,
>                       VAR_DECL, get_identifier ("_Jv_JCR_SECTION_data"),
>                       class_array_type);
> -  DECL_SECTION_NAME (cdecl) = build_string (strlen (JCR_SECTION_NAME),
> -                                           JCR_SECTION_NAME);
>    DECL_ALIGN (cdecl) = POINTER_SIZE;
>    DECL_USER_ALIGN (cdecl) = 1;
>    DECL_INITIAL (cdecl) = build_constructor (class_array_type, init);
> @@ -2817,6 +2815,8 @@ 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));
>    pushdecl_top_level (cdecl);
>    relayout_decl (cdecl);
>    rest_of_decl_compilation (cdecl, 1, 0);
> Index: c/c-decl.c
> ===================================================================
> --- c/c-decl.c  (revision 211362)
> +++ c/c-decl.c  (working copy)
> @@ -2304,8 +2304,10 @@ merge_decls (tree newdecl, tree olddecl,
>          We want to issue an error if the sections conflict but that
>          must be done later in decl_attributes since we are called
>          before attributes are assigned.  */
> -      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
> -       DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
> +      if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC 
> (olddecl))
> +         && DECL_SECTION_NAME (newdecl) == NULL_TREE
> +         && DECL_SECTION_NAME (olddecl))
> +       set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl));
>
>        /* Copy the assembler name.
>          Currently, it can only be defined in the prototype.  */
> @@ -2574,6 +2576,13 @@ duplicate_decls (tree newdecl, tree oldd
>    merge_decls (newdecl, olddecl, newtype, oldtype);
>
>    /* The NEWDECL will no longer be needed.  */
> +  if (TREE_CODE (newdecl) == FUNCTION_DECL
> +      || TREE_CODE (newdecl) == VAR_DECL)
> +    {
> +      struct symtab_node *snode = symtab_get_node (newdecl);
> +      if (snode)
> +       symtab_remove_node (snode);
> +    }
>    ggc_free (newdecl);
>    return true;
>  }
> Index: cgraph.c
> ===================================================================
> --- cgraph.c    (revision 211362)
> +++ cgraph.c    (working copy)
> @@ -641,14 +641,9 @@ cgraph_add_thunk (struct cgraph_node *de
>
>    node = cgraph_get_node (alias);
>    if (node)
> -    {
> -      gcc_assert (node->definition);
> -      gcc_assert (!node->alias);
> -      gcc_assert (!node->thunk.thunk_p);
> -      cgraph_remove_node (node);
> -    }
> -
> -  node = cgraph_create_node (alias);
> +    cgraph_reset_node (node);
> +  else
> +    node = cgraph_create_node (alias);
>    gcc_checking_assert (!virtual_offset
>                        || wi::eq_p (virtual_offset, virtual_value));
>    node->thunk.fixed_offset = fixed_offset;
> @@ -2264,6 +2259,8 @@ cgraph_make_node_local_1 (struct cgraph_
>      {
>        symtab_make_decl_local (node->decl);
>
> +      node->set_section (NULL);
> +      node->set_comdat_group (NULL);
>        node->externally_visible = false;
>        node->forced_by_abi = false;
>        node->local.local = true;
> Index: cgraph.h
> ===================================================================
> --- cgraph.h    (revision 211362)
> +++ cgraph.h    (working copy)
> @@ -157,9 +157,24 @@ public:
>    /* Set comdat group.  */
>    void set_comdat_group (tree group)
>      {
> +      gcc_checking_assert (!group || TREE_CODE (group) == IDENTIFIER_NODE
> +                          || DECL_P (group));
>        comdat_group_ = group;
>      }
>
> +  /* Return section.  */
> +  tree get_section ()
> +    {
> +      return section_;
> +    }
> +
> +  /* Set section.  */
> +  void set_section (tree section)
> +    {
> +      gcc_checking_assert (!section || TREE_CODE (section) == STRING_CST);
> +      section_ = section;
> +    }
> +
>    /* Vectors of referring and referenced entities.  */
>    struct ipa_ref_list ref_list;
>
> @@ -175,6 +190,9 @@ public:
>
>    /* Comdat group the symbol is in.  Can be private if GGC allowed that.  */
>    tree comdat_group_;
> +
> +  /* Section name. Again can be private, if allowed.  */
> +  tree section_;
>  };
>
>  enum availability
> Index: tree.c
> ===================================================================
> --- tree.c      (revision 211362)
> +++ tree.c      (working copy)
> @@ -608,7 +608,7 @@ decl_assembler_name (tree decl)
>     DECL is associated with.  This can be either an IDENTIFIER_NODE or a
>     decl, in which case its DECL_ASSEMBLER_NAME identifies the group.  */
>  tree
> -decl_comdat_group (tree node)
> +decl_comdat_group (const_tree node)
>  {
>    struct symtab_node *snode = symtab_get_node (node);
>    if (!snode)
> @@ -618,7 +618,7 @@ decl_comdat_group (tree node)
>
>  /* Likewise, but make sure it's been reduced to an IDENTIFIER_NODE.  */
>  tree
> -decl_comdat_group_id (tree node)
> +decl_comdat_group_id (const_tree node)
>  {
>    struct symtab_node *snode = symtab_get_node (node);
>    if (!snode)
> @@ -626,6 +626,37 @@ decl_comdat_group_id (tree node)
>    return snode->get_comdat_group_id ();
>  }
>
> +/* When the target supports named section, return its name as IDENTIFIER_NODE
> +   or NULL if it is in no section.  */
> +tree
> +decl_section_name (const_tree node)
> +{
> +  struct symtab_node *snode = symtab_get_node (node);
> +  if (!snode)
> +    return NULL;
> +  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)
> +{
> +  struct symtab_node *snode;
> +
> +  if (value == NULL)
> +    {
> +      snode = symtab_get_node (node);
> +      if (!snode)
> +       return;
> +    }
> +  else if (TREE_CODE (node) == VAR_DECL)
> +    snode = varpool_node_for_decl (node);
> +  else
> +    snode = cgraph_get_create_node (node);
> +  snode->set_section (value);
> +}
> +
>  /* Compute the number of bytes occupied by a tree with code CODE.
>     This function cannot be used for nodes that have variable sizes,
>     including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR.  */
> @@ -5264,10 +5295,6 @@ find_decls_types_r (tree *tp, int *ws, v
>           fld_worklist_push (DECL_FIELD_BIT_OFFSET (t), fld);
>           fld_worklist_push (DECL_FCONTEXT (t), fld);
>         }
> -      else if (TREE_CODE (t) == VAR_DECL)
> -       {
> -         fld_worklist_push (DECL_SECTION_NAME (t), fld);
> -       }
>
>        if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL)
>           && DECL_HAS_VALUE_EXPR_P (t))
> Index: tree.h
> ===================================================================
> --- tree.h      (revision 211362)
> +++ tree.h      (working copy)
> @@ -2368,8 +2368,7 @@ extern void decl_value_expr_insert (tree
>
>  /* Records the section name in a section attribute.  Used to pass
>     the name from decl_attributes to make_function_rtl and make_decl_rtl.  */
> -#define DECL_SECTION_NAME(NODE) \
> -  (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.section_name)
> +#define DECL_SECTION_NAME(NODE) decl_section_name (NODE)
>
>  /* Nonzero in a decl means that the gimplifier has seen (or placed)
>     this variable in a BIND_EXPR.  */
> @@ -3431,8 +3430,10 @@ tree_operand_check_code (const_tree __t,
>     || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
>
>  extern tree decl_assembler_name (tree);
> -extern tree decl_comdat_group (tree);
> -extern tree decl_comdat_group_id (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);
>
>  /* 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 211362)
> +++ tree-emutls.c       (working copy)
> @@ -245,7 +245,6 @@ get_emutls_init_templ_addr (tree decl)
>    TREE_READONLY (to) = 1;
>    DECL_IGNORED_P (to) = 1;
>    DECL_CONTEXT (to) = DECL_CONTEXT (decl);
> -  DECL_SECTION_NAME (to) = DECL_SECTION_NAME (decl);
>    DECL_PRESERVE_P (to) = DECL_PRESERVE_P (decl);
>
>    DECL_WEAK (to) = DECL_WEAK (decl);
> @@ -265,10 +264,13 @@ get_emutls_init_templ_addr (tree decl)
>
>    if (targetm.emutls.tmpl_section)
>      {
> -      DECL_SECTION_NAME (to)
> -        = build_string (strlen (targetm.emutls.tmpl_section),
> -                       targetm.emutls.tmpl_section);
> +      set_decl_section_name
> +       (to,
> +         build_string (strlen (targetm.emutls.tmpl_section),
> +                      targetm.emutls.tmpl_section));
>      }
> +  else
> +    set_decl_section_name (to, DECL_SECTION_NAME (decl));
>
>    /* Create varpool node for the new variable and finalize it if it is
>       not external one.  */
> @@ -323,9 +325,10 @@ 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)
>      {
> -      DECL_SECTION_NAME (to)
> -        = build_string (strlen (targetm.emutls.var_section),
> -                       targetm.emutls.var_section);
> +      set_decl_section_name
> +        (to,
> +         build_string (strlen (targetm.emutls.var_section),
> +                      targetm.emutls.var_section));
>      }
>
>    /* If this variable is defined locally, then we need to initialize the
> Index: cp/optimize.c
> ===================================================================
> --- cp/optimize.c       (revision 211362)
> +++ cp/optimize.c       (working copy)
> @@ -476,7 +476,6 @@ maybe_clone_body (tree fn)
>          to it. By doing so, it also corrupted the comdat group. */
>        if (DECL_ONE_ONLY (fn))
>         cgraph_get_create_node (clone)->set_comdat_group (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);
>        DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
> @@ -487,6 +486,7 @@ maybe_clone_body (tree fn)
>        DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
>        DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
>        DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS 
> (fn);
> +      set_decl_section_name (clone, DECL_SECTION_NAME (fn));
>
>        /* Adjust the parameter names and locations.  */
>        parm = DECL_ARGUMENTS (fn);
> Index: cp/decl.c
> ===================================================================
> --- cp/decl.c   (revision 211362)
> +++ cp/decl.c   (working copy)
> @@ -2019,8 +2019,10 @@ duplicate_decls (tree newdecl, tree oldd
>          We want to issue an error if the sections conflict but that must be
>          done later in decl_attributes since we are called before attributes
>          are assigned.  */
> -      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
> -       DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
> +      if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC 
> (olddecl))
> +         && DECL_SECTION_NAME (newdecl) == NULL_TREE
> +         && DECL_SECTION_NAME (olddecl) != NULL_TREE)
> +       set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl));
>
>        if (TREE_CODE (newdecl) == FUNCTION_DECL)
>         {
> Index: cp/method.c
> ===================================================================
> --- cp/method.c (revision 211362)
> +++ cp/method.c (working copy)
> @@ -363,7 +363,7 @@ use_thunk (tree thunk_fndecl, bool emit_
>           resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
>
>           /* Output the thunk into the same section as function.  */
> -         DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
> +         set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (function));
>         }
>      }
>
> Index: cp/vtable-class-hierarchy.c
> ===================================================================
> --- cp/vtable-class-hierarchy.c (revision 211362)
> +++ cp/vtable-class-hierarchy.c (working copy)
> @@ -1247,8 +1247,8 @@ 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.  */
>
> -      DECL_SECTION_NAME (var_decl) = build_string (strlen 
> (".vtable_map_vars"),
> -                                                   ".vtable_map_vars");
> +      set_decl_section_name (var_decl, build_string (strlen 
> (".vtable_map_vars"),
> +                                                     ".vtable_map_vars"));
>        DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl) = true;
>        DECL_INITIAL (var_decl) = initial_value;
>
> Index: lto-cgraph.c
> ===================================================================
> --- lto-cgraph.c        (revision 211362)
> +++ lto-cgraph.c        (working copy)
> @@ -396,6 +396,7 @@ lto_output_node (struct lto_simple_outpu
>    int i;
>    bool alias_p;
>    const char *comdat;
> +  const char *section;
>    tree group;
>
>    boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
> @@ -486,6 +487,7 @@ lto_output_node (struct lto_simple_outpu
>    else
>      comdat = "";
>    lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);
> +
>    if (group)
>      {
>        if (node->same_comdat_group && !boundary_p)
> @@ -499,6 +501,13 @@ lto_output_node (struct lto_simple_outpu
>        streamer_write_hwi_stream (ob->main_stream, ref);
>      }
>
> +  group = node->get_section ();
> +  if (group)
> +    section = TREE_STRING_POINTER (group);
> +  else
> +    section = "";
> +  lto_output_data_stream (ob->main_stream, section, strlen (section) + 1);
> +
>    streamer_write_hwi_stream (ob->main_stream, node->tp_first_run);
>
>    bp = bitpack_create (ob->main_stream);
> @@ -563,6 +572,7 @@ lto_output_varpool_node (struct lto_simp
>    int ref;
>    bool alias_p;
>    const char *comdat;
> +  const char *section;
>    tree group;
>
>    streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
> @@ -600,12 +610,14 @@ lto_output_varpool_node (struct lto_simp
>           /* in_other_partition.  */
>      }
>    streamer_write_bitpack (&bp);
> +
>    group = node->get_comdat_group ();
>    if (group)
>      comdat = IDENTIFIER_POINTER (group);
>    else
>      comdat = "";
>    lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);
> +
>    if (group)
>      {
>        if (node->same_comdat_group && !boundary_p)
> @@ -618,6 +630,14 @@ lto_output_varpool_node (struct lto_simp
>         ref = LCC_NOT_FOUND;
>        streamer_write_hwi_stream (ob->main_stream, ref);
>      }
> +
> +  group = node->get_section ();
> +  if (group)
> +    section = TREE_STRING_POINTER (group);
> +  else
> +    section = "";
> +  lto_output_data_stream (ob->main_stream, section, strlen (section) + 1);
> +
>    streamer_write_enum (ob->main_stream, ld_plugin_symbol_resolution,
>                        LDPR_NUM_KNOWN, node->resolution);
>  }
> @@ -968,13 +988,33 @@ output_symtab (void)
>    output_refs (encoder);
>  }
>
> -/* Return COMDAT_GROUP encoded in IB as a plain string.  */
> +/* Return identifier encoded in IB as a plain string.  */
>
>  static tree
> -read_comdat_group (struct lto_input_block *ib)
> +read_identifier (struct lto_input_block *ib)
>  {
>    unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
> -  tree group;
> +  tree id;
> +
> +  if (ib->data[ib->p + len])
> +    lto_section_overrun (ib);
> +  if (!len)
> +    {
> +      ib->p++;
> +      return NULL;
> +    }
> +  id = get_identifier (ib->data + ib->p);
> +  ib->p += len + 1;
> +  return id;
> +}
> +
> +/* Return identifier encoded in IB as a plain string.  */
> +
> +static tree
> +read_string_cst (struct lto_input_block *ib)
> +{
> +  unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
> +  tree id;
>
>    if (ib->data[ib->p + len])
>      lto_section_overrun (ib);
> @@ -983,9 +1023,9 @@ read_comdat_group (struct lto_input_bloc
>        ib->p++;
>        return NULL;
>      }
> -  group = get_identifier (ib->data + ib->p);
> +  id = build_string (len, ib->data + ib->p);
>    ib->p += len + 1;
> -  return group;
> +  return id;
>  }
>
>  /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
> @@ -1077,6 +1117,7 @@ input_node (struct lto_file_decl_data *f
>    int order;
>    int i, count;
>    tree group;
> +  tree section;
>
>    order = streamer_read_hwi (ib) + order_base;
>    clone_ref = streamer_read_hwi (ib);
> @@ -1122,9 +1163,10 @@ input_node (struct lto_file_decl_data *f
>    if (tag == LTO_symtab_analyzed_node)
>      ref = streamer_read_hwi (ib);
>
> -  group = read_comdat_group (ib);
> +  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'
> @@ -1151,6 +1193,8 @@ input_node (struct lto_file_decl_data *f
>      }
>    else
>      node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
> +  if (section)
> +    node->set_section (section);
>
>    if (node->thunk.thunk_p)
>      {
> @@ -1183,6 +1227,7 @@ input_varpool_node (struct lto_file_decl
>    int ref = LCC_NOT_FOUND;
>    int order;
>    tree group;
> +  tree section;
>
>    order = streamer_read_hwi (ib) + order_base;
>    decl_index = streamer_read_uhwi (ib);
> @@ -1220,7 +1265,7 @@ input_varpool_node (struct lto_file_decl
>      }
>    if (node->alias && !node->analyzed && node->weakref)
>      node->alias_target = get_alias_symbol (node->decl);
> -  group = read_comdat_group (ib);
> +  group = read_identifier (ib);
>    if (group)
>      {
>        node->set_comdat_group (group);
> @@ -1230,6 +1275,9 @@ input_varpool_node (struct lto_file_decl
>      }
>    else
>      node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
> +  section = read_string_cst (ib);
> +  if (section)
> +    node->set_section (section);
>    node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution,
>                                                 LDPR_NUM_KNOWN);
>    gcc_assert (flag_ltrans
> Index: cgraphclones.c
> ===================================================================
> --- cgraphclones.c      (revision 211362)
> +++ cgraphclones.c      (working copy)
> @@ -340,7 +340,6 @@ duplicate_thunk_for_node (cgraph_node *t
>
>    DECL_NAME (new_decl) = clone_function_name (thunk->decl, 
> "artificial_thunk");
>    SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
> -  DECL_SECTION_NAME (new_decl) = NULL;
>
>    new_thunk = cgraph_create_node (new_decl);
>    set_new_clone_decl_and_node_flags (new_thunk);
> @@ -557,8 +556,6 @@ cgraph_create_virtual_clone (struct cgra
>       that is not weak also.
>       ??? We cannot use COMDAT linkage because there is no
>       ABI support for this.  */
> -  if (old_node->get_comdat_group ())
> -    DECL_SECTION_NAME (new_node->decl) = NULL;
>    set_new_clone_decl_and_node_flags (new_node);
>    new_node->clone.tree_map = tree_map;
>    new_node->clone.args_to_skip = args_to_skip;
> Index: lto-streamer-out.c
> ===================================================================
> --- lto-streamer-out.c  (revision 211362)
> +++ lto-streamer-out.c  (working copy)
> @@ -535,7 +535,6 @@ DFS_write_tree_body (struct output_block
>        /* Make sure we don't inadvertently set the assembler name.  */
>        if (DECL_ASSEMBLER_NAME_SET_P (expr))
>         DFS_follow_tree_edge (DECL_ASSEMBLER_NAME (expr));
> -      DFS_follow_tree_edge (DECL_SECTION_NAME (expr));
>      }
>
>    if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
> @@ -973,7 +972,6 @@ hash_tree (struct streamer_tree_cache_d
>      {
>        if (DECL_ASSEMBLER_NAME_SET_P (t))
>         visit (DECL_ASSEMBLER_NAME (t));
> -      visit (DECL_SECTION_NAME (t));
>      }
>
>    if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
> Index: dwarf2out.c
> ===================================================================
> --- dwarf2out.c (revision 211362)
> +++ dwarf2out.c (working copy)
> @@ -13611,7 +13611,9 @@ secname_for_decl (const_tree decl)
>  {
>    const char *secname;
>
> -  if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_SECTION_NAME (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);
> Index: go/go-gcc.cc
> ===================================================================
> --- go/go-gcc.cc        (revision 211362)
> +++ go/go-gcc.cc        (working copy)
> @@ -2376,7 +2376,7 @@ Gcc_backend::global_variable_set_init(Bv
>    // a different one now that DECL_INITIAL is set.
>    if (DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl))
>      {
> -      DECL_SECTION_NAME (var_decl) = NULL_TREE;
> +      set_decl_section_name (var_decl, NULL);
>        resolve_unique_section (var_decl,
>                               compute_reloc_for_constant (expr_tree),
>                               1);
> Index: ada/gcc-interface/utils.c
> ===================================================================
> --- ada/gcc-interface/utils.c   (revision 211362)
> +++ ada/gcc-interface/utils.c   (working copy)
> @@ -2476,9 +2476,9 @@ process_attributes (tree *node, struct a
>        case ATTR_LINK_SECTION:
>         if (targetm_common.have_named_sections)
>           {
> -           DECL_SECTION_NAME (*node)
> -             = build_string (IDENTIFIER_LENGTH (attr->name),
> -                             IDENTIFIER_POINTER (attr->name));
> +           set_decl_section_name (*node,
> +                                  build_string (IDENTIFIER_LENGTH 
> (attr->name),
> +                                                IDENTIFIER_POINTER 
> (attr->name)));
>             DECL_COMMON (*node) = 0;
>           }
>         else
> Index: ipa.c
> ===================================================================
> --- ipa.c       (revision 211362)
> +++ ipa.c       (working copy)
> @@ -714,7 +714,7 @@ ipa_discover_readonly_nonaddressable_var
>             /* Making variable in explicit section readonly can cause section
>                type conflict.
>                See e.g. gcc.c-torture/compile/pr23237.c */
> -           && DECL_SECTION_NAME (vnode->decl) == NULL)
> +           && vnode->get_section () == NULL)
>           {
>             if (!TREE_READONLY (vnode->decl) && dump_file)
>               fprintf (dump_file, " %s (read-only)", vnode->name ());
> Index: tree-vect-data-refs.c
> ===================================================================
> --- tree-vect-data-refs.c       (revision 211362)
> +++ tree-vect-data-refs.c       (working copy)
> @@ -5213,7 +5213,8 @@ vect_can_force_dr_alignment_p (const_tre
>    /* Do not override explicit alignment set by the user when an explicit
>       section name is also used.  This is a common idiom used by many
>       software projects.  */
> -  if (DECL_SECTION_NAME (decl) != NULL_TREE
> +  if (TREE_STATIC (decl)
> +      && DECL_SECTION_NAME (decl) != NULL_TREE
>        && !DECL_HAS_IMPLICIT_SECTION_NAME_P (decl))
>      return false;
>
> Index: lto/lto.c
> ===================================================================
> --- lto/lto.c   (revision 211362)
> +++ lto/lto.c   (working copy)
> @@ -767,7 +767,6 @@ mentions_vars_p_decl_with_vis (tree t)
>
>    /* Accessor macro has side-effects, use field-name here. */
>    CHECK_NO_VAR (t->decl_with_vis.assembler_name);
> -  CHECK_NO_VAR (DECL_SECTION_NAME (t));
>    return false;
>  }
>
> @@ -1529,7 +1528,6 @@ compare_tree_sccs_1 (tree t1, tree t2, t
>        if (DECL_ASSEMBLER_NAME_SET_P (t1))
>         compare_tree_edges (DECL_ASSEMBLER_NAME (t1),
>                             DECL_ASSEMBLER_NAME (t2));
> -      compare_tree_edges (DECL_SECTION_NAME (t1), DECL_SECTION_NAME (t2));
>      }
>
>    if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
> @@ -2718,7 +2716,6 @@ lto_fixup_prevailing_decls (tree t)
>        if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
>         {
>           LTO_NO_PREVAIL (t->decl_with_vis.assembler_name);
> -         LTO_NO_PREVAIL (DECL_SECTION_NAME (t));
>         }
>        if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
>         {
> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c (revision 211362)
> +++ tree-streamer-out.c (working copy)
> @@ -660,8 +660,6 @@ write_ts_decl_with_vis_tree_pointers (st
>      stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
>    else
>      stream_write_tree (ob, NULL_TREE, false);
> -
> -  stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
>  }
>
>
> Index: varasm.c
> ===================================================================
> --- varasm.c    (revision 211362)
> +++ varasm.c    (working copy)
> @@ -1369,6 +1369,7 @@ make_decl_rtl (tree decl)
>       is called early and it needs to make DECL_RTL to get the name.
>       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_INITIAL (decl) == NULL_TREE
>        && DECL_COMMON (decl))
> @@ -6460,7 +6461,7 @@ default_unique_section (tree decl, int r
>
>    string = ACONCAT ((linkonce, prefix, ".", name, NULL));
>
> -  DECL_SECTION_NAME (decl) = build_string (strlen (string), string);
> +  set_decl_section_name (decl, build_string (strlen (string), string));
>  }
>
>  /* Like compute_reloc_for_constant, except for an RTX.  The return value
> Index: ipa-comdats.c
> ===================================================================
> --- ipa-comdats.c       (revision 211362)
> +++ ipa-comdats.c       (working copy)
> @@ -243,7 +243,7 @@ ipa_comdats (void)
>              || symbol->force_output
>              || symbol->used_from_other_partition
>              || TREE_THIS_VOLATILE (symbol->decl)
> -            || DECL_SECTION_NAME (symbol->decl)
> +            || symbol->get_section ()
>              || (TREE_CODE (symbol->decl) == FUNCTION_DECL
>                  && (DECL_STATIC_CONSTRUCTOR (symbol->decl)
>                      || DECL_STATIC_DESTRUCTOR (symbol->decl))))
> Index: tree-streamer-in.c
> ===================================================================
> --- tree-streamer-in.c  (revision 211362)
> +++ tree-streamer-in.c  (working copy)
> @@ -759,8 +759,6 @@ lto_input_ts_decl_with_vis_tree_pointers
>        gcc_assert (TREE_CODE (id) == IDENTIFIER_NODE);
>        SET_DECL_ASSEMBLER_NAME (expr, id);
>      }
> -
> -  DECL_SECTION_NAME (expr) = stream_read_tree (ib, data_in);
>  }
>
>
> Index: symtab.c
> ===================================================================
> --- symtab.c    (revision 211362)
> +++ symtab.c    (working copy)
> @@ -563,9 +563,9 @@ dump_symtab_base (FILE *f, symtab_node *
>              IDENTIFIER_POINTER (node->get_comdat_group_id ()));
>    if (DECL_ONE_ONLY (node->decl))
>      fprintf (f, " one_only");
> -  if (DECL_SECTION_NAME (node->decl))
> -    fprintf (f, " section_name:%s",
> -            TREE_STRING_POINTER (DECL_SECTION_NAME (node->decl)));
> +  if (node->get_section ())
> +    fprintf (f, " section:%s",
> +            TREE_STRING_POINTER (node->get_section ()));
>    if (DECL_VISIBILITY_SPECIFIED (node->decl))
>      fprintf (f, " visibility_specified");
>    if (DECL_VISIBILITY (node->decl))
> @@ -877,11 +877,7 @@ symtab_make_decl_local (tree decl)
>      DECL_COMMON (decl) = 0;
>    else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
>
> -  if (DECL_COMDAT (decl))
> -    {
> -      DECL_SECTION_NAME (decl) = 0;
> -      DECL_COMDAT (decl) = 0;
> -    }
> +  DECL_COMDAT (decl) = 0;
>    DECL_WEAK (decl) = 0;
>    DECL_EXTERNAL (decl) = 0;
>    DECL_VISIBILITY_SPECIFIED (decl) = 0;
> Index: config/mep/mep.c
> ===================================================================
> --- config/mep/mep.c    (revision 211362)
> +++ config/mep/mep.c    (working copy)
> @@ -4658,7 +4658,7 @@ mep_unique_section (tree decl, int reloc
>
>    sprintf (string, "%s%s", prefix, name);
>
> -  DECL_SECTION_NAME (decl) = build_string (len, string);
> +  set_decl_section_name (decl, build_string (len, string));
>  }
>
>  /* Given a decl, a section name, and whether the decl initializer
> Index: config/i386/winnt.c
> ===================================================================
> --- config/i386/winnt.c (revision 211362)
> +++ 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);
>
> -  DECL_SECTION_NAME (decl) = build_string (len, string);
> +  set_decl_section_name (decl, build_string (len, string));
>  }
>
>  /* Local and global relocs can be placed always into readonly memory for
> Index: config/i386/i386.c
> ===================================================================
> --- config/i386/i386.c  (revision 211362)
> +++ config/i386/i386.c  (working copy)
> @@ -5193,7 +5193,7 @@ x86_64_elf_unique_section (tree decl, in
>
>           string = ACONCAT ((linkonce, prefix, ".", name, NULL));
>
> -         DECL_SECTION_NAME (decl) = build_string (strlen (string), string);
> +         set_decl_section_name (decl, build_string (strlen (string), 
> string));
>           return;
>         }
>      }
> Index: config/c6x/c6x.c
> ===================================================================
> --- config/c6x/c6x.c    (revision 211362)
> +++ config/c6x/c6x.c    (working copy)
> @@ -1060,7 +1060,7 @@ c6x_elf_unique_section (tree decl, int r
>
>        string = ACONCAT ((linkonce, prefix, ".", name, NULL));
>
> -      DECL_SECTION_NAME (decl) = build_string (strlen (string), string);
> +      set_decl_section_name (decl, build_string (strlen (string), string));
>        return;
>      }
>    default_unique_section (decl, reloc);
> Index: config/rs6000/rs6000.c
> ===================================================================
> --- config/rs6000/rs6000.c      (revision 211362)
> +++ config/rs6000/rs6000.c      (working copy)
> @@ -29342,7 +29342,7 @@ rs6000_xcoff_unique_section (tree decl,
>
>    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
>    name = (*targetm.strip_name_encoding) (name);
> -  DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
> +  set_decl_section_name (decl, build_string (strlen (name), name));
>  }
>
>  /* Select section for constant in constant pool.
> Index: config/mcore/mcore.c
> ===================================================================
> --- config/mcore/mcore.c        (revision 211362)
> +++ config/mcore/mcore.c        (working copy)
> @@ -3089,7 +3089,7 @@ mcore_unique_section (tree decl, int rel
>
>    sprintf (string, "%s%s", prefix, name);
>
> -  DECL_SECTION_NAME (decl) = build_string (len, string);
> +  set_decl_section_name (decl, build_string (len, string));
>  }
>
>  int
> Index: config/mips/mips.c
> ===================================================================
> --- config/mips/mips.c  (revision 211362)
> +++ 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));
> -  DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
> +  set_decl_section_name (stubdecl, build_string (strlen (secname), 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));
> -      DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), 
> secname);
> +      set_decl_section_name (stubdecl, build_string (strlen (secname), 
> secname));
>        DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
>                                            RESULT_DECL, NULL_TREE,
>                                            void_type_node);
> Index: config/v850/v850.c
> ===================================================================
> --- config/v850/v850.c  (revision 211362)
> +++ config/v850/v850.c  (working copy)
> @@ -2644,7 +2644,7 @@ v850_insert_attributes (tree decl, tree
>           /* Only set the section name if specified by a pragma, because
>              otherwise it will force those variables to get allocated storage
>              in this module, rather than by the linker.  */
> -         DECL_SECTION_NAME (decl) = chosen_section;
> +         set_decl_section_name (decl, chosen_section);
>         }
>      }
>  }
> Index: config/h8300/h8300.c
> ===================================================================
> --- config/h8300/h8300.c        (revision 211362)
> +++ config/h8300/h8300.c        (working copy)
> @@ -5461,7 +5461,7 @@ h8300_handle_eightbit_data_attribute (tr
>
>    if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
>      {
> -      DECL_SECTION_NAME (decl) = build_string (7, ".eight");
> +      set_decl_section_name (decl, build_string (7, ".eight"));
>      }
>    else
>      {
> @@ -5485,7 +5485,7 @@ h8300_handle_tiny_data_attribute (tree *
>
>    if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
>      {
> -      DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
> +      set_decl_section_name (decl, build_string (6, ".tiny"));
>      }
>    else
>      {
> Index: config/bfin/bfin.c
> ===================================================================
> --- config/bfin/bfin.c  (revision 211362)
> +++ config/bfin/bfin.c  (working copy)
> @@ -4769,7 +4769,7 @@ bfin_handle_l1_text_attribute (tree *nod
>        *no_add_attrs = true;
>      }
>    else
> -    DECL_SECTION_NAME (decl) = build_string (9, ".l1.text");
> +    set_decl_section_name (decl, build_string (9, ".l1.text"));
>
>    return NULL_TREE;
>  }
> @@ -4847,7 +4847,7 @@ bfin_handle_l2_attribute (tree *node, tr
>           *no_add_attrs = true;
>         }
>        else
> -       DECL_SECTION_NAME (decl) = build_string (9, ".l2.text");
> +       set_decl_section_name (decl, build_string (9, ".l2.text"));
>      }
>    else if (TREE_CODE (decl) == VAR_DECL)
>      {
> @@ -4860,7 +4860,7 @@ bfin_handle_l2_attribute (tree *node, tr
>           *no_add_attrs = true;
>         }
>        else
> -       DECL_SECTION_NAME (decl) = build_string (9, ".l2.data");
> +       set_decl_section_name (decl, build_string (9, ".l2.data"));
>      }
>
>    return NULL_TREE;
> Index: varpool.c
> ===================================================================
> --- varpool.c   (revision 211362)
> +++ varpool.c   (working copy)
> @@ -582,7 +582,7 @@ varpool_finalize_named_section_flags (va
>        && !DECL_EXTERNAL (node->decl)
>        && TREE_CODE (node->decl) == VAR_DECL
>        && !DECL_HAS_VALUE_EXPR_P (node->decl)
> -      && DECL_SECTION_NAME (node->decl))
> +      && node->get_section ())
>      get_variable_section (node->decl, false);
>  }
>

Reply via email to