diff options
author | Jan Hubicka <jh@suse.cz> | 2013-08-19 12:14:06 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-08-19 10:14:06 +0000 |
commit | eefe9a995ceec7fc5ca79505e96bda214e6bd82c (patch) | |
tree | 6500dfce0eb1776cd3cf03771e785f6de3bc1607 /gcc/cgraphunit.c | |
parent | 5eb5ec2f3034a1c62262914b090f64a5d5f0bc86 (diff) | |
download | gcc-eefe9a995ceec7fc5ca79505e96bda214e6bd82c.zip gcc-eefe9a995ceec7fc5ca79505e96bda214e6bd82c.tar.gz gcc-eefe9a995ceec7fc5ca79505e96bda214e6bd82c.tar.bz2 |
Makeifle-in (ipa-devirt.o): New.
* Makeifle-in (ipa-devirt.o): New.
(GTFILES): Add ipa-utils.h and ipa-devirt.c
* cgraphunit.c (decide_is_symbol_needed): Do not care about virtuals.
(analyze_functions): Look into possible targets of polymorphic call.
* dumpfile.c (dump_files): Add type-inheritance dump.
* dumpfile.h (TDI_inheritance): New.
* ipa-devirt.c: New file.
* ipa-utils.h (odr_type_d): Forward declare.
(odr_type): New type.
(build_type_inheritance_graph): Declare.
(possible_polymorphic_call_targets): Declare and introduce inline
variant when only edge is pased.
(dump_possible_polymorphic_call_targets): Likewise.
* timevar.def (TV_IPA_INHERITANCE, TV_IPA_VIRTUAL_CALL): New.
* tree.c (type_in_anonymous_namespace_p): Break out from ...
(types_same_for_odr): ... here.
* tree.h (type_in_anonymous_namespace_p): Declare.
* g++.dg/ipa/type-inheritance-1.C: New testcase.
From-SVN: r201836
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 1a4f99f..0aa68c7 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -235,10 +235,6 @@ decide_is_symbol_needed (symtab_node node) if (!node->symbol.definition) return false; - /* Devirtualization may access these. */ - if (DECL_VIRTUAL_P (decl) && optimize) - return true; - if (DECL_EXTERNAL (decl)) return false; @@ -838,6 +834,7 @@ analyze_functions (void) struct cgraph_node *first_handled = first_analyzed; static struct varpool_node *first_analyzed_var; struct varpool_node *first_handled_var = first_analyzed_var; + struct pointer_set_t *reachable_call_targets = pointer_set_create (); symtab_node node, next; int i; @@ -853,6 +850,8 @@ analyze_functions (void) FOR_EACH_SYMBOL (node) if (node->symbol.cpp_implicit_alias) fixup_same_cpp_alias_visibility (node, symtab_alias_target (node)); + if (optimize && flag_devirtualize) + build_type_inheritance_graph (); /* Analysis adds static variables that in turn adds references to new functions. So we need to iterate the process until it stabilize. */ @@ -875,6 +874,8 @@ analyze_functions (void) changed = true; if (cgraph_dump_file) fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node)); + if (!changed && cgraph_dump_file) + fprintf (cgraph_dump_file, "\n"); } if (node == (symtab_node)first_analyzed || node == (symtab_node)first_analyzed_var) @@ -919,6 +920,29 @@ analyze_functions (void) for (edge = cnode->callees; edge; edge = edge->next_callee) if (edge->callee->symbol.definition) enqueue_node ((symtab_node)edge->callee); + if (optimize && flag_devirtualize) + { + for (edge = cnode->indirect_calls; edge; edge = edge->next_callee) + if (edge->indirect_info->polymorphic) + { + unsigned int i; + void *cache_token; + vec <cgraph_node *>targets + = possible_polymorphic_call_targets + (edge, NULL, &cache_token); + + if (!pointer_set_insert (reachable_call_targets, + cache_token)) + { + if (cgraph_dump_file) + dump_possible_polymorphic_call_targets + (cgraph_dump_file, edge); + + for (i = 0; i < targets.length(); i++) + enqueue_node ((symtab_node) targets[i]); + } + } + } /* If decl is a clone of an abstract function, mark that abstract function so that we don't release its body. @@ -999,6 +1023,7 @@ analyze_functions (void) dump_symtab (cgraph_dump_file); } bitmap_obstack_release (NULL); + pointer_set_destroy (reachable_call_targets); ggc_collect (); } |