* cgraph.h (cgraph_only_called_directly_p,
cgraph_can_remove_if_no_direct_calls_p): test address_taken flag.
(cgraph_can_remove_if_no_direct_calls_and_refs_p): New function.
* cgraphunit.c (cgraph_mark_functions_to_output): Test address_taken.
(assemble
* ipa.c (cgraph_remove_unreachable_nodes): Use
cgraph_can_remove_if_no_direct_calls_and_refs_p; clear address_taken flags.
* tree-inline.c (copy_bb): Check address_taken flag.
* tree-profile.c (tree_gen_ic_func_profiler): Check address_taken and
externally_visible flag.
* tree-ssa/unreachable.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159354
138bc75d-0d04-0410-961f-
82ee72b054a4
+2010-05-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_mark_address_taken_node): No longer imply needed flag.
+ * cgraph.h (cgraph_only_called_directly_p,
+ cgraph_can_remove_if_no_direct_calls_p): test address_taken flag.
+ (cgraph_can_remove_if_no_direct_calls_and_refs_p): New function.
+ * cgraphunit.c (cgraph_mark_functions_to_output): Test address_taken.
+ (assemble
+ * ipa.c (cgraph_remove_unreachable_nodes): Use
+ cgraph_can_remove_if_no_direct_calls_and_refs_p; clear address_taken flags.
+ * tree-inline.c (copy_bb): Check address_taken flag.
+ * tree-profile.c (tree_gen_ic_func_profiler): Check address_taken and
+ externally_visible flag.
+
2010-05-12 Jason Merrill <jason@redhat.com>
PR bootstrap/44048
void
cgraph_mark_address_taken_node (struct cgraph_node *node)
{
+ cgraph_mark_reachable_node (node);
node->address_taken = 1;
- cgraph_mark_needed_node (node);
}
/* Return local info for the compiled function. */
static inline bool
cgraph_only_called_directly_p (struct cgraph_node *node)
{
- return !node->needed && !node->local.externally_visible;
+ return !node->needed && !node->address_taken && !node->local.externally_visible;
}
/* Return true when function NODE can be removed from callgraph
if all direct calls are eliminated. */
static inline bool
-cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node)
+cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
{
return (!node->needed && !node->reachable_from_other_partition
&& (DECL_COMDAT (node->decl) || !node->local.externally_visible));
}
+/* Return true when function NODE can be removed from callgraph
+ if all direct calls are eliminated. */
+
+static inline bool
+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);
+}
+
/* Constant pool accessor function. */
htab_t constant_pool_htab (void);
if (node->analyzed
&& !node->global.inlined_to
&& (node->needed || node->reachable_from_other_partition
+ || node->address_taken
|| (e && node->reachable))
&& !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
#endif
varpool_reset_queue ();
for (node = cgraph_nodes; node; node = node->next)
- if (!cgraph_can_remove_if_no_direct_calls_p (node)
+ if (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
&& ((!DECL_EXTERNAL (node->decl))
|| before_inlining_p))
{
varpool_remove_node (vnode);
}
}
+ if (file)
+ fprintf (file, "\nClearing address taken flags:");
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->address_taken
+ && !node->reachable_from_other_partition)
+ {
+ int i;
+ struct ipa_ref *ref;
+ bool found = false;
+ for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref)
+ && !found; i++)
+ found = true;
+ if (!found)
+ {
+ if (file)
+ fprintf (file, " %s", cgraph_node_name (node));
+ node->address_taken = false;
+ }
+ }
#ifdef ENABLE_CHECKING
verify_cgraph ();
+2010-05-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa/unreachable.c: New test.
+
2010-05-12 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/sfinae1.C: New.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+static void bad_boy()
+{
+}
+int
+main()
+{
+ void *t=(void *)bad_boy;
+ if (!t)
+ return 1;
+ return 0;
+}
+/* { dg-final { scan-tree-dump-not "bad_boy" "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
other cases we hit a bug (incorrect node sharing is the
most common reason for missing edges). */
gcc_assert (dest->needed || !dest->analyzed
+ || dest->address_taken
|| !id->src_node->analyzed);
if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
cgraph_create_edge_including_clones
gimple stmt1, stmt2;
tree tree_uid, cur_func;
- if (!c_node->needed)
+ if (cgraph_only_called_directly_p (c_node))
return;
tree_init_edge_profiler ();