On Mon, Jun 2, 2014 at 5:15 PM, Ilya Enkovich <enkovich....@gmail.com> wrote: > Hi, > > In the most case we follow transparent alias chains wne assemble names. But > in some cases it is not performed. For instrumented functions it is critical > and following patch fixes that. It also adds a visibility inheritance for > instrtumented functions.
It feels like this should be handled by the symtab code nowadays ... Honza? Richard. > Bootstrapped and tested on linux-x86_64. > > Thanks, > Ilya > -- > gcc/ > > 2014-06-02 Ilya Enkovich <ilya.enkov...@intel.com> > > * varasm.c: Include tree-chkp.h. > (ultimate_transparent_alias_target): Move up. > (make_decl_rtl): For instrumented function use > name of the original decl. > (assemble_start_function): Mark function as global > in case it is instrumentation clone of the global > function. > (do_assemble_alias): Follow transparent alias chain > for identifier. Check if original alias is public. > (maybe_assemble_visibility): Use visibility of the > original function for instrumented version. > (default_unique_section): Likewise. > > > diff --git a/gcc/varasm.c b/gcc/varasm.c > index fcae2fa..d473bc7 100644 > --- a/gcc/varasm.c > +++ b/gcc/varasm.c > @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see > #include "pointer-set.h" > #include "asan.h" > #include "basic-block.h" > +#include "tree-chkp.h" > > #ifdef XCOFF_DEBUGGING_INFO > #include "xcoffout.h" /* Needed for external data > @@ -1200,6 +1201,30 @@ use_blocks_for_decl_p (tree decl) > return targetm.use_blocks_for_decl_p (decl); > } > > +/* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at *ALIAS > + until we find an identifier that is not itself a transparent alias. > + Modify the alias passed to it by reference (and all aliases on the > + way to the ultimate target), such that they do not have to be > + followed again, and return the ultimate target of the alias > + chain. */ > + > +static inline tree > +ultimate_transparent_alias_target (tree *alias) > +{ > + tree target = *alias; > + > + if (IDENTIFIER_TRANSPARENT_ALIAS (target)) > + { > + gcc_assert (TREE_CHAIN (target)); > + target = ultimate_transparent_alias_target (&TREE_CHAIN (target)); > + gcc_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target) > + && ! TREE_CHAIN (target)); > + *alias = target; > + } > + > + return target; > +} > + > /* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL. DECL should > have static storage duration. In other words, it should not be an > automatic variable, including PARM_DECLs. > @@ -1214,6 +1239,7 @@ make_decl_rtl (tree decl) > { > const char *name = 0; > int reg_number; > + tree id; > rtx x; > > /* Check that we are not being given an automatic variable. */ > @@ -1271,7 +1297,12 @@ make_decl_rtl (tree decl) > return; > } > > - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); > + id = DECL_ASSEMBLER_NAME (decl); > + if (TREE_CODE (decl) == FUNCTION_DECL > + && cgraph_get_node (decl) > + && cgraph_get_node (decl)->instrumentation_clone) > + ultimate_transparent_alias_target (&id); > + name = IDENTIFIER_POINTER (id); > > if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL > && DECL_REGISTER (decl)) > @@ -1699,7 +1730,10 @@ assemble_start_function (tree decl, const char *fnname) > > /* Make function name accessible from other files, if appropriate. */ > > - if (TREE_PUBLIC (decl)) > + if (TREE_PUBLIC (decl) > + || (cgraph_get_node (decl)->instrumentation_clone > + && cgraph_get_node (decl)->instrumented_version > + && TREE_PUBLIC (cgraph_get_node > (decl)->instrumented_version->decl))) > { > notice_global_symbol (decl); > > @@ -2386,30 +2420,6 @@ mark_decl_referenced (tree decl) > } > > > -/* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at *ALIAS > - until we find an identifier that is not itself a transparent alias. > - Modify the alias passed to it by reference (and all aliases on the > - way to the ultimate target), such that they do not have to be > - followed again, and return the ultimate target of the alias > - chain. */ > - > -static inline tree > -ultimate_transparent_alias_target (tree *alias) > -{ > - tree target = *alias; > - > - if (IDENTIFIER_TRANSPARENT_ALIAS (target)) > - { > - gcc_assert (TREE_CHAIN (target)); > - target = ultimate_transparent_alias_target (&TREE_CHAIN (target)); > - gcc_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target) > - && ! TREE_CHAIN (target)); > - *alias = target; > - } > - > - return target; > -} > - > /* Output to FILE (an assembly file) a reference to NAME. If NAME > starts with a *, the rest of NAME is output verbatim. Otherwise > NAME is transformed in a target-specific way (usually by the > @@ -5544,6 +5554,9 @@ vec<alias_pair, va_gc> *alias_pairs; > void > do_assemble_alias (tree decl, tree target) > { > + tree orig_decl = decl; > + tree id; > + > /* Emulated TLS had better not get this var. */ > gcc_assert (!(!targetm.have_tls > && TREE_CODE (decl) == VAR_DECL > @@ -5552,12 +5565,21 @@ do_assemble_alias (tree decl, tree target) > if (TREE_ASM_WRITTEN (decl)) > return; > > + if (TREE_CODE (decl) == FUNCTION_DECL > + && cgraph_get_node (decl)->instrumentation_clone > + && cgraph_get_node (decl)->instrumented_version) > + orig_decl = cgraph_get_node (decl)->instrumented_version->decl; > + > + id = DECL_ASSEMBLER_NAME (decl); > + ultimate_transparent_alias_target (&id); > + > /* We must force creation of DECL_RTL for debug info generation, even > though > we don't use it here. */ > make_decl_rtl (decl); > > TREE_ASM_WRITTEN (decl) = 1; > TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1; > + TREE_ASM_WRITTEN (id) = 1; > > if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) > { > @@ -5568,7 +5590,7 @@ do_assemble_alias (tree decl, tree target) > > #ifdef ASM_OUTPUT_WEAKREF > ASM_OUTPUT_WEAKREF (asm_out_file, decl, > - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), > + IDENTIFIER_POINTER (id), > IDENTIFIER_POINTER (target)); > #else > if (!TARGET_SUPPORTS_WEAK) > @@ -5584,7 +5606,7 @@ do_assemble_alias (tree decl, tree target) > #ifdef ASM_OUTPUT_DEF > /* Make name accessible from other files, if appropriate. */ > > - if (TREE_PUBLIC (decl)) > + if (TREE_PUBLIC (decl) || TREE_PUBLIC (orig_decl)) > { > globalize_decl (decl); > maybe_assemble_visibility (decl); > @@ -5594,7 +5616,7 @@ do_assemble_alias (tree decl, tree target) > #if defined (ASM_OUTPUT_TYPE_DIRECTIVE) > if (targetm.has_ifunc_p ()) > ASM_OUTPUT_TYPE_DIRECTIVE > - (asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), > + (asm_out_file, IDENTIFIER_POINTER (id), > IFUNC_ASM_TYPE); > else > #endif > @@ -5606,7 +5628,7 @@ do_assemble_alias (tree decl, tree target) > ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target); > # else > ASM_OUTPUT_DEF (asm_out_file, > - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), > + IDENTIFIER_POINTER (id), > IDENTIFIER_POINTER (target)); > # endif > #elif defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL) > @@ -5614,7 +5636,7 @@ do_assemble_alias (tree decl, tree target) > const char *name; > tree *p, t; > > - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); > + name = IDENTIFIER_POINTER (id); > # ifdef ASM_WEAKEN_DECL > ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target)); > # else > @@ -5623,7 +5645,8 @@ do_assemble_alias (tree decl, tree target) > /* Remove this function from the pending weak list so that > we do not emit multiple .weak directives for it. */ > for (p = &weak_decls; (t = *p) ; ) > - if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t))) > + if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t)) > + || id == DECL_ASSEMBLER_NAME (TREE_VALUE (t))) > *p = TREE_CHAIN (t); > else > p = &TREE_CHAIN (t); > @@ -5632,8 +5655,7 @@ do_assemble_alias (tree decl, tree target) > list, for the same reason. */ > for (p = &weakref_targets; (t = *p) ; ) > { > - if (DECL_ASSEMBLER_NAME (decl) > - == ultimate_transparent_alias_target (&TREE_VALUE (t))) > + if (id == ultimate_transparent_alias_target (&TREE_VALUE (t))) > *p = TREE_CHAIN (t); > else > p = &TREE_CHAIN (t); > @@ -5899,6 +5921,12 @@ maybe_assemble_visibility (tree decl) > { > enum symbol_visibility vis = DECL_VISIBILITY (decl); > > + if (TREE_CODE (decl) == FUNCTION_DECL > + && cgraph_get_node (decl) > + && cgraph_get_node (decl)->instrumentation_clone > + && cgraph_get_node (decl)->instrumented_version) > + vis = DECL_VISIBILITY (cgraph_get_node > (decl)->instrumented_version->decl); > + > if (vis != VISIBILITY_DEFAULT) > { > targetm.asm_out.assemble_visibility (decl, vis); > @@ -6463,6 +6491,7 @@ default_unique_section (tree decl, int reloc) > bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP; > const char *prefix, *name, *linkonce; > char *string; > + tree id; > > switch (categorize_decl_for_section (decl, reloc)) > { > @@ -6512,7 +6541,9 @@ default_unique_section (tree decl, int reloc) > gcc_unreachable (); > } > > - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); > + id = DECL_ASSEMBLER_NAME (decl); > + ultimate_transparent_alias_target (&id); > + name = IDENTIFIER_POINTER (id); > name = targetm.strip_name_encoding (name); > > /* If we're using one_only, then there needs to be a .gnu.linkonce