This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
pretty-ipa merge 4: "process" cgraph node flag
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 28 Mar 2009 13:07:01 +0100
- Subject: pretty-ipa merge 4: "process" cgraph node flag
Hi,
when writting local passes that use modify info about function itself
(such as local nothrow discovery) or that use other function bodies
it is important to know if some function is already processed by current
topdown walk of local passes or it is going to be handled later.
This patch adds "process" flag for this and remove "output" flag that
is late passes was used to test if function should appear in assembly
file. Now we can test process || TREE_ASM_WRITTEN.
Bootstrapped/regtested x86_64-linux, comitting.
Honza
Index: ChangeLog
===================================================================
*** ChangeLog (revision 145177)
--- ChangeLog (working copy)
***************
*** 1,5 ****
--- 1,18 ----
2009-03-28 Jan Hubicka <jh@suse.cz>
+ * cgraph.c (dump_cgraph_node): Add replace output flag by process.
+ * cgraph.h (cgraph_node): Likewise.
+ * cgraphunit.c (cgraph_process_new_functions): Set process flag.
+ (cgraph_reset_node): Use process flag.
+ (cgraph_mark_functions_to_output): Likewise.
+ (cgraph_expand_function): Likewise.
+ (cgraph_expand_all_functions): Likewise.
+ (cgraph_output_in_order): Likewise.
+ * dwarf2out.c (reference_to_unused): Likewise.
+ * passes.c do_per_function_toporder): Likewise.
+
+ 2009-03-28 Jan Hubicka <jh@suse.cz>
+
Bring from lto-branch:
2008-09-03 Doug Kwan <dougkwan@google.com>
Index: cgraph.c
===================================================================
*** cgraph.c (revision 145177)
--- cgraph.c (working copy)
*************** dump_cgraph_node (FILE *f, struct cgraph
*** 1168,1175 ****
fprintf (f, " reachable");
if (gimple_has_body_p (node->decl))
fprintf (f, " body");
! if (node->output)
! fprintf (f, " output");
if (node->local.local)
fprintf (f, " local");
if (node->local.externally_visible)
--- 1168,1175 ----
fprintf (f, " reachable");
if (gimple_has_body_p (node->decl))
fprintf (f, " body");
! if (node->process)
! fprintf (f, " process");
if (node->local.local)
fprintf (f, " local");
if (node->local.externally_visible)
Index: cgraph.h
===================================================================
*** cgraph.h (revision 145177)
--- cgraph.h (working copy)
*************** struct cgraph_node GTY((chain_next ("%h.
*** 178,185 ****
/* Set once the function has been instantiated and its callee
lists created. */
unsigned analyzed : 1;
! /* Set when function is scheduled to be assembled. */
! unsigned output : 1;
/* Set for aliases once they got through assemble_alias. */
unsigned alias : 1;
--- 178,185 ----
/* Set once the function has been instantiated and its callee
lists created. */
unsigned analyzed : 1;
! /* Set when function is scheduled to be processed by local passes. */
! unsigned process : 1;
/* Set for aliases once they got through assemble_alias. */
unsigned alias : 1;
Index: cgraphunit.c
===================================================================
*** cgraphunit.c (revision 145177)
--- cgraphunit.c (working copy)
*************** cgraph_process_new_functions (void)
*** 426,432 ****
case CGRAPH_STATE_EXPANSION:
/* Functions created during expansion shall be compiled
directly. */
! node->output = 0;
cgraph_expand_function (node);
break;
--- 426,432 ----
case CGRAPH_STATE_EXPANSION:
/* Functions created during expansion shall be compiled
directly. */
! node->process = 0;
cgraph_expand_function (node);
break;
*************** cgraph_process_new_functions (void)
*** 452,463 ****
static void
cgraph_reset_node (struct cgraph_node *node)
{
! /* If node->output is set, then we have already begun whole-unit analysis.
This is *not* testing for whether we've already emitted the function.
That case can be sort-of legitimately seen with real function redefinition
errors. I would argue that the front end should never present us with
such a case, but don't enforce that for now. */
! gcc_assert (!node->output);
/* Reset our data structures so we can analyze the function again. */
memset (&node->local, 0, sizeof (node->local));
--- 452,463 ----
static void
cgraph_reset_node (struct cgraph_node *node)
{
! /* If node->process is set, then we have already begun whole-unit analysis.
This is *not* testing for whether we've already emitted the function.
That case can be sort-of legitimately seen with real function redefinition
errors. I would argue that the front end should never present us with
such a case, but don't enforce that for now. */
! gcc_assert (!node->process);
/* Reset our data structures so we can analyze the function again. */
memset (&node->local, 0, sizeof (node->local));
*************** cgraph_mark_functions_to_output (void)
*** 990,996 ****
tree decl = node->decl;
struct cgraph_edge *e;
! gcc_assert (!node->output);
for (e = node->callers; e; e = e->next_caller)
if (e->inline_failed)
--- 990,996 ----
tree decl = node->decl;
struct cgraph_edge *e;
! gcc_assert (!node->process);
for (e = node->callers; e; e = e->next_caller)
if (e->inline_failed)
*************** cgraph_mark_functions_to_output (void)
*** 1005,1011 ****
|| (e && node->reachable))
&& !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
! node->output = 1;
else
{
/* We should've reclaimed all functions that are not needed. */
--- 1005,1011 ----
|| (e && node->reachable))
&& !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
! node->process = 1;
else
{
/* We should've reclaimed all functions that are not needed. */
*************** cgraph_expand_function (struct cgraph_no
*** 1038,1043 ****
--- 1038,1044 ----
gcc_assert (!node->global.inlined_to);
announce_function (decl);
+ node->process = 0;
gcc_assert (node->lowered);
*************** cgraph_expand_all_functions (void)
*** 1093,1108 ****
/* Garbage collector may remove inline clones we eliminate during
optimization. So we must be sure to not reference them. */
for (i = 0; i < order_pos; i++)
! if (order[i]->output)
order[new_order_pos++] = order[i];
for (i = new_order_pos - 1; i >= 0; i--)
{
node = order[i];
! if (node->output)
{
gcc_assert (node->reachable);
! node->output = 0;
cgraph_expand_function (node);
}
}
--- 1094,1109 ----
/* Garbage collector may remove inline clones we eliminate during
optimization. So we must be sure to not reference them. */
for (i = 0; i < order_pos; i++)
! if (order[i]->process)
order[new_order_pos++] = order[i];
for (i = new_order_pos - 1; i >= 0; i--)
{
node = order[i];
! if (node->process)
{
gcc_assert (node->reachable);
! node->process = 0;
cgraph_expand_function (node);
}
}
*************** cgraph_output_in_order (void)
*** 1151,1157 ****
for (pf = cgraph_nodes; pf; pf = pf->next)
{
! if (pf->output)
{
i = pf->order;
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
--- 1152,1158 ----
for (pf = cgraph_nodes; pf; pf = pf->next)
{
! if (pf->process)
{
i = pf->order;
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
*************** cgraph_output_in_order (void)
*** 1191,1197 ****
switch (nodes[i].kind)
{
case ORDER_FUNCTION:
! nodes[i].u.f->output = 0;
cgraph_expand_function (nodes[i].u.f);
break;
--- 1192,1198 ----
switch (nodes[i].kind)
{
case ORDER_FUNCTION:
! nodes[i].u.f->process = 0;
cgraph_expand_function (nodes[i].u.f);
break;
Index: dwarf2out.c
===================================================================
*** dwarf2out.c (revision 145177)
--- dwarf2out.c (working copy)
*************** reference_to_unused (tree * tp, int * wa
*** 11319,11325 ****
&& (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
{
struct cgraph_node *node = cgraph_node (*tp);
! if (!node->output)
return *tp;
}
else if (TREE_CODE (*tp) == STRING_CST && !TREE_ASM_WRITTEN (*tp))
--- 11319,11325 ----
&& (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
{
struct cgraph_node *node = cgraph_node (*tp);
! if (node->process || TREE_ASM_WRITTEN (*tp))
return *tp;
}
else if (TREE_CODE (*tp) == STRING_CST && !TREE_ASM_WRITTEN (*tp))
Index: passes.c
===================================================================
*** passes.c (revision 145177)
--- passes.c (working copy)
*************** do_per_function_toporder (void (*callbac
*** 878,888 ****
--- 878,891 ----
order = GGC_NEWVEC (struct cgraph_node *, cgraph_n_nodes);
nnodes = cgraph_postorder (order);
for (i = nnodes - 1; i >= 0; i--)
+ order[i]->process = 1;
+ for (i = nnodes - 1; i >= 0; i--)
{
struct cgraph_node *node = order[i];
/* Allow possibly removed nodes to be garbage collected. */
order[i] = NULL;
+ node->process = 0;
if (node->analyzed && (node->needed || node->reachable))
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));