diff options
author | Jan Hubicka <jh@suse.cz> | 2003-06-23 23:11:44 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2003-06-23 21:11:44 +0000 |
commit | 1668aabc227d71870526e434415a6800cdeeba2f (patch) | |
tree | a308ac6242dd91f73480ea940c0237afcc47f134 /gcc/cgraphunit.c | |
parent | 89ce1c8f763e1c3485d97d3c8c74f75f94bf0e09 (diff) | |
download | gcc-1668aabc227d71870526e434415a6800cdeeba2f.zip gcc-1668aabc227d71870526e434415a6800cdeeba2f.tar.gz gcc-1668aabc227d71870526e434415a6800cdeeba2f.tar.bz2 |
cgraph.c (cgraph_nodes_queue): Declare.
* cgraph.c (cgraph_nodes_queue): Declare.
(eq_node): Take identifier as p2.
(cgraph_node): Update htab_find_slot_with_hash call.
(cgraph_node_for_identifier): New.
(cgraph_mark_needed_node): Move here from cgraphunit.c.
* cgraph.h (cgraph_nodes_queue): Declare.
(cgraph_node_for_identifier): Declare.
* cgraphunit.c (cgraph_finalize_function): Collect entry points here
instead of in cgraph_finalize_compilation_unit; constructors and
destructors are entry points.
(cgraph_finalize_compilation_unit): Reorganize debug outout;
examine nested functions after lowerng; call collect_functions hook.
(cgraph_mark_local_functions): DECL_COMDAT functions are not local.
(cgraph_finalize_compilation_unit): Do not collect entry points.
* varasm.c: Include cgraph.h
(assemble_name): Mark referenced identifier as needed.
* cgraphunit.c (record_call_1): Use get_callee_fndecl.
From-SVN: r68390
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 113 |
1 files changed, 50 insertions, 63 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index a306908..9fc5dd0 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -55,7 +55,29 @@ cgraph_finalize_function (decl, body) node->decl = decl; - node->local.can_inline_once = tree_inlinable_function_p (decl, 1); + if (/* Externally visible functions must be output. The exception are + COMDAT functions that must be output only when they are needed. + Similarly are handled defered 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)))) + { + cgraph_mark_needed_node (node, 1); + } + + if (!node->needed && !DECL_COMDAT (node->decl)) + node->local.can_inline_once = tree_inlinable_function_p (decl, 1); + else + node->local.can_inline_once = 0; if (flag_inline_trees) node->local.inline_many = tree_inlinable_function_p (decl, 0); else @@ -64,33 +86,6 @@ cgraph_finalize_function (decl, body) (*debug_hooks->deferred_inline_function) (decl); } -static struct cgraph_node *queue = NULL; - -/* Notify finalize_compilation_unit that given node is reachable - or needed. */ - -void -cgraph_mark_needed_node (node, needed) - struct cgraph_node *node; - int needed; -{ - if (needed) - { - if (DECL_SAVED_TREE (node->decl)) - announce_function (node->decl); - node->needed = 1; - } - if (!node->reachable) - { - node->reachable = 1; - if (DECL_SAVED_TREE (node->decl)) - { - node->aux = queue; - queue = node; - } - } -} - /* Walk tree and record all calls. Called via walk_tree. */ static tree record_call_1 (tp, walk_subtrees, data) @@ -108,15 +103,8 @@ record_call_1 (tp, walk_subtrees, data) } else if (TREE_CODE (*tp) == CALL_EXPR) { - /* We cannot use get_callee_fndecl here because it actually tries - too hard to get the function declaration, looking for indirect - references and stripping NOPS. As a result, get_callee_fndecl - finds calls that shouldn't be in the call graph. */ - - tree decl = TREE_OPERAND (*tp, 0); - if (TREE_CODE (decl) == ADDR_EXPR) - decl = TREE_OPERAND (decl, 0); - if (TREE_CODE (decl) == FUNCTION_DECL) + tree decl = get_callee_fndecl (*tp); + if (decl && TREE_CODE (decl) == FUNCTION_DECL) { if (DECL_BUILT_IN (decl)) return NULL; @@ -156,40 +144,31 @@ cgraph_finalize_compilation_unit () struct cgraph_node *node; struct cgraph_edge *edge; - /* Collect entry points to the unit. */ - if (!quiet_flag) - fprintf (stderr, "\n\nUnit entry points:"); - - for (node = cgraph_nodes; node; node = node->next) { - tree decl = node->decl; - - if (!DECL_SAVED_TREE (decl)) - continue; - if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) - || (DECL_ASSEMBLER_NAME_SET_P (decl) - && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) - { - /* This function can be called from outside this compliation - unit, so it most definitely is needed. */ - cgraph_mark_needed_node (node, 1); - } + fprintf (stderr, "\n\nInitial entry points:"); + for (node = cgraph_nodes; node; node = node->next) + if (node->needed && DECL_SAVED_TREE (node->decl)) + announce_function (node->decl); } /* Propagate reachability flag and lower representation of all reachable functions. In the future, lowering will introduce new functions and new entry points on the way (by template instantiation and virtual method table generation for instance). */ - while (queue) + while (cgraph_nodes_queue) { - tree decl = queue->decl; + tree decl = cgraph_nodes_queue->decl; + + node = cgraph_nodes_queue; + cgraph_nodes_queue = cgraph_nodes_queue->aux; - node = queue; - queue = queue->aux; if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl)) abort (); + if (lang_hooks.callgraph.lower_function) + (*lang_hooks.callgraph.lower_function) (decl); + /* At the moment frontend automatically emits all nested functions. */ if (node->nested) { @@ -200,9 +179,6 @@ cgraph_finalize_compilation_unit () cgraph_mark_needed_node (node2, 0); } - if (lang_hooks.callgraph.lower_function) - (*lang_hooks.callgraph.lower_function) (decl); - /* First kill forward declaration so reverse inling works properly. */ cgraph_create_edges (decl, DECL_SAVED_TREE (decl)); @@ -213,6 +189,15 @@ cgraph_finalize_compilation_unit () } node->lowered = true; } + /* Collect entry points to the unit. */ + + if (!quiet_flag) + { + fprintf (stderr, "\n\nUnit entry points:"); + for (node = cgraph_nodes; node; node = node->next) + if (node->needed && DECL_SAVED_TREE (node->decl)) + announce_function (node->decl); + } if (!quiet_flag) fprintf (stderr, "\n\nReclaiming functions:"); @@ -248,7 +233,8 @@ cgraph_mark_functions_to_output () && (node->needed || (!node->local.inline_many && !node->global.inline_once && node->reachable) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) + || (DECL_ASSEMBLER_NAME_SET_P (decl) + && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) && !TREE_ASM_WRITTEN (decl) && !node->origin && !DECL_EXTERNAL (decl)) node->output = 1; @@ -331,7 +317,7 @@ cgraph_expand_functions () for (node = cgraph_nodes; node; node = node->next) node->aux = NULL; for (node = cgraph_nodes; node; node = node->next) - if (node->output && !node->aux) + if (!node->aux) { node2 = node; if (!node->callers) @@ -400,6 +386,7 @@ cgraph_mark_local_functions () { node->local.local = (!node->needed && DECL_SAVED_TREE (node->decl) + && !DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl)); if (node->local.local) announce_function (node->decl); |