+
+ /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO.
+ This is because very little of code knows that assembler name needs to
+ mangled. Avoid touching declarations with user asm name set to mask
+ some of the problems. */
+ if (DECL_ASSEMBLER_NAME_SET_P (vnode->decl)
+ && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (vnode->decl))[0]=='*')
+ return true;
+
+ if (DECL_PRESERVE_P (vnode->decl))
+ return true;
+ if (lookup_attribute ("externally_visible",
+ DECL_ATTRIBUTES (vnode->decl)))
+ return true;
+ if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+ && lookup_attribute ("dllexport",
+ DECL_ATTRIBUTES (vnode->decl)))
+ return true;
+
+ /* See if we have linker information about symbol not being used or
+ if we need to make guess based on the declaration.
+
+ Even if the linker clams the symbol is unused, never bring internal
+ symbols that are declared by user as used or externally visible.
+ This is needed for i.e. references from asm statements. */
+ if (varpool_used_from_object_file_p (vnode))
+ return true;
+ for (alias = vnode->extra_name; alias; alias = alias->next)
+ if (alias->resolution != LDPR_PREVAILING_DEF_IRONLY)
+ break;
+ if (!alias && 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,
+ so this does not enable more optimization, but referring static var
+ is faster for dynamic linking. Also this match logic hidding vtables
+ from LTO symbol tables. */
+ if ((in_lto_p || flag_whole_program)
+ && !vnode->force_output
+ && DECL_COMDAT (vnode->decl) && DECL_VIRTUAL_P (vnode->decl))
+ return false;
+
+ /* When doing link time optimizations, hidden symbols become local. */
+ if (in_lto_p
+ && (DECL_VISIBILITY (vnode->decl) == VISIBILITY_HIDDEN
+ || DECL_VISIBILITY (vnode->decl) == VISIBILITY_INTERNAL)
+ /* Be sure that node is defined in IR file, not in other object
+ file. In that case we don't set used_from_other_object_file. */
+ && vnode->finalized)
+ ;
+ else if (!flag_whole_program)
+ return true;
+
+ /* Do not attempt to privatize COMDATS by default.
+ This would break linking with C++ libraries sharing
+ inline definitions.
+
+ FIXME: We can do so for readonly vars with no address taken and
+ possibly also for vtables since no direct pointer comparsion is done.
+ It might be interesting to do so to reduce linking overhead. */
+ if (DECL_COMDAT (vnode->decl) || DECL_WEAK (vnode->decl))