diff options
author | Jan Hubicka <jh@suse.cz> | 2010-05-13 08:13:46 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-05-13 06:13:46 +0000 |
commit | bd3cdcc0872c2ce75d82ecc5a426cb3ace641d0f (patch) | |
tree | eb2005967068c3a8ec31dce8fb4dc415f37fe993 /gcc | |
parent | 73647d75199a9e5c8a0e2e049d1f70b86d43c8f4 (diff) | |
download | gcc-bd3cdcc0872c2ce75d82ecc5a426cb3ace641d0f.zip gcc-bd3cdcc0872c2ce75d82ecc5a426cb3ace641d0f.tar.gz gcc-bd3cdcc0872c2ce75d82ecc5a426cb3ace641d0f.tar.bz2 |
cgraph.c (cgraph_mark_address_taken_node): No longer imply needed flag.
* 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.
* tree-ssa/unreachable.c: New test.
From-SVN: r159354
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cgraph.c | 2 | ||||
-rw-r--r-- | gcc/cgraph.h | 13 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 1 | ||||
-rw-r--r-- | gcc/ipa.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/unreachable.c | 15 | ||||
-rw-r--r-- | gcc/tree-inline.c | 1 | ||||
-rw-r--r-- | gcc/tree-profile.c | 2 |
9 files changed, 68 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0decfd8..f6b1554 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +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 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index b16a10d..82ce0e8 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1686,8 +1686,8 @@ cgraph_mark_needed_node (struct cgraph_node *node) 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. */ diff --git a/gcc/cgraph.h b/gcc/cgraph.h index dbfc89f..1ccae09 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -856,19 +856,28 @@ varpool_node_set_nonempty_p (varpool_node_set set) 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); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index cacb90c..b97a33e 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1201,6 +1201,7 @@ cgraph_mark_functions_to_output (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)) @@ -207,7 +207,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) #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)) { @@ -405,6 +405,25 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) 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 (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e62336b..8f18143 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +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. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/unreachable.c b/gcc/testsuite/gcc.dg/tree-ssa/unreachable.c new file mode 100644 index 0000000..279a277 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/unreachable.c @@ -0,0 +1,15 @@ +/* { 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" } } */ diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 302d36b..03b013c 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1711,6 +1711,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, 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 diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index a907510..6c2d1bd 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -345,7 +345,7 @@ tree_gen_ic_func_profiler (void) 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 (); |