From eefe9a995ceec7fc5ca79505e96bda214e6bd82c Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 19 Aug 2013 12:14:06 +0200 Subject: 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 --- gcc/cgraphunit.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'gcc/cgraphunit.c') 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 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 (); } -- cgit v1.1