diff options
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 (); } |