* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147342
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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 *
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))
/* 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;
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);
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:
{
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))
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);
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;