C++ PATCH to defer RTL generation for inlines

Mark Mitchell mark@codesourcery.com
Sat Nov 27 10:23:00 GMT 1999


This patch, for the still disabled inlining-on-trees, shows the first
major win from this change: dramatically reduced compile-times and
memory usage.  By not generating RTL for functions we're not going to
write out, and instead doing inlining on trees, we win big-time.

On one of my benchmark test-cases, this patch reduces memory usage
from 247MB to 157MB and compile-time from 313 seconds to 119 seconds.

Next will be to get debugging information correct for the inlined
functions; at that point, I'll turn this stuff on by default.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-11-27  Mark Mitchell  <mark@codesourcery.com>

	* decl2.c (finish_file): Call expand_body for inline functions
	that will be written out but that do not yet have RTL.
	* semantics.c (expand_body): Do not generate RTL For inline
	functions that do not yet need to be written out.

Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.284
diff -c -p -r1.284 decl2.c
*** decl2.c	1999/11/25 20:32:03	1.284
--- decl2.c	1999/11/27 18:01:03
*************** finish_file ()
*** 3531,3536 ****
--- 3531,3566 ----
  	      && DECL_INITIAL (decl)
  	      && (DECL_NEEDED_P (decl) || !DECL_COMDAT (decl)))
  	    DECL_EXTERNAL (decl) = 0;
+ 
+ 	  /* If we're going to need to write this function out, and
+ 	     there's already a body for it, create RTL for it now.
+ 	     (There might be no body if this is a method we haven't
+ 	     gotten around to synthesizing yet.)  */
+ 	  if (!DECL_EXTERNAL (decl)
+ 	      && (DECL_NEEDED_P (decl) || !DECL_COMDAT (decl))
+ 	      && DECL_SAVED_TREE (decl)
+ 	      && !DECL_SAVED_INSNS (decl)
+ 	      && !TREE_ASM_WRITTEN (decl))
+ 	    {
+ 	      int saved_not_really_extern;
+ 
+ 	      /* When we call finish_function in expand_body, it will
+ 		 try to reset DECL_NOT_REALLY_EXTERN so we save and
+ 		 restore it here.  */
+ 	      saved_not_really = DECL_NOT_REALLY_EXTERN (decl);
+ 	      /* Generate RTL for this function now that we know we
+ 		 need it.  */
+ 	      expand_body (decl);
+ 	      /* Undo the damage done by finish_function.  */
+ 	      DECL_EXTERNAL (decl) = 0;
+ 	      DECL_NOT_REALLY_EXTERN (decl) = saved_not_really_extern;
+ 	      /* If we're compiling -fsyntax-only pretend that this
+ 		 function has been written out so that we don't try to
+ 		 expand it again.  */
+ 	      if (flag_syntax_only)
+ 		TREE_ASM_WRITTEN (decl) = 1;
+ 	      reconsider = 1;
+ 	    }
  	}
  
        if (saved_inlines_used
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.110
diff -c -p -r1.110 semantics.c
*** semantics.c	1999/11/25 20:32:04	1.110
--- semantics.c	1999/11/27 18:01:04
*************** expand_body (fn)
*** 2535,2540 ****
--- 2535,2573 ----
    if (flag_syntax_only)
      return;
  
+   /* If possible, avoid generating RTL for this function.  Instead,
+      just record it as an inline function, and wait until end-of-file
+      to decide whether to write it out or not.  */
+   if (/* We have to generate RTL if we can't inline trees.  */
+       flag_inline_trees
+       /* Or if it's not an inline function.  */
+       && DECL_INLINE (fn)
+       /* Or if we have to keep all inline functions anyhow.  */
+       && !flag_keep_inline_functions
+       /* Or if we actually have a reference to the function.  */
+       && !DECL_NEEDED_P (fn)
+       /* Or if we're at the end-of-file, and this function is not
+ 	 DECL_COMDAT.  */
+       && (!at_eof || DECL_COMDAT (fn))
+       /* Or if this is a nested function.  */
+       && !hack_decl_function_context (fn))
+     {
+       /* Give the function RTL now so that we can assign it to a
+ 	 function pointer, etc.  */
+       make_function_rtl (fn);
+       /* Set DECL_EXTERNAL so that assemble_external will be called as
+ 	 necessary.  We'll clear it again in finish_file.  */
+       if (!DECL_EXTERNAL (fn))
+ 	{
+ 	  DECL_NOT_REALLY_EXTERN (fn) = 1;
+ 	  DECL_EXTERNAL (fn) = 1;
+ 	}
+       /* Remember this function.  In finish_file we'll decide if
+ 	 we actually need to write this function out.  */
+       mark_inline_for_output (fn);
+       return;
+     }
+ 
    /* Optimize the body of the function before expanding it.  */
    optimize_function (fn);
  


More information about the Gcc-patches mailing list