aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-09-04 21:24:30 -0700
committerRichard Henderson <rth@gcc.gnu.org>2003-09-04 21:24:30 -0700
commit8dafba3ca49dbbd3ac78eb8d026576b9633d433c (patch)
treee52f1fb527a3257f89b40c552bfaabe7263e2310
parentdd37c5a069e7520f2583ea70f58237de7b90e6e2 (diff)
downloadgcc-8dafba3ca49dbbd3ac78eb8d026576b9633d433c.zip
gcc-8dafba3ca49dbbd3ac78eb8d026576b9633d433c.tar.gz
gcc-8dafba3ca49dbbd3ac78eb8d026576b9633d433c.tar.bz2
cgraph.c (cgraph_mark_reachable_node): Split out from ...
* cgraph.c (cgraph_mark_reachable_node): Split out from ... (cgraph_mark_needed_node): Remove needed argument. * cgraph.h: Update to match. * cgraphunit.c (decide_is_function_needed): Split out from ... (cgraph_finalize_function): Reorg. Avoid deferred_inline_function if we generated the function. (record_call_1): Update for cgraph_mark_reachable_node. * varasm.c (mark_referenced): Likewise. * objc/objc-act.c (mark_referenced_methods): Likewise. * decl2.c (mark_member_pointers_and_eh_handlers): Update for change in cgraph_mark_needed_node arguments. From-SVN: r71104
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cgraph.c20
-rw-r--r--gcc/cgraph.h3
-rw-r--r--gcc/cgraphunit.c111
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/objc/objc-act.c5
-rw-r--r--gcc/varasm.c2
8 files changed, 110 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8ecc67d..92437ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * cgraph.c (cgraph_mark_reachable_node): Split out from ...
+ (cgraph_mark_needed_node): Remove needed argument.
+ * cgraph.h: Update to match.
+ * cgraphunit.c (decide_is_function_needed): Split out from ...
+ (cgraph_finalize_function): Reorg. Avoid deferred_inline_function
+ if we generated the function.
+ (record_call_1): Update for cgraph_mark_reachable_node.
+ * varasm.c (mark_referenced): Likewise.
+ * objc/objc-act.c (mark_referenced_methods): Likewise.
+
2003-09-04 DJ Delorie <dj@redhat.com>
* targhooks.c: Add comment explaining the migration process.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index bd83f6a..8b4c0cc 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -234,14 +234,11 @@ cgraph_remove_node (struct cgraph_node *node)
/* Do not free the structure itself so the walk over chain can continue. */
}
-/* Notify finalize_compilation_unit that given node is reachable
- or needed. */
+/* Notify finalize_compilation_unit that given node is reachable. */
+
void
-cgraph_mark_needed_node (struct cgraph_node *node, int needed)
+cgraph_mark_reachable_node (struct cgraph_node *node)
{
- if (needed)
- node->needed = 1;
-
if (!node->reachable && DECL_SAVED_TREE (node->decl))
{
node->reachable = 1;
@@ -257,11 +254,20 @@ cgraph_mark_needed_node (struct cgraph_node *node, int needed)
for (node2 = node->nested; node2; node2 = node2->next_nested)
if (!node2->reachable)
- cgraph_mark_needed_node (node2, 0);
+ cgraph_mark_reachable_node (node2);
}
}
}
+/* Likewise indicate that a node is needed, i.e. reachable via some
+ external means. */
+
+void
+cgraph_mark_needed_node (struct cgraph_node *node)
+{
+ node->needed = 1;
+ cgraph_mark_reachable_node (node);
+}
/* Record call from CALLER to CALLEE */
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index f96ac0d..aaa09a2 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -173,7 +173,8 @@ void cgraph_finalize_function (tree, tree);
void cgraph_finalize_compilation_unit (void);
void cgraph_create_edges (tree, tree);
void cgraph_optimize (void);
-void cgraph_mark_needed_node (struct cgraph_node *, int);
+void cgraph_mark_needed_node (struct cgraph_node *);
+void cgraph_mark_reachable_node (struct cgraph_node *);
bool cgraph_inline_p (tree, tree);
#endif /* GCC_CGRAPH_H */
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7188501..1476c8b 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -62,6 +62,64 @@ static int overall_insns;
record_calls_1. */
static htab_t visited_nodes;
+/* Determine if function DECL is needed. That is, visible to something
+ either outside this translation unit, something magic in the system
+ configury, or (if not doing unit-at-a-time) to something we havn't
+ seen yet. */
+
+static bool
+decide_is_function_needed (struct cgraph_node *node, tree decl)
+{
+ /* If we decided it was needed before, but at the time we didn't have
+ the body of the function available, then it's still needed. We have
+ to go back and re-check its dependencies now. */
+ if (node->needed)
+ return true;
+
+ /* Externally visible functions must be output. The exception is
+ COMDAT functions that must be output only when they are needed. */
+ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ return true;
+
+ /* Constructors and destructors are reachable from the runtime by
+ some mechanism. */
+ if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
+ return true;
+
+ /* If the user told us it is used, then it must be so. */
+ if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ return true;
+
+ /* ??? If the assembler name is set by hand, it is possible to assemble
+ the name later after finalizing the function and the fact is noticed
+ in assemble_name then. This is arguably a bug. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ return true;
+
+ if (flag_unit_at_a_time)
+ return false;
+
+ /* If not doing unit at a time, then we'll only defer this function
+ if its marked for inlining. Otherwise we want to emit it now. */
+
+ /* "extern inline" functions are never output locally. */
+ if (DECL_EXTERNAL (decl))
+ return false;
+ /* ??? */
+ if (node->origin)
+ return false;
+ if (!DECL_INLINE (decl)
+ || (!node->local.disregard_inline_limits
+ /* When declared inline, defer even the uninlinable functions.
+ This allows them to be elliminated when unused. */
+ && !DECL_DECLARED_INLINE_P (decl)
+ && (node->local.inlinable || !cgraph_default_inline_p (node))))
+ return true;
+
+ return false;
+}
+
/* Analyze function once it is parsed. Set up the local information
available - create cgraph edges for function calls via BODY. */
@@ -73,42 +131,16 @@ cgraph_finalize_function (tree decl, tree body ATTRIBUTE_UNUSED)
node->decl = decl;
node->local.finalized = true;
- /* Function now has DECL_SAVED_TREE set. Enqueue it into cgraph_nodes_queue
- if needed. */
- if (node->needed)
- cgraph_mark_needed_node (node, 0);
+ /* If not unit at a time, then we need to create the call graph
+ now, so that called functions can be queued and emitted now. */
if (!flag_unit_at_a_time)
cgraph_analyze_function (node);
- if (/* Externally visible functions must be output. The exception are
- COMDAT functions that must be output only when they are needed.
- Similarly are handled deferred functions and
- external functions (GCC extension "extern inline") */
- (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
- /* ??? Constructors and destructors not called otherwise can be inlined
- into single construction/destruction function per section to save some
- resources. For now just mark it as reachable. */
- || DECL_STATIC_CONSTRUCTOR (decl)
- || DECL_STATIC_DESTRUCTOR (decl)
- /* Function whose name is output to the assembler file must be produced.
- It is possible to assemble the name later after finalizing the function
- and the fact is noticed in assemble_name then. */
- || (DECL_ASSEMBLER_NAME_SET_P (decl)
- && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- || lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
- cgraph_mark_needed_node (node, 1);
- /* When not doing unit-at-a-time deffer only inline functions. */
- else if (!flag_unit_at_a_time
- && !DECL_EXTERNAL (decl)
- && !node->origin
- && (!DECL_INLINE (decl)
- || (!node->local.disregard_inline_limits
- /* When declared inline, deffer even the uninlinable functions.
- This allows them to be elliminated when unused. */
- && !DECL_DECLARED_INLINE_P (decl)
- && (node->local.inlinable
- || !cgraph_default_inline_p (node)))))
- cgraph_mark_needed_node (node, 1);
+ if (decide_is_function_needed (node, decl))
+ cgraph_mark_needed_node (node);
+
+ /* If not unit at a time, go ahead and emit everything we've
+ found to be reachable at this time. */
if (!flag_unit_at_a_time)
while (cgraph_nodes_queue)
{
@@ -118,7 +150,9 @@ cgraph_finalize_function (tree decl, tree body ATTRIBUTE_UNUSED)
cgraph_expand_function (n);
}
- (*debug_hooks->deferred_inline_function) (decl);
+ /* If we've not yet emitted decl, tell the debug info about it. */
+ if (flag_unit_at_a_time || !node->reachable)
+ (*debug_hooks->deferred_inline_function) (decl);
}
/* Walk tree and record all calls. Called via walk_tree. */
@@ -133,7 +167,7 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data)
{
tree decl = TREE_OPERAND (*tp, 0);
if (TREE_CODE (decl) == FUNCTION_DECL)
- cgraph_mark_needed_node (cgraph_node (decl), 1);
+ cgraph_mark_needed_node (cgraph_node (decl));
}
else if (TREE_CODE (*tp) == CALL_EXPR)
{
@@ -251,13 +285,14 @@ cgraph_finalize_compilation_unit (void)
abort ();
cgraph_analyze_function (node);
+
for (edge = node->callees; edge; edge = edge->next_callee)
- {
if (!edge->callee->reachable)
- cgraph_mark_needed_node (edge->callee, 0);
- }
+ cgraph_mark_reachable_node (edge->callee);
+
cgraph_varpool_assemble_pending_decls ();
}
+
/* Collect entry points to the unit. */
if (cgraph_dump_file)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ca8ea06..6f8668c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers_and_eh_handlers): Update for
+ change in cgraph_mark_needed_node arguments.
+
2003-09-02 Geoffrey Keating <geoffk@apple.com>
PR 12161
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 7ca20c8..20d97d4 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2570,7 +2570,7 @@ mark_member_pointers_and_eh_handlers (tree *tp,
{
case PTRMEM_CST:
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (*tp)))
- cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (*tp)), 1);
+ cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (*tp)));
break;
/* EH handlers will emit EH tables referencing typeinfo. */
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 10cc889..0e1c1be 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3981,13 +3981,14 @@ mark_referenced_methods ()
chain = CLASS_CLS_METHODS (impent->imp_context);
while (chain)
{
- cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
+ cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
chain = TREE_CHAIN (chain);
}
+
chain = CLASS_NST_METHODS (impent->imp_context);
while (chain)
{
- cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)), 1);
+ cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
chain = TREE_CHAIN (chain);
}
}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index ac53521..d327cb2 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1662,7 +1662,7 @@ mark_referenced (tree id)
{
node = cgraph_node_for_identifier (id);
if (node)
- cgraph_mark_needed_node (node, 1);
+ cgraph_mark_needed_node (node);
}
vnode = cgraph_varpool_node_for_identifier (id);