Commit a8289259 by Jan Hubicka Committed by Jan Hubicka

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
parent 06bd7f56
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> 2009-11-12 Uros Bizjak <ubizjak@gmail.com>
PR middle-end/41930 PR middle-end/41930
...@@ -531,6 +531,7 @@ bool varpool_assemble_decl (struct varpool_node *node); ...@@ -531,6 +531,7 @@ bool varpool_assemble_decl (struct varpool_node *node);
bool varpool_analyze_pending_decls (void); bool varpool_analyze_pending_decls (void);
void varpool_remove_unreferenced_decls (void); void varpool_remove_unreferenced_decls (void);
void varpool_empty_needed_queue (void); void varpool_empty_needed_queue (void);
const char * varpool_node_name (struct varpool_node *node);
/* Walk all reachable static variables. */ /* Walk all reachable static variables. */
#define FOR_EACH_STATIC_VARIABLE(node) \ #define FOR_EACH_STATIC_VARIABLE(node) \
......
...@@ -884,6 +884,7 @@ process_function_and_variable_attributes (struct cgraph_node *first, ...@@ -884,6 +884,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
{ {
mark_decl_referenced (decl); mark_decl_referenced (decl);
vnode->force_output = true;
if (vnode->finalized) if (vnode->finalized)
varpool_mark_needed_node (vnode); varpool_mark_needed_node (vnode);
} }
......
...@@ -292,7 +292,8 @@ function_and_variable_visibility (bool whole_program) ...@@ -292,7 +292,8 @@ function_and_variable_visibility (bool whole_program)
for (node = cgraph_nodes; node; node = node->next) 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)) if (cgraph_externally_visible_p (node, whole_program))
{ {
gcc_assert (!node->global.inlined_to); gcc_assert (!node->global.inlined_to);
...@@ -317,7 +318,7 @@ function_and_variable_visibility (bool whole_program) ...@@ -317,7 +318,7 @@ function_and_variable_visibility (bool whole_program)
{ {
if (!vnode->finalized) if (!vnode->finalized)
continue; 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)); || TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (node->decl));
if (vnode->needed if (vnode->needed
&& (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl)) && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
...@@ -352,6 +353,11 @@ function_and_variable_visibility (bool whole_program) ...@@ -352,6 +353,11 @@ function_and_variable_visibility (bool whole_program)
if (node->local.externally_visible) if (node->local.externally_visible)
fprintf (dump_file, " %s", cgraph_node_name (node)); fprintf (dump_file, " %s", cgraph_node_name (node));
fprintf (dump_file, "\n\n"); 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; cgraph_function_flags_ready = true;
return 0; return 0;
...@@ -410,6 +416,14 @@ whole_program_function_and_variable_visibility (void) ...@@ -410,6 +416,14 @@ whole_program_function_and_variable_visibility (void)
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed) for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
if (vnode->externally_visible && !DECL_COMDAT (vnode->decl)) if (vnode->externally_visible && !DECL_COMDAT (vnode->decl))
varpool_mark_needed_node (vnode); 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; return 0;
} }
......
...@@ -80,7 +80,7 @@ static GTY(()) struct varpool_node *varpool_first_unanalyzed_node; ...@@ -80,7 +80,7 @@ static GTY(()) struct varpool_node *varpool_first_unanalyzed_node;
static GTY(()) struct varpool_node *varpool_assembled_nodes_queue; static GTY(()) struct varpool_node *varpool_assembled_nodes_queue;
/* Return name of the node used in debug output. */ /* Return name of the node used in debug output. */
static const char * const char *
varpool_node_name (struct varpool_node *node) varpool_node_name (struct varpool_node *node)
{ {
return lang_hooks.decl_printable_name (node->decl, 2); return lang_hooks.decl_printable_name (node->decl, 2);
...@@ -229,7 +229,8 @@ bool ...@@ -229,7 +229,8 @@ bool
decide_is_variable_needed (struct varpool_node *node, tree decl) decide_is_variable_needed (struct varpool_node *node, tree decl)
{ {
/* If the user told us it is used, then it must be so. */ /* 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; return true;
/* ??? If the assembler name is set by hand, it is possible to assemble /* ??? 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) ...@@ -239,11 +240,6 @@ decide_is_variable_needed (struct varpool_node *node, tree decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
return true; 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 /* Externally visible variables must be output. The exception is
COMDAT variables that must be output only when they are needed. */ COMDAT variables that must be output only when they are needed. */
if (TREE_PUBLIC (decl) if (TREE_PUBLIC (decl)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment