This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]