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:
Jan Hubicka 2009-11-12 17:21:59 +01:00 committed by Jan Hubicka
parent 06bd7f563b
commit a82892595b
5 changed files with 32 additions and 9 deletions

View File

@ -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

View File

@ -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) \

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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)