/* Callgraph handling code.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
Free Software Foundation, Inc.
Contributed by Jan Hubicka
fprintf (f, " output");
if (node->externally_visible)
fprintf (f, " externally_visible");
+ if (node->resolution != LDPR_UNKNOWN)
+ fprintf (f, " %s",
+ ld_plugin_symbol_resolution_names[(int)node->resolution]);
if (node->in_other_partition)
fprintf (f, " in_other_partition");
else if (node->used_from_other_partition)
bool
decide_is_variable_needed (struct varpool_node *node, tree decl)
{
- if (node->used_from_other_partition)
- return true;
/* If the user told us it is used, then it must be so. */
- if ((node->externally_visible && !DECL_COMDAT (decl))
- || node->force_output)
+ if (node->force_output)
return true;
+ gcc_assert (!DECL_EXTERNAL (decl));
+
/* Externally visible variables must be output. The exception is
COMDAT variables that must be output only when they are needed. */
if (TREE_PUBLIC (decl)
- && !flag_whole_program
- && !flag_lto
&& !DECL_COMDAT (decl)
&& !DECL_EXTERNAL (decl))
return true;
/* When not reordering top level variables, we have to assume that
we are going to keep everything. */
- if (flag_toplevel_reorder)
- return false;
-
- /* We want to emit COMDAT variables only when absolutely necessary. */
- if (DECL_COMDAT (decl))
- return false;
- return true;
+ if (!flag_toplevel_reorder)
+ return true;
+ return false;
}
/* Return if DECL is constant and its initial value is known (so we can do
gcc_assert (TREE_CODE (decl) == VAR_DECL);
- if (!TREE_READONLY (decl))
+ if (!TREE_READONLY (decl) || TREE_THIS_VOLATILE (decl))
return false;
/* Gimplifier takes away constructors of local vars */
if (decide_is_variable_needed (node, decl))
varpool_mark_needed_node (node);
- /* Since we reclaim unreachable nodes at the end of every language
- level unit, we need to be conservative about possible entry points
- there. */
- else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
- varpool_mark_needed_node (node);
if (cgraph_global_info_ready)
varpool_assemble_pending_decls ();
}
while (node)
{
- tree decl = node->decl;
next = node->next_needed;
node->needed = 0;
- if (node->finalized
- && (decide_is_variable_needed (node, decl)
- /* ??? Cgraph does not yet rule the world with an iron hand,
- and does not control the emission of debug information.
- After a variable has its DECL_RTL set, we must assume that
- it may be referenced by the debug information, and we can
- no longer elide it. */
- || DECL_RTL_SET_P (decl)))
+ if (node->analyzed
+ && (!varpool_can_remove_if_no_refs (node)
+ /* We just expanded all function bodies. See if any of
+ them needed the variable. */
+ || DECL_RTL_SET_P (node->decl)))
varpool_mark_needed_node (node);
node = next;
varpool_analyze_pending_decls ();
}
+/* For variables in named sections make sure get_variable_section
+ is called before we switch to those sections. Then section
+ conflicts between read-only and read-only requiring relocations
+ sections can be resolved. */
+void
+varpool_finalize_named_section_flags (struct varpool_node *node)
+{
+ if (!TREE_ASM_WRITTEN (node->decl)
+ && !node->alias
+ && !node->in_other_partition
+ && !DECL_EXTERNAL (node->decl)
+ && TREE_CODE (node->decl) == VAR_DECL
+ && !DECL_HAS_VALUE_EXPR_P (node->decl)
+ && DECL_SECTION_NAME (node->decl))
+ get_variable_section (node->decl, false);
+}
+
/* Output all variables enqueued to be assembled. */
bool
varpool_assemble_pending_decls (void)
{
bool changed = false;
+ struct varpool_node *node;
if (seen_error ())
return false;
elsewhere. */
varpool_analyze_pending_decls ();
+ for (node = varpool_nodes_queue; node; node = node->next_needed)
+ varpool_finalize_named_section_flags (node);
+
while (varpool_nodes_queue)
{
struct varpool_node *node = varpool_nodes_queue;