Avoid loop in cgraph_remove_node

Jan Hubicka jh@suse.cz
Fri Mar 18 01:04:00 GMT 2005


Hi,
this patch avoids one of loops in cgraph_remove_node Richard complained
about.  It does not reduce the performance in any thrilling way as the
loop iterates at most once in mainline for already quite a some time,
but I found a related but while working on it - in non-unit-at-a-time we
can't release the body of inlinable function even if it seems unused
right now.  THe real quadratic bottleneck is the next_node linked list,
that can be replaced by doubly linked list like we did in other cases,
but I will deal with this incrementally.

Bootstrapped/regtested i686-pc-gnu-linux and ppc-linux and I am going to commit it to
mainline now.  I think this can go to 4.0 branch too, as missing inline
oppurtunities in non-unit-at-a-time mode is a bug and tester reports
following testcases to start passing:
libmudflap.cth/pass40-frag.c (-static -DSTATIC) execution test
libmudflap.cth/pass40-frag.c (-static -DSTATIC) output pattern test
(I have to look whether this is just bug in tester or real)

Honza

2005-03-18  Jan Hubicka  <jh@suse.cz>
	* cgraph.c (cgraph_remove_node): Reorganize killing of dead bodies.
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.65
diff -c -3 -p -r1.65 cgraph.c
*** cgraph.c	2 Mar 2005 11:09:47 -0000	1.65
--- cgraph.c	17 Mar 2005 16:10:28 -0000
*************** void
*** 398,404 ****
  cgraph_remove_node (struct cgraph_node *node)
  {
    void **slot;
!   bool check_dead = 1;
  
    cgraph_node_remove_callers (node);
    cgraph_node_remove_callees (node);
--- 398,404 ----
  cgraph_remove_node (struct cgraph_node *node)
  {
    void **slot;
!   bool kill_body = false;
  
    cgraph_node_remove_callers (node);
    cgraph_node_remove_callees (node);
*************** cgraph_remove_node (struct cgraph_node *
*** 426,437 ****
        else
  	{
            htab_clear_slot (cgraph_hash, slot);
! 	  if (!dump_enabled_p (TDI_tree_all))
! 	    {
!               DECL_SAVED_TREE (node->decl) = NULL;
! 	      DECL_STRUCT_FUNCTION (node->decl) = NULL;
! 	    }
! 	  check_dead = false;
  	}
      }
    else
--- 426,432 ----
        else
  	{
            htab_clear_slot (cgraph_hash, slot);
! 	  kill_body = true;
  	}
      }
    else
*************** cgraph_remove_node (struct cgraph_node *
*** 443,465 ****
        n->next_clone = node->next_clone;
      }
  
!   /* Work out whether we still need a function body (either there is inline
!      clone or there is out of line function whose body is not written).  */
!   if (check_dead && flag_unit_at_a_time)
!     {
!       struct cgraph_node *n;
! 
!       for (n = *slot; n; n = n->next_clone)
! 	if (n->global.inlined_to
! 	    || (!n->global.inlined_to
! 		&& !TREE_ASM_WRITTEN (n->decl) && !DECL_EXTERNAL (n->decl)))
! 	  break;
!       if (!n && !dump_enabled_p (TDI_tree_all))
! 	{
! 	  DECL_SAVED_TREE (node->decl) = NULL;
! 	  DECL_STRUCT_FUNCTION (node->decl) = NULL;
!           DECL_INITIAL (node->decl) = error_mark_node;
! 	}
      }
    cgraph_n_nodes--;
    /* Do not free the structure itself so the walk over chain can continue.  */
--- 438,460 ----
        n->next_clone = node->next_clone;
      }
  
!   /* While all the clones are removed after being proceeded, the function 
!      itself is kept in the cgraph even after it is compiled.  Check whether
!      we are done with this body and reclaim it proactively if this is the case.
!      */
!   if (!kill_body && *slot)
!     {
!       struct cgraph_node *n = *slot;
!       if (!n->next_clone && !n->global.inlined_to
! 	  && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))
! 	kill_body = true;
!     }
! 
!   if (kill_body && !dump_enabled_p (TDI_tree_all) && flag_unit_at_a_time)
!     {
!       DECL_SAVED_TREE (node->decl) = NULL;
!       DECL_STRUCT_FUNCTION (node->decl) = NULL;
!       DECL_INITIAL (node->decl) = error_mark_node;
      }
    cgraph_n_nodes--;
    /* Do not free the structure itself so the walk over chain can continue.  */



More information about the Gcc-patches mailing list