From a82892595bc3b2a84b13455711a609138dbcb052 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 12 Nov 2009 17:21:59 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++++++++++ gcc/cgraph.h | 1 + gcc/cgraphunit.c | 1 + gcc/ipa.c | 18 ++++++++++++++++-- gcc/varpool.c | 10 +++------- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0fe06ac7dfb..d616cb7dc77 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-11-12 Jan Hubicka + + * 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 PR middle-end/41930 diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 016ce9de14c..46fee67e6e3 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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) \ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 7105e59c5ec..377e4353fdb 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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); } diff --git a/gcc/ipa.c b/gcc/ipa.c index 4297ea2f46f..bf8faa95fc9 100644 --- a/gcc/ipa.c +++ b/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; } diff --git a/gcc/varpool.c b/gcc/varpool.c index 8815efda249..90a9ace0ff9 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -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)