On Wed, 28 Sep 2011, Jan Hubicka wrote:

> Hi,
> this patch adds support for V2 plugin API (thanks, Cary) that adds
> LDPR_PREVAILING_DEF_IRONLY_EXP.
> The reoslution is like LDPR_PREVAILING_DEF_IRONLY but the symbol is exported
> out of DSO.  It is up to the compiler to optimize it out or keep it based on
> the knowledge whether the symbol can be optimized out at all (i.e. most 
> COMDATs
> can, other types can't).
> 
> This solve quite few problems with building C++ APPS, see the PR log.
> 
> I was originally wrong about gold implementation being buggy. The problem 
> turned
> out to be subtle lto-symtab bug that was mostly latent because of the COMDAT 
> hack
> we use. lto_symtab_resolve_symbols is supposed to honor plugin decision when 
> it is
> available but it doesn't when resolution of very first entry in the list is 
> UNKNOWN.
> This can happen because we add into symtab also declarations that are not in
> varpool (i.e. they are neither defined or used by the object file), but they 
> are
> used otherwise, i.e. referred from stuff used for debug info or TB 
> devirtualization.
> 
> To ensure backward compatibility I am keeping the COMDAT hack in place.  It 
> won't help
> letting compiler know the plugin API version, since we decide on that at a 
> time
> we output object files and thus we are not called from plugin.  I suppose we 
> could
> keep the hack in place for next release and remove it afterwards penalizing 
> builds
> with old binutils? Or perhaps even in GCC 4.7 if GNU LD gets updated in time.
> 
> Bootstrapped/regtested x86_64-linux, built Mozilla and lto-bootstrap in 
> progress.
> OK if it passes?

Ok.

Any idea when GNU ld will catch up?

Thanks,
Richard.

> Honza
> 
>       PR lto/47247
>       * lto-plugin.c (get_symbols_v2): New variable.
>       (write_resolution): Use V2 API when available.
>       (onload): Handle LDPT_GET_SYMBOLS_V2.
> 
>       * lto-symtab.c (lto_symtab_resolve_symbols): Do not resolve
>       when resolution is already availbale from plugin.
>       (lto_symtab_merge_decls_1): Handle LDPR_PREVAILING_DEF_IRONLY_EXP.
>       * cgraph.c (ld_plugin_symbol_resolution): Add prevailing_def_ironly_exp.
>       * lto-cgraph.c (LDPR_NUM_KNOWN): Update.
>       * ipa.c (varpool_externally_visible_p): IRONLY variables are never
>       externally visible.
>       * varasm.c (resolution_to_local_definition_p): Add
>       LDPR_PREVAILING_DEF_IRONLY_EXP.
>       (resolution_local_p): Likewise.
> 
>       * common.c (lto_resolution_str): Add new resolution.
>       * common.h (lto_resolution_str): Likewise.
> Index: lto-plugin/lto-plugin.c
> ===================================================================
> *** lto-plugin/lto-plugin.c   (revision 179274)
> --- lto-plugin/lto-plugin.c   (working copy)
> *************** enum symbol_style
> *** 129,135 ****
>   static char *arguments_file_name;
>   static ld_plugin_register_claim_file register_claim_file;
>   static ld_plugin_register_all_symbols_read register_all_symbols_read;
> ! static ld_plugin_get_symbols get_symbols;
>   static ld_plugin_register_cleanup register_cleanup;
>   static ld_plugin_add_input_file add_input_file;
>   static ld_plugin_add_input_library add_input_library;
> --- 129,135 ----
>   static char *arguments_file_name;
>   static ld_plugin_register_claim_file register_claim_file;
>   static ld_plugin_register_all_symbols_read register_all_symbols_read;
> ! static ld_plugin_get_symbols get_symbols, get_symbols_v2;
>   static ld_plugin_register_cleanup register_cleanup;
>   static ld_plugin_add_input_file add_input_file;
>   static ld_plugin_add_input_library add_input_library;
> *************** write_resolution (void)
> *** 441,447 ****
>         struct plugin_symtab *symtab = &info->symtab;
>         struct ld_plugin_symbol *syms = symtab->syms;
>   
> !       get_symbols (info->handle, symtab->nsyms, syms);
>   
>         finish_conflict_resolution (symtab, &info->conflicts);
>   
> --- 441,452 ----
>         struct plugin_symtab *symtab = &info->symtab;
>         struct ld_plugin_symbol *syms = symtab->syms;
>   
> !       /* Version 2 of API supports IRONLY_EXP resolution that is
> !          accepted by GCC-4.7 and newer.  */
> !       if (get_symbols_v2)
> !         get_symbols_v2 (info->handle, symtab->nsyms, syms);
> !       else
> !         get_symbols (info->handle, symtab->nsyms, syms);
>   
>         finish_conflict_resolution (symtab, &info->conflicts);
>   
> *************** onload (struct ld_plugin_tv *tv)
> *** 986,991 ****
> --- 991,999 ----
>       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
>         register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
>         break;
> +     case LDPT_GET_SYMBOLS_V2:
> +       get_symbols_v2 = p->tv_u.tv_get_symbols;
> +       break;
>       case LDPT_GET_SYMBOLS:
>         get_symbols = p->tv_u.tv_get_symbols;
>         break;
> Index: gcc/lto-symtab.c
> ===================================================================
> *** gcc/lto-symtab.c  (revision 179274)
> --- gcc/lto-symtab.c  (working copy)
> *************** lto_symtab_resolve_symbols (void **slot)
> *** 441,452 ****
>       e->node = cgraph_get_node (e->decl);
>         else if (TREE_CODE (e->decl) == VAR_DECL)
>       e->vnode = varpool_get_node (e->decl);
>       }
>   
> -   e = (lto_symtab_entry_t) *slot;
> - 
>     /* If the chain is already resolved there is nothing else to do.  */
> !   if (e->resolution != LDPR_UNKNOWN)
>       return;
>   
>     /* Find the single non-replaceable prevailing symbol and
> --- 444,457 ----
>       e->node = cgraph_get_node (e->decl);
>         else if (TREE_CODE (e->decl) == VAR_DECL)
>       e->vnode = varpool_get_node (e->decl);
> +       if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
> +       || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
> +       || e->resolution == LDPR_PREVAILING_DEF)
> +     prevailing = e;
>       }
>   
>     /* If the chain is already resolved there is nothing else to do.  */
> !   if (prevailing)
>       return;
>   
>     /* Find the single non-replaceable prevailing symbol and
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 586,591 ****
> --- 591,597 ----
>     for (prevailing = (lto_symtab_entry_t) *slot;
>          prevailing
>          && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY
> +        && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP
>          && prevailing->resolution != LDPR_PREVAILING_DEF;
>          prevailing = prevailing->next)
>       ;
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 595,600 ****
> --- 601,607 ----
>       for (e = prevailing->next; e; e = e->next)
>         {
>       if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
> +         || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
>           || e->resolution == LDPR_PREVAILING_DEF)
>         fatal_error ("multiple prevailing defs for %qE",
>                      DECL_NAME (prevailing->decl));
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 685,693 ****
>        to handle UNKNOWN relocation well.
>   
>        The problem with storing guessed decision is whether to use
> !      PREVAILING_DEF or PREVAILING_DEF_IRONLY.  First one would disable
> !      some whole program optimizations, while ther second would imply
> !      to many whole program assumptions.  */
>     if (prevailing->node && !flag_ltrans && !prevailing->guessed)
>       prevailing->node->resolution = prevailing->resolution;
>     else if (prevailing->vnode && !flag_ltrans && !prevailing->guessed)
> --- 692,700 ----
>        to handle UNKNOWN relocation well.
>   
>        The problem with storing guessed decision is whether to use
> !      PREVAILING_DEF, PREVAILING_DEF_IRONLY, PREVAILING_DEF_IRONLY_EXP.
> !      First one would disable some whole program optimizations, while
> !      ther second would imply to many whole program assumptions.  */
>     if (prevailing->node && !flag_ltrans && !prevailing->guessed)
>       prevailing->node->resolution = prevailing->resolution;
>     else if (prevailing->vnode && !flag_ltrans && !prevailing->guessed)
> Index: gcc/cgraph.c
> ===================================================================
> *** gcc/cgraph.c      (revision 179274)
> --- gcc/cgraph.c      (working copy)
> *************** const char * const ld_plugin_symbol_reso
> *** 110,116 ****
>     "preempted_ir",
>     "resolved_ir",
>     "resolved_exec",
> !   "resolved_dyn"
>   };
>   
>   static void cgraph_node_remove_callers (struct cgraph_node *node);
> --- 110,117 ----
>     "preempted_ir",
>     "resolved_ir",
>     "resolved_exec",
> !   "resolved_dyn",
> !   "prevailing_def_ironly_exp"
>   };
>   
>   static void cgraph_node_remove_callers (struct cgraph_node *node);
> Index: gcc/lto-cgraph.c
> ===================================================================
> *** gcc/lto-cgraph.c  (revision 179274)
> --- gcc/lto-cgraph.c  (working copy)
> *************** static void output_cgraph_opt_summary (c
> *** 52,58 ****
>   static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes);
>   
>   /* Number of LDPR values known to GCC.  */
> ! #define LDPR_NUM_KNOWN (LDPR_RESOLVED_DYN + 1)
>   
>   /* Cgraph streaming is organized as set of record whose type
>      is indicated by a tag.  */
> --- 52,58 ----
>   static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes);
>   
>   /* Number of LDPR values known to GCC.  */
> ! #define LDPR_NUM_KNOWN (LDPR_PREVAILING_DEF_IRONLY_EXP + 1)
>   
>   /* Cgraph streaming is organized as set of record whose type
>      is indicated by a tag.  */
> Index: gcc/ipa.c
> ===================================================================
> *** gcc/ipa.c (revision 179274)
> --- gcc/ipa.c (working copy)
> *************** varpool_externally_visible_p (struct var
> *** 685,690 ****
> --- 688,695 ----
>        This is needed for i.e. references from asm statements.   */
>     if (varpool_used_from_object_file_p (vnode))
>       return true;
> +   if (vnode->resolution == LDPR_PREVAILING_DEF_IRONLY)
> +     return false;
>   
>     /* As a special case, the COMDAT virutal tables can be unshared.
>        In LTO mode turn vtables into static variables.  The variable is 
> readonly,
> Index: gcc/lto/common.c
> ===================================================================
> *** gcc/lto/common.c  (revision 179274)
> --- gcc/lto/common.c  (working copy)
> *************** const char *lto_visibility_str[4] __attr
> *** 31,37 ****
>    "INTERNAL", "HIDDEN"
>   };
>   
> ! const char *lto_resolution_str[9] __attribute__ ((visibility ("hidden"))) =
>   {
>     "UNKNOWN",
>     "UNDEF",
> --- 31,37 ----
>    "INTERNAL", "HIDDEN"
>   };
>   
> ! const char *lto_resolution_str[10] __attribute__ ((visibility ("hidden"))) =
>   {
>     "UNKNOWN",
>     "UNDEF",
> *************** const char *lto_resolution_str[9] __attr
> *** 41,46 ****
>     "PREEMPTED_IR",
>     "RESOLVED_IR",
>     "RESOLVED_EXEC",
> !   "RESOLVED_DYN"
>   };
>   
> --- 41,47 ----
>     "PREEMPTED_IR",
>     "RESOLVED_IR",
>     "RESOLVED_EXEC",
> !   "RESOLVED_DYN",
> !   "PREVAILING_DEF_IRONLY_EXP",
>   };
>   
> Index: gcc/lto/common.h
> ===================================================================
> *** gcc/lto/common.h  (revision 179274)
> --- gcc/lto/common.h  (working copy)
> *************** along with GCC; see the file COPYING3.
> *** 20,26 ****
>   
>   
>   
> ! static const char *lto_resolution_str[9] =
>   {
>     "UNKNOWN",
>     "UNDEF",
> --- 20,26 ----
>   
>   
>   
> ! static const char *lto_resolution_str[10] =
>   {
>     "UNKNOWN",
>     "UNDEF",
> *************** static const char *lto_resolution_str[9]
> *** 30,34 ****
>     "PREEMPTED_IR",
>     "RESOLVED_IR",
>     "RESOLVED_EXEC",
> !   "RESOLVED_DYN"
>   };
> --- 30,35 ----
>     "PREEMPTED_IR",
>     "RESOLVED_IR",
>     "RESOLVED_EXEC",
> !   "RESOLVED_DYN",
> !   "PREVAILING_DEF_IRONLY_EXP",
>   };
> Index: gcc/varasm.c
> ===================================================================
> *** gcc/varasm.c      (revision 179274)
> --- gcc/varasm.c      (working copy)
> *************** static bool
> *** 6681,6686 ****
> --- 6681,6687 ----
>   resolution_to_local_definition_p (enum ld_plugin_symbol_resolution 
> resolution)
>   {
>     return (resolution == LDPR_PREVAILING_DEF
> +       || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
>         || resolution == LDPR_PREVAILING_DEF_IRONLY);
>   }
>   
> *************** resolution_local_p (enum ld_plugin_symbo
> *** 6692,6697 ****
> --- 6693,6699 ----
>   {
>     return (resolution == LDPR_PREVAILING_DEF
>         || resolution == LDPR_PREVAILING_DEF_IRONLY
> +       || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
>         || resolution == LDPR_PREEMPTED_REG
>         || resolution == LDPR_PREEMPTED_IR
>         || resolution == LDPR_RESOLVED_IR
> 
> 

-- 
Richard Guenther <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer

Reply via email to