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
This commit is contained in:
Jan Hubicka 2009-05-10 17:11:01 +02:00 committed by Jan Hubicka
parent 9a0c618755
commit 39ff5a9676
6 changed files with 70 additions and 41 deletions

View File

@ -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

View File

@ -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))

View File

@ -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);

View File

@ -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:

View File

@ -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))

View File

@ -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;