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]

[C++ patch] PR c++/12850


Hi,
The problem of C++/12850 testcase is that we create insanely many instantiations.
These instantiations are all created by recursive walk so we don't GGC collect
because function_depth gets large.  I need two changes in order to get
GGC doing what it is supposed to do.

First one is to deffer those instantiations to the very end of
compilation.  We can do the garbage collection better then and we limit
recusion that is both good.  This came in with patch
http://gcc.gnu.org/ml/gcc-patches/2003-04/msg01679.html
The patch force the recursion when there is chance that callee will be
proved to be nothrow.  I see no point doing this when not optimizing or
with unit-at-a-time (where we sort the functions anyway)  This assumes
that the toplev.c code is only one propagating the nothrow flags and
that C++ don't have it's own mechanizm somewhere I never heart about.

I checked that the testcase from
http://gcc.gnu.org/ml/gcc-patches/2003-04/msg01679.html compiles 3
seconds with -O2 independently on the patch (and resulting code gets one
line shorter) and about 50 seconds with -fno-unit-at-a-time, again not
affected.  -O0 times are down to 1.5 second with the patch.

This alone doesn't help, because all the instantiations happens with
function_depth == 2 thus we skip ggc_collect.  instantiate_template
itself increase function_depth and once gain we increase it in
expand_or_deffer_fn, so we conclude to deffer everything and lose again.

The other half of patch is decreasing function_depth for call to
instantiate_template where GGC can safely happen and similarly for
synthetize_method.  This is not cleanset thing to do, so I would be very happy
to hear about ideas to do this cleanly.

The patch reduces -O0 consumption to about 40MB, while -O2 consumption is at
about 260MB, testcase needed about 540MB originally for me.

Honza

	PR c++/12850
	* cgraphunit.c (cgraph_finalize_function): Always ggc_collect when
	at zero nest level.

	* decl2.c (finish_file): reduce function depth before synthetizing.
	(mark_used): Do not proactively instantiate templates when compiling
	in unit-at-a-time or not optimizing.
	* optimize.c (maybe_clone_body): Do not increase function depth.
	* pt.c (instantiate_pending_templates):  reduce function depth before
	instantiating.
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 cgraphunit.c
*** cgraphunit.c	8 Jan 2004 22:57:49 -0000	1.43
--- cgraphunit.c	10 Jan 2004 16:39:31 -0000
*************** cgraph_finalize_function (tree decl, boo
*** 219,225 ****
    /* If not unit at a time, go ahead and emit everything we've found
       to be reachable at this time.  */
    if (!nested)
!     cgraph_assemble_pending_functions ();
  
    /* If we've not yet emitted decl, tell the debug info about it.  */
    if (!TREE_ASM_WRITTEN (decl))
--- 219,228 ----
    /* If not unit at a time, go ahead and emit everything we've found
       to be reachable at this time.  */
    if (!nested)
!     {
!       if (!cgraph_assemble_pending_functions ())
! 	ggc_collect ();
!     }
  
    /* If we've not yet emitted decl, tell the debug info about it.  */
    if (!TREE_ASM_WRITTEN (decl))
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.693
diff -c -3 -p -r1.693 decl2.c
*** cp/decl2.c	23 Dec 2003 16:53:50 -0000	1.693
--- cp/decl2.c	10 Jan 2004 16:39:33 -0000
*************** finish_file (void)
*** 2576,2581 ****
--- 2576,2582 ----
        /* If there are templates that we've put off instantiating, do
  	 them now.  */
        instantiate_pending_templates ();
+       ggc_collect ();
  
        /* Write out virtual tables as required.  Note that writing out
    	 the virtual table for a template class may cause the
*************** finish_file (void)
*** 2714,2720 ****
--- 2715,2725 ----
  		 finish_function doesn't clean things up, and we end
  		 up with CURRENT_FUNCTION_DECL set.  */
  	      push_to_top_level ();
+ 	      /* syntetize_method increase function depth.  We are safe for GGC
+ 	         here.  */
+ 	      function_depth--;
  	      synthesize_method (decl);
+ 	      function_depth++;
  	      pop_from_top_level ();
  	      reconsider = true;
  	    }
*************** mark_used (tree decl)
*** 3008,3015 ****
  
  	 However, if instantiating this function might help us mark
  	 the current function TREE_NOTHROW, we go ahead and
! 	 instantiate it now.  */
        defer = (!flag_exceptions
  	       || TREE_CODE (decl) != FUNCTION_DECL
  	       /* If the called function can't throw, we don't need to
  		  generate its body to find that out.  */
--- 3013,3026 ----
  
  	 However, if instantiating this function might help us mark
  	 the current function TREE_NOTHROW, we go ahead and
! 	 instantiate it now.  
! 	 
! 	 This is not needed for unit-at-a-time since we reorder the functions
! 	 in topological order anyway.
! 	 */
        defer = (!flag_exceptions
+ 	       || flag_unit_at_a_time
+ 	       || !optimize
  	       || TREE_CODE (decl) != FUNCTION_DECL
  	       /* If the called function can't throw, we don't need to
  		  generate its body to find that out.  */
Index: cp/optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/optimize.c,v
retrieving revision 1.102
diff -c -3 -p -r1.102 optimize.c
*** cp/optimize.c	6 Nov 2003 22:08:26 -0000	1.102
--- cp/optimize.c	10 Jan 2004 16:39:33 -0000
*************** maybe_clone_body (tree fn)
*** 129,139 ****
    /* Emit the DWARF1 abstract instance.  */
    (*debug_hooks->deferred_inline_function) (fn);
  
-   /* Our caller does not expect collection to happen, which it might if
-      we decide to compile the function to rtl now.  Arrange for a new
-      gc context to be created if so.  */
-   function_depth++;
- 
    /* We know that any clones immediately follow FN in the TYPE_METHODS
       list.  */
    for (clone = TREE_CHAIN (fn);
--- 129,134 ----
*************** maybe_clone_body (tree fn)
*** 252,259 ****
        expand_or_defer_fn (clone);
        pop_from_top_level ();
      }
- 
-   function_depth--;
  
    /* We don't need to process the original function any further.  */
    return 1;
--- 247,252 ----
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.809
diff -c -3 -p -r1.809 pt.c
*** cp/pt.c	8 Jan 2004 11:52:41 -0000	1.809
--- cp/pt.c	10 Jan 2004 16:39:34 -0000
*************** instantiate_pending_templates (void)
*** 11162,11167 ****
--- 11162,11171 ----
    int instantiated_something = 0;
    int reconsider;
    location_t saved_loc = input_location;
+ 
+   /* instantiate_decl increase function depth.  We are safe for GGC
+      here.  */
+   function_depth--;
    
    do 
      {
*************** instantiate_pending_templates (void)
*** 11235,11240 ****
--- 11239,11248 ----
        last_pending_template = last;
      } 
    while (reconsider);
+   /* instantiate_decl increase function depth.  We are safe for GGC
+      here.  */
+   function_depth++;
+   
  
    input_location = saved_loc;
    return instantiated_something;


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