summaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r--gcc/cgraphunit.c53
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 ();