diff options
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 29b653d1e11..722c4f4d063 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -403,10 +403,11 @@ cgraph_node::reset (void) remove_all_references (); } -/* Return true when there are references to the node. */ +/* Return true when there are references to the node. INCLUDE_SELF is + true if a self reference counts as a reference. */ bool -symtab_node::referred_to_p (void) +symtab_node::referred_to_p (bool include_self) { ipa_ref *ref = NULL; @@ -416,7 +417,13 @@ symtab_node::referred_to_p (void) /* For functions check also calls. */ cgraph_node *cn = dyn_cast <cgraph_node *> (this); if (cn && cn->callers) - return true; + { + if (include_self) + return true; + for (cgraph_edge *e = cn->callers; e; e = e->next_caller) + if (e->caller != this) + return true; + } return false; } @@ -924,8 +931,12 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets, static cgraph_node *first_analyzed; static varpool_node *first_analyzed_var; +/* FIRST_TIME is set to TRUE for the first time we are called for a + translation unit from finalize_compilation_unit() or false + otherwise. */ + static void -analyze_functions (void) +analyze_functions (bool first_time) { /* Keep track of already processed nodes when called multiple times for intermodule optimization. */ @@ -1097,6 +1108,13 @@ analyze_functions (void) symtab_node::dump_table (symtab->dump_file); } + if (first_time) + { + symtab_node *snode; + FOR_EACH_SYMBOL (snode) + check_global_declaration (snode->decl); + } + if (symtab->dump_file) fprintf (symtab->dump_file, "\nRemoving unused symbols:"); @@ -1109,6 +1127,19 @@ analyze_functions (void) { if (symtab->dump_file) fprintf (symtab->dump_file, " %s", node->name ()); + + /* See if the debugger can use anything before the DECL + passes away. Perhaps it can notice a DECL that is now a + constant and can tag the early DIE with an appropriate + attribute. + + Otherwise, this is the last chance the debug_hooks have + at looking at optimized away DECLs, since + late_global_decl will subsequently be called from the + contents of the now pruned symbol table. */ + if (!decl_function_context (node->decl)) + (*debug_hooks->late_global_decl) (node->decl); + node->remove (); continue; } @@ -2445,13 +2476,23 @@ symbol_table::finalize_compilation_unit (void) /* Gimplify and lower all functions, compute reachability and remove unreachable nodes. */ - analyze_functions (); + analyze_functions (/*first_time=*/true); /* Mark alias targets necessary and emit diagnostics. */ handle_alias_pairs (); /* Gimplify and lower thunks. */ - analyze_functions (); + analyze_functions (/*first_time=*/false); + + /* Emit early debug for reachable functions, and by consequence, + locally scoped symbols. */ + struct cgraph_node *cnode; + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode) + (*debug_hooks->early_global_decl) (cnode->decl); + + /* Clean up anything that needs cleaning up after initial debug + generation. */ + (*debug_hooks->early_finish) (); /* Finally drive the pass manager. */ compile (); |