cgraph.h (varpool_node_name): Declare.
* cgraph.h (varpool_node_name): Declare. * cgraphunit.c (process_function_and_variable_attributes): Set force_output flag on used variables. * ipa.c (function_and_variable_visibility): Dump externally visible and needed variables. * varpool.c (varpool_node_name): Export. (decide_is_variable_needed): Check COMDAT for externally visible vars; ignore needed flag. From-SVN: r154121
This commit is contained in:
parent
06bd7f563b
commit
a82892595b
5 changed files with 32 additions and 9 deletions
|
@ -1,3 +1,14 @@
|
|||
2009-11-12 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraph.h (varpool_node_name): Declare.
|
||||
* cgraphunit.c (process_function_and_variable_attributes): Set force_output
|
||||
flag on used variables.
|
||||
* ipa.c (function_and_variable_visibility): Dump externally visible and needed
|
||||
variables.
|
||||
* varpool.c (varpool_node_name): Export.
|
||||
(decide_is_variable_needed): Check COMDAT for externally visible vars;
|
||||
ignore needed flag.
|
||||
|
||||
2009-11-12 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR middle-end/41930
|
||||
|
|
|
@ -531,6 +531,7 @@ bool varpool_assemble_decl (struct varpool_node *node);
|
|||
bool varpool_analyze_pending_decls (void);
|
||||
void varpool_remove_unreferenced_decls (void);
|
||||
void varpool_empty_needed_queue (void);
|
||||
const char * varpool_node_name (struct varpool_node *node);
|
||||
|
||||
/* Walk all reachable static variables. */
|
||||
#define FOR_EACH_STATIC_VARIABLE(node) \
|
||||
|
|
|
@ -884,6 +884,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
|
|||
if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
|
||||
{
|
||||
mark_decl_referenced (decl);
|
||||
vnode->force_output = true;
|
||||
if (vnode->finalized)
|
||||
varpool_mark_needed_node (vnode);
|
||||
}
|
||||
|
|
18
gcc/ipa.c
18
gcc/ipa.c
|
@ -292,7 +292,8 @@ function_and_variable_visibility (bool whole_program)
|
|||
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
{
|
||||
gcc_assert (!DECL_WEAK (node->decl) || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
|
||||
gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
|
||||
|| TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
|
||||
if (cgraph_externally_visible_p (node, whole_program))
|
||||
{
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
|
@ -317,7 +318,7 @@ function_and_variable_visibility (bool whole_program)
|
|||
{
|
||||
if (!vnode->finalized)
|
||||
continue;
|
||||
gcc_assert ((!DECL_WEAK (vnode->decl) || DECL_COMMON (vnode->decl))
|
||||
gcc_assert ((!DECL_WEAK (vnode->decl) && !DECL_COMMON (vnode->decl) && !DECL_COMDAT (vnode->decl))
|
||||
|| TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (node->decl));
|
||||
if (vnode->needed
|
||||
&& (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
|
||||
|
@ -352,6 +353,11 @@ function_and_variable_visibility (bool whole_program)
|
|||
if (node->local.externally_visible)
|
||||
fprintf (dump_file, " %s", cgraph_node_name (node));
|
||||
fprintf (dump_file, "\n\n");
|
||||
fprintf (dump_file, "\nMarking externally visible variables:");
|
||||
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
|
||||
if (vnode->externally_visible)
|
||||
fprintf (dump_file, " %s", varpool_node_name (vnode));
|
||||
fprintf (dump_file, "\n\n");
|
||||
}
|
||||
cgraph_function_flags_ready = true;
|
||||
return 0;
|
||||
|
@ -410,6 +416,14 @@ whole_program_function_and_variable_visibility (void)
|
|||
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
|
||||
if (vnode->externally_visible && !DECL_COMDAT (vnode->decl))
|
||||
varpool_mark_needed_node (vnode);
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "\nNeeded variables:");
|
||||
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
|
||||
if (vnode->needed)
|
||||
fprintf (dump_file, " %s", varpool_node_name (vnode));
|
||||
fprintf (dump_file, "\n\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ static GTY(()) struct varpool_node *varpool_first_unanalyzed_node;
|
|||
static GTY(()) struct varpool_node *varpool_assembled_nodes_queue;
|
||||
|
||||
/* Return name of the node used in debug output. */
|
||||
static const char *
|
||||
const char *
|
||||
varpool_node_name (struct varpool_node *node)
|
||||
{
|
||||
return lang_hooks.decl_printable_name (node->decl, 2);
|
||||
|
@ -229,7 +229,8 @@ bool
|
|||
decide_is_variable_needed (struct varpool_node *node, tree decl)
|
||||
{
|
||||
/* If the user told us it is used, then it must be so. */
|
||||
if (node->externally_visible || node->force_output)
|
||||
if ((node->externally_visible && !DECL_COMDAT (decl))
|
||||
|| node->force_output)
|
||||
return true;
|
||||
|
||||
/* ??? If the assembler name is set by hand, it is possible to assemble
|
||||
|
@ -239,11 +240,6 @@ decide_is_variable_needed (struct varpool_node *node, tree decl)
|
|||
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|
||||
return true;
|
||||
|
||||
/* If we decided it was needed before, but at the time we didn't have
|
||||
the definition available, then it's still needed. */
|
||||
if (node->needed)
|
||||
return true;
|
||||
|
||||
/* Externally visible variables must be output. The exception is
|
||||
COMDAT variables that must be output only when they are needed. */
|
||||
if (TREE_PUBLIC (decl)
|
||||
|
|
Loading…
Add table
Reference in a new issue