summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-16 18:15:17 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-16 18:15:17 +0000
commit7410370bd303fd440cb530bb2fe4fc4c2d944b5d (patch)
treeb9cf407f17bdb390a410566498c603ef34073ef6
parentf369130eb68c3206c86c59ec5bba04d8f79f90df (diff)
downloadgcc-7410370bd303fd440cb530bb2fe4fc4c2d944b5d.tar.gz
* cgraph.h (+varpool_can_remove_if_no_refs): Move here from ...;
when !flag_toplevel_reorder do not remove unless variable is COMDAT or ARTIFICIAL. * ipa.c (varpool_can_remove_if_no_refs): ... here. (cgraph_remove_unreachable_nodes): Only analyzed nodes needs to stay. * cgraphunit.c (cgraph_analyze_functions): Dump varpool, too. * varpool.c (decide_is_variable_needed): Do not handle visibility issues. (varpool_finalize_decl): Likewise. (varpool_remove_unreferenced_decls): Use varpool_mark_needed_node; update outdated comment on DECL_RTL_SET_P check. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166812 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cgraph.h12
-rw-r--r--gcc/cgraphunit.c3
-rw-r--r--gcc/ipa.c13
-rw-r--r--gcc/varpool.c38
5 files changed, 41 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 08258500e77..30a45df910b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2010-11-16 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (+varpool_can_remove_if_no_refs): Move here from ...;
+ when !flag_toplevel_reorder do not remove unless variable is
+ COMDAT or ARTIFICIAL.
+ * ipa.c (varpool_can_remove_if_no_refs): ... here.
+ (cgraph_remove_unreachable_nodes): Only analyzed nodes needs to stay.
+ * cgraphunit.c (cgraph_analyze_functions): Dump varpool, too.
+ * varpool.c (decide_is_variable_needed): Do not handle visibility issues.
+ (varpool_finalize_decl): Likewise.
+ (varpool_remove_unreferenced_decls): Use varpool_mark_needed_node; update
+ outdated comment on DECL_RTL_SET_P check.
+
2010-11-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config/sol2.h (NM_FLAGS): Define.
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 2b7ed4b8985..0334a154824 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -928,6 +928,18 @@ cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node)
return !node->address_taken && cgraph_can_remove_if_no_direct_calls_and_refs_p (node);
}
+/* Return true when function NODE can be removed from callgraph
+ if all direct calls are eliminated. */
+
+static inline bool
+varpool_can_remove_if_no_refs (struct varpool_node *node)
+{
+ return (!node->force_output && !node->used_from_other_partition
+ && (flag_toplevel_reorder || DECL_COMDAT (node->decl)
+ || DECL_ARTIFICIAL (node->decl))
+ && (DECL_COMDAT (node->decl) || !node->externally_visible));
+}
+
/* Return true when all references to VNODE must be visible in ipa_ref_list.
i.e. if the variable is not externally visible or not used in some magic
way (asm statement or such).
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index f98243955b7..dd7c0fbffce 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -943,6 +943,7 @@ cgraph_analyze_functions (void)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n\nInitial ");
dump_cgraph (cgraph_dump_file);
+ dump_varpool (cgraph_dump_file);
}
if (cgraph_dump_file)
@@ -972,6 +973,7 @@ cgraph_analyze_functions (void)
{
fprintf (cgraph_dump_file, "\n\nReclaimed ");
dump_cgraph (cgraph_dump_file);
+ dump_varpool (cgraph_dump_file);
}
bitmap_obstack_release (NULL);
first_analyzed = cgraph_nodes;
@@ -1816,6 +1818,7 @@ cgraph_optimize (void)
{
fprintf (cgraph_dump_file, "\nFinal ");
dump_cgraph (cgraph_dump_file);
+ dump_varpool (cgraph_dump_file);
}
#ifdef ENABLE_CHECKING
verify_cgraph ();
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 1dd85f80c36..3742f84e53b 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -188,16 +188,6 @@ process_references (struct ipa_ref_list *list,
}
}
-/* Return true when function NODE can be removed from callgraph
- if all direct calls are eliminated. */
-
-static inline bool
-varpool_can_remove_if_no_refs (struct varpool_node *node)
-{
- return (!node->force_output && !node->used_from_other_partition
- && (DECL_COMDAT (node->decl) || !node->externally_visible));
-}
-
/* Return true when function can be marked local. */
static bool
@@ -269,7 +259,8 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
{
vnode->next_needed = NULL;
vnode->prev_needed = NULL;
- if (!varpool_can_remove_if_no_refs (vnode))
+ if (vnode->analyzed
+ && !varpool_can_remove_if_no_refs (vnode))
{
vnode->needed = false;
varpool_mark_needed_node (vnode);
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 2a96d796b5e..88226601302 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -331,31 +331,24 @@ varpool_reset_queue (void)
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
@@ -427,11 +420,6 @@ varpool_finalize_decl (tree decl)
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 ();
}
@@ -557,18 +545,14 @@ varpool_remove_unreferenced_decls (void)
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;