While looking at the -fmem-stats results for this testcase, I noticed about 500MB of overhead coming from the VEC_safe_push in cp_lexer_new_main. This is happening because when we allocate space for a vector, the allocator pads it out some, and that space ends up lost. The first patch changes the vector code to ask the gc allocator how much space it's really going to get, and adjust the number of slots to fill that space. This reduces the VM footprint of the compiler for the testcase from 1704 MB to 1162 MB, an almost 32% reduction.

The second patch is derived from Jan's patch of

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12245#c42

and further reduces the VM footprint to 967 MB, not quite back to the 2.95 level of 717 MB, but pretty close.

Tested x86_64-pc-linux-gnu.  Are one or both of these OK for trunk?
commit 75f153fdd2166feeaa9fcc982951537c7c1cb4a7
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Jan 13 17:53:50 2012 -0500

    	PR c++/14179
    	* vec.c (vec_gc_o_reserve_1): Use ggc_round_alloc_size.

diff --git a/gcc/vec.c b/gcc/vec.c
index c1d0034..783a3cf 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -221,6 +221,7 @@ vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
 {
   struct vec_prefix *pfx = (struct vec_prefix *) vec;
   unsigned alloc = calculate_allocation (pfx, reserve, exact);
+  size_t size;
 
   if (!alloc)
     {
@@ -229,7 +230,17 @@ vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
       return NULL;
     }
 
-  vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT);
+  /* Calculate the amount of space we want.  */
+  size = vec_offset + alloc * elt_size;
+  /* Ask the allocator how much space it will really give us.  */
+  size = ggc_round_alloc_size (size);
+  /* Adjust the number of slots accordingly.  */
+  alloc = (size - vec_offset) / elt_size;
+  /* And finally, recalculate the amount of space we ask for.  */
+  size = vec_offset + alloc * elt_size;
+
+  vec = ggc_realloc_stat (vec, size PASS_MEM_STAT);
+
   ((struct vec_prefix *)vec)->alloc = alloc;
   if (!pfx)
     ((struct vec_prefix *)vec)->num = 0;
commit a18a514aa781b65048e69330564197b0692978aa
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Jan 13 17:54:44 2012 -0500

    	PR c/12245
    	PR c++/14179
    	* convert.c (convert_to_integer): Use fold_convert for
    	converting an INTEGER_CST to integer type.

diff --git a/gcc/convert.c b/gcc/convert.c
index f04b204..dbe2c7e 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -860,6 +860,10 @@ convert_to_integer (tree type, tree expr)
 	  break;
 	}
 
+      /* When parsing long initializers, we might end up with a lot of casts.
+	 Shortcut this.  */
+      if (TREE_CODE (expr) == INTEGER_CST)
+	return fold_convert (type, expr);
       return build1 (CONVERT_EXPR, type, expr);
 
     case REAL_TYPE:

Reply via email to