tests for compiler (non-)limits

Jakub Jelinek jakub@redhat.com
Thu Dec 13 13:04:00 GMT 2007

On Wed, May 30, 2007 at 05:19:36PM -0700, Geoffrey Keating wrote:
> On 30/05/2007, at 2:21 PM, Richard Guenther wrote:
> >
> >>       * gcc.c-torture/compile/limits-structnest.c: New.
> >
> >This one makes me swap and cry.  Please throttle it down one  
> >magnitude.
> It would be better if you could work out why it's causing you to swap  
> and fix that instead; it didn't seem to require 1G of RAM on my system  
> and there's no reason why it should, that would imply that each  
> structure definition is taking 100K, for a structure with one field!   
> Perhaps this is a recent regression?  Could you narrow it down to a  
> specific patch?

I don't believe this.  On x86_64-linux, if I

ulimit -Sv $((1500*1024))


/usr/src/gcc-3.2/obj/gcc/cc1 -O2 limits-structnest.c
limits-structnest.c:21: memory exhausted before '{' token

Execution times (seconds)
 lexical analysis      :   0.00 ( 0%) usr   0.01 (100%) sys   0.00 ( 0%) wall
 parser                :   0.02 (100%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall
 TOTAL                 :   0.02             0.01             0.00

/usr/src/gcc-3.3/obj/gcc/cc1 -O2 limits-structnest.c

cc1: out of memory allocating 32 bytes after a total of 1485455360 bytes

/usr/src/gcc-3.4/obj/gcc/cc1 -O2 limits-structnest.c

Analyzing compilation unit
Performing intraprocedural optimizations
Assembling functions:
virtual memory exhausted: Cannot allocate memory

/usr/src/gcc-4.1/obj/gcc/cc1 -O2 limits-structnest.c

Analyzing compilation unitPerforming intraprocedural optimizations
Assembling functions:
virtual memory exhausted: Cannot allocate memory

/usr/src/gcc/obj/gcc/cc1 -O2 limits-structnest.c	# trunk

Analyzing compilation unit
 {GC 8427k -> 7339k}Performing interprocedural optimizations
 <visibility> <early_local_cleanups> <inline> <static-var> <pure-const>Assembling functions:
virtual memory exhausted: Cannot allocate memory

The place where all the memory is eaten is during get_alias_set on the
structure. get_alias_set is called on this testcase just 20001 times (twice
for each struct, but each second time TYPE_ALIAS_SET_KNOWN_P is already true
and therefore it is cheap).  But then record_alias_subset will:
          splay_tree_foreach (subset_entry->children, insert_subset_children,
so it is quadratic and given that splay tree nodes are 32B on 64-bit hosts
(4 pointers) that corresponds to that 10000 * 10000 / 2 * 32 ~= 1.5GB of
memory.  On 32-bit hosts, you can get away with just half of that memory.

So decreasing the testcase to have 5000 instead of 10000 nested structs would
help a lot - 400MB (resp. 200MB for 32-bit) is already bearable.  Note that
many of us build/regtest gcc with very high make -j factors and so even if
you have 2GB of RAM this is a problem.

Alternatively, we could perhaps punt if some alias set has too many subsets
(perhaps add a new --param for that).  We have the has_zero_child field of
struct alias_set_entry, which effectively makes the alias set similar to
alias set 0, so we wouldn't need to record any children.  At least as far as
alias_sets_conflict_p is concerned.  We unfortunately have also
the alias_set_subset_of function, which doesn't look at has_zero_child,
not sure if that's a bug or not.  If that's intentional, we could introduce
another bool flag along has_zero_child - children_throttled or something,
and if some subset has more than param (default e.g. 1000) children,
set has_zero_child, children_throttled and not add any children, then
let alias_set_subset_of return true if ase->children_throttled.


More information about the Gcc-patches mailing list