diff options
author | Jan Hubicka <jh@suse.cz> | 2009-05-10 17:11:01 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2009-05-10 15:11:01 +0000 |
commit | 39ff5a967693c3aa56e8abf0e9c75fabe3335d8d (patch) | |
tree | 74ceb2f1c2ecc5f55f8c3f84dd6a925d1b0918c4 /gcc | |
parent | 9a0c61875533558e047cb5ef140d9836ed475ab9 (diff) | |
download | gcc-39ff5a967693c3aa56e8abf0e9c75fabe3335d8d.zip gcc-39ff5a967693c3aa56e8abf0e9c75fabe3335d8d.tar.gz gcc-39ff5a967693c3aa56e8abf0e9c75fabe3335d8d.tar.bz2 |
cgraphbuild.c (record_reference): Use cgraph_mark_address_taken_node.
* cgraphbuild.c (record_reference): Use cgraph_mark_address_taken_node.
* cgraph.c (cgraph_mark_address_taken_node): New function.
(dump_cgraph_node): Dump new flag.
* cgraph.h (struct cgraph_node): Add address_taken.
(cgraph_mark_address_taken_node): New function.
* cp/decl2.c (cxx_callgraph_analyze_expr): Use
cgraph_mark_address_taken.
* ipa.c (cgraph_postorder): Prioritize functions with address taken
since new direct calls can be born.
From-SVN: r147342
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cgraph.c | 11 | ||||
-rw-r--r-- | gcc/cgraph.h | 3 | ||||
-rw-r--r-- | gcc/cgraphbuild.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 4 | ||||
-rw-r--r-- | gcc/ipa.c | 79 |
6 files changed, 70 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ea0881..935aaa4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-05-10 Jan Hubicka <jh@suse.cz> + + * cgraphbuild.c (record_reference): Use cgraph_mark_address_taken_node. + * cgraph.c (cgraph_mark_address_taken_node): New function. + (dump_cgraph_node): Dump new flag. + * cgraph.h (struct cgraph_node): Add address_taken. + (cgraph_mark_address_taken_node): New function. + * cp/decl2.c (cxx_callgraph_analyze_expr): Use + cgraph_mark_address_taken. + * ipa.c (cgraph_postorder): Prioritize functions with address taken + since new direct calls can be born. + 2009-05-10 Joseph Myers <joseph@codesourcery.com> * c-lex.c (c_lex_with_flags): Expect cpp_hashnode in diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 5d2cc1d..60ff168 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1293,6 +1293,15 @@ cgraph_mark_needed_node (struct cgraph_node *node) cgraph_mark_reachable_node (node); } +/* Likewise indicate that a node is having address taken. */ + +void +cgraph_mark_address_taken_node (struct cgraph_node *node) +{ + node->address_taken = 1; + cgraph_mark_needed_node (node); +} + /* Return local info for the compiled function. */ struct cgraph_local_info * @@ -1397,6 +1406,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) fprintf (f, " nested in: %s", cgraph_node_name (node->origin)); if (node->needed) fprintf (f, " needed"); + if (node->address_taken) + fprintf (f, " address_taken"); else if (node->reachable) fprintf (f, " reachable"); if (gimple_has_body_p (node->decl)) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index c1a1a0a..2e4201e 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -189,6 +189,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { /* Set when function must be output - it is externally visible or its address is taken. */ unsigned needed : 1; + /* Set when function has address taken. */ + unsigned address_taken : 1; /* Set when decl is an abstract function pointed to by the ABSTRACT_DECL_ORIGIN of a reachable function. */ unsigned abstract_and_needed : 1; @@ -417,6 +419,7 @@ void cgraph_mark_if_needed (tree); void cgraph_finalize_compilation_unit (void); void cgraph_optimize (void); void cgraph_mark_needed_node (struct cgraph_node *); +void cgraph_mark_address_taken_node (struct cgraph_node *); void cgraph_mark_reachable_node (struct cgraph_node *); bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason); bool cgraph_preserve_function_body_p (tree); diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index fb56ce5..a7a8bd2 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -58,7 +58,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) functions reachable unconditionally. */ decl = TREE_OPERAND (*tp, 0); if (TREE_CODE (decl) == FUNCTION_DECL) - cgraph_mark_needed_node (cgraph_node (decl)); + cgraph_mark_address_taken_node (cgraph_node (decl)); break; default: diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 8196b54..1f8e848 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3250,11 +3250,11 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED) { case PTRMEM_CST: if (TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) - cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (t))); + cgraph_mark_address_taken_node (cgraph_node (PTRMEM_CST_MEMBER (t))); break; case BASELINK: if (TREE_CODE (BASELINK_FUNCTIONS (t)) == FUNCTION_DECL) - cgraph_mark_needed_node (cgraph_node (BASELINK_FUNCTIONS (t))); + cgraph_mark_address_taken_node (cgraph_node (BASELINK_FUNCTIONS (t))); break; case VAR_DECL: if (DECL_VTABLE_OR_VTT_P (t)) @@ -38,6 +38,7 @@ cgraph_postorder (struct cgraph_node **order) int stack_size = 0; int order_pos = 0; struct cgraph_edge *edge, last; + int pass; struct cgraph_node **stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); @@ -48,44 +49,46 @@ cgraph_postorder (struct cgraph_node **order) right through inline functions. */ for (node = cgraph_nodes; node; node = node->next) node->aux = NULL; - for (node = cgraph_nodes; node; node = node->next) - if (!node->aux) - { - node2 = node; - if (!node->callers) - node->aux = &last; - else - node->aux = node->callers; - while (node2) - { - while (node2->aux != &last) - { - edge = (struct cgraph_edge *) node2->aux; - if (edge->next_caller) - node2->aux = edge->next_caller; - else - node2->aux = &last; - if (!edge->caller->aux) - { - if (!edge->caller->callers) - edge->caller->aux = &last; - else - edge->caller->aux = edge->caller->callers; - stack[stack_size++] = node2; - node2 = edge->caller; - break; - } - } - if (node2->aux == &last) - { - order[order_pos++] = node2; - if (stack_size) - node2 = stack[--stack_size]; - else - node2 = NULL; - } - } - } + for (pass = 0; pass < 2; pass++) + for (node = cgraph_nodes; node; node = node->next) + if (!node->aux + && (pass || (node->needed && !node->address_taken))) + { + node2 = node; + if (!node->callers) + node->aux = &last; + else + node->aux = node->callers; + while (node2) + { + while (node2->aux != &last) + { + edge = (struct cgraph_edge *) node2->aux; + if (edge->next_caller) + node2->aux = edge->next_caller; + else + node2->aux = &last; + if (!edge->caller->aux) + { + if (!edge->caller->callers) + edge->caller->aux = &last; + else + edge->caller->aux = edge->caller->callers; + stack[stack_size++] = node2; + node2 = edge->caller; + break; + } + } + if (node2->aux == &last) + { + order[order_pos++] = node2; + if (stack_size) + node2 = stack[--stack_size]; + else + node2 = NULL; + } + } + } free (stack); for (node = cgraph_nodes; node; node = node->next) node->aux = NULL; |