Commit 39ff5a96 by Jan Hubicka Committed by Jan Hubicka

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
parent 9a0c6187
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> 2009-05-10 Joseph Myers <joseph@codesourcery.com>
* c-lex.c (c_lex_with_flags): Expect cpp_hashnode in * c-lex.c (c_lex_with_flags): Expect cpp_hashnode in
......
...@@ -1293,6 +1293,15 @@ cgraph_mark_needed_node (struct cgraph_node *node) ...@@ -1293,6 +1293,15 @@ cgraph_mark_needed_node (struct cgraph_node *node)
cgraph_mark_reachable_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. */ /* Return local info for the compiled function. */
struct cgraph_local_info * struct cgraph_local_info *
...@@ -1397,6 +1406,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) ...@@ -1397,6 +1406,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " nested in: %s", cgraph_node_name (node->origin)); fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
if (node->needed) if (node->needed)
fprintf (f, " needed"); fprintf (f, " needed");
if (node->address_taken)
fprintf (f, " address_taken");
else if (node->reachable) else if (node->reachable)
fprintf (f, " reachable"); fprintf (f, " reachable");
if (gimple_has_body_p (node->decl)) if (gimple_has_body_p (node->decl))
......
...@@ -189,6 +189,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { ...@@ -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 /* Set when function must be output - it is externally visible
or its address is taken. */ or its address is taken. */
unsigned needed : 1; unsigned needed : 1;
/* Set when function has address taken. */
unsigned address_taken : 1;
/* Set when decl is an abstract function pointed to by the /* Set when decl is an abstract function pointed to by the
ABSTRACT_DECL_ORIGIN of a reachable function. */ ABSTRACT_DECL_ORIGIN of a reachable function. */
unsigned abstract_and_needed : 1; unsigned abstract_and_needed : 1;
...@@ -417,6 +419,7 @@ void cgraph_mark_if_needed (tree); ...@@ -417,6 +419,7 @@ void cgraph_mark_if_needed (tree);
void cgraph_finalize_compilation_unit (void); void cgraph_finalize_compilation_unit (void);
void cgraph_optimize (void); void cgraph_optimize (void);
void cgraph_mark_needed_node (struct cgraph_node *); 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 *); void cgraph_mark_reachable_node (struct cgraph_node *);
bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason); bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason);
bool cgraph_preserve_function_body_p (tree); bool cgraph_preserve_function_body_p (tree);
......
...@@ -58,7 +58,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) ...@@ -58,7 +58,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
functions reachable unconditionally. */ functions reachable unconditionally. */
decl = TREE_OPERAND (*tp, 0); decl = TREE_OPERAND (*tp, 0);
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
cgraph_mark_needed_node (cgraph_node (decl)); cgraph_mark_address_taken_node (cgraph_node (decl));
break; break;
default: default:
......
...@@ -3250,11 +3250,11 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED) ...@@ -3250,11 +3250,11 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED)
{ {
case PTRMEM_CST: case PTRMEM_CST:
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) 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; break;
case BASELINK: case BASELINK:
if (TREE_CODE (BASELINK_FUNCTIONS (t)) == FUNCTION_DECL) 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; break;
case VAR_DECL: case VAR_DECL:
if (DECL_VTABLE_OR_VTT_P (t)) if (DECL_VTABLE_OR_VTT_P (t))
......
...@@ -38,6 +38,7 @@ cgraph_postorder (struct cgraph_node **order) ...@@ -38,6 +38,7 @@ cgraph_postorder (struct cgraph_node **order)
int stack_size = 0; int stack_size = 0;
int order_pos = 0; int order_pos = 0;
struct cgraph_edge *edge, last; struct cgraph_edge *edge, last;
int pass;
struct cgraph_node **stack = struct cgraph_node **stack =
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
...@@ -48,44 +49,46 @@ cgraph_postorder (struct cgraph_node **order) ...@@ -48,44 +49,46 @@ cgraph_postorder (struct cgraph_node **order)
right through inline functions. */ right through inline functions. */
for (node = cgraph_nodes; node; node = node->next) for (node = cgraph_nodes; node; node = node->next)
node->aux = NULL; node->aux = NULL;
for (node = cgraph_nodes; node; node = node->next) for (pass = 0; pass < 2; pass++)
if (!node->aux) for (node = cgraph_nodes; node; node = node->next)
{ if (!node->aux
node2 = node; && (pass || (node->needed && !node->address_taken)))
if (!node->callers) {
node->aux = &last; node2 = node;
else if (!node->callers)
node->aux = node->callers; node->aux = &last;
while (node2) else
{ node->aux = node->callers;
while (node2->aux != &last) while (node2)
{ {
edge = (struct cgraph_edge *) node2->aux; while (node2->aux != &last)
if (edge->next_caller) {
node2->aux = edge->next_caller; edge = (struct cgraph_edge *) node2->aux;
else if (edge->next_caller)
node2->aux = &last; node2->aux = edge->next_caller;
if (!edge->caller->aux) else
{ node2->aux = &last;
if (!edge->caller->callers) if (!edge->caller->aux)
edge->caller->aux = &last; {
else if (!edge->caller->callers)
edge->caller->aux = edge->caller->callers; edge->caller->aux = &last;
stack[stack_size++] = node2; else
node2 = edge->caller; edge->caller->aux = edge->caller->callers;
break; stack[stack_size++] = node2;
} node2 = edge->caller;
} break;
if (node2->aux == &last) }
{ }
order[order_pos++] = node2; if (node2->aux == &last)
if (stack_size) {
node2 = stack[--stack_size]; order[order_pos++] = node2;
else if (stack_size)
node2 = NULL; node2 = stack[--stack_size];
} else
} node2 = NULL;
} }
}
}
free (stack); free (stack);
for (node = cgraph_nodes; node; node = node->next) for (node = cgraph_nodes; node; node = node->next)
node->aux = NULL; node->aux = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment