Bug 18938 - Out of memory with many select case statements
Summary: Out of memory with many select case statements
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: memory-hog
Depends on:
Blocks:
 
Reported: 2004-12-11 17:10 UTC by Thomas Koenig
Modified: 2007-02-17 21:43 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-11-13 16:49:10


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2004-12-11 17:10:41 UTC
$ cat multi-case
#! /usr/bin/perl

srand(0);

$last = 100 unless $last = shift;

for ($i=1; $i<=$last; $i++) {
    push(@lines, sprintf("    case(%d)\n     j = %d\n",$i, $last-$i));
}

for ($i=0; $i<=$last; $i++) {
    $j = int(rand($last));
    $temp = $lines[$i];
    $lines[$i] = $lines[$j];
    $lines[$j] = $temp;
}
print "program main\n";
print "  read (*,*) i\n";
print "  select case (i)\n";
print @lines;
printf "  end select\n";
print  "  print *,i,j\n";
print  "end\n";
$ perl multi-case 100000 > multi-case.f90
$ gfortran multi-case.f90

f951: out of memory allocating 1252087640 bytes after a total of 61874176 bytes
$ perl multi-case 5
program main
  read (*,*) i
  select case (i)
    case(3)
     j = 2
    case(4)
     j = 1
    case(2)
     j = 3
    case(1)
     j = 4
    case(5)
     j = 0
  end select
  print *,i,j
end
$ gfortran -v
Reading specs from /home/ig25/lib/gcc/i686-pc-linux-gnu/4.0.0/specs
Configured with: ../gcc/configure --prefix=/home/ig25 --enable-languages=c,c++,f95
Thread model: posix
gcc version 4.0.0 20041208 (experimental)
Comment 1 Andrew Pinski 2004-12-11 17:24:53 UTC
Confirmed, but the problem is not in the front-end this time :).

#4  0x0027c298 in sbitmap_vector_alloc (n_vecs=2416101224, n_elms=100007) at /Users/pinskia/
src/local3/gcc/gcc/sbitmap.c:160
#5  0x002ea824 in make_edges (min=0x9002c768, max=0x51350200, update_p=1) at /Users/
pinskia/src/local3/gcc/gcc/cfgbuild.c:247
#6  0x002eaf84 in find_many_sub_basic_blocks (blocks=0x1) at /Users/pinskia/src/local3/gcc/gcc/
cfgbuild.c:697
#7  0x002b4878 in tree_expand_cfg () at /Users/pinskia/src/local3/gcc/gcc/cfgexpand.c:1322
Comment 2 Steven Bosscher 2004-12-11 21:57:14 UTC
Speculations I'd put money on if the bookies would accept it: 
1) You can show this same problem with C/C++ if you have enough cases. 
2) No compiler can support 2416101224 basic blocks -- but why do we have 
   so many of them?? 
 
 
Comment 3 Thomas Koenig 2004-12-12 10:42:35 UTC
(In reply to comment #2)
> Speculations I'd put money on if the bookies would accept it: 
> 1) You can show this same problem with C/C++ if you have enough cases.

Yes.

$ time ./multi-case-c 150000 > multi-case.c
$ gcc multi-case.c

cc1: out of memory allocating 2815331376 bytes after a total of 10571776 bytes
$ gcc -v
Reading specs from /home/ig25/lib/gcc/i686-pc-linux-gnu/4.0.0/specs
Configured with: ../gcc/configure --prefix=/home/ig25 --enable-languages=c,c++,f95
Thread model: posix
gcc version 4.0.0 20041208 (experimental)
$ cat multi-case-c
#! /usr/bin/perl

$last = shift;

for ($i=1; $i<=$last; $i++) {
    push(@lines, sprintf("    case %d:\n         j = %d;\n    break;\n", $i,
$last-$i));
}
for ($i=0; $i<=$last; $i++) {
    $j = int(rand($last));
    $temp = $lines[$i];
    $lines[$i] = $lines[$j];
    $lines[$j] = $temp;
}
print <<EOF;
#include <stdio.h>
int main()
{
    int i,j;
    scanf("%d",&i);
    switch(i) {
EOF
print @lines;
print <<EOF;
    }
    printf("%d\\n",i);
    return 0;
}
EOF
$ ./multi-case-c 4
#include <stdio.h>
int main()
{
    int i,j;
    scanf("%d",&i);
    switch(i) {
    case 2:
         j = 2;
    break;
    case 4:
         j = 0;
    break;
    case 3:
         j = 1;
    break;
    case 1:
         j = 3;
    break;
    }
    printf("%d\n",i);
    return 0;

This isn't a regression, gcc 3.3 had the same problem:

$ /usr/bin/gcc multi-case.c

cc1: out of memory allocating 2815312608 bytes after a total of 18419712 bytes
$ /usr/bin/gcc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.5/specs
Configured with: ../src/configure -v
--enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr
--mandir=/usr/share/man
--infodir=/usr/share/info--with-gxx-include-dir=/usr/include/c++/3.3
--enable-shared --with-system-zlib --enable-nls --without-included-gettext
--enable-__cxa_atexit --enable-clocale=gnu --enable-debug --enable-java-gc=boehm
--enable-java-awt=xlib --enable-objc-gci486-linux
Thread model: posix
gcc version 3.3.5 (Debian 1:3.3.5-3)
Comment 4 Thomas Koenig 2007-02-17 21:43:20 UTC
This appears to have been fixed in the meantime:

$ perl multi-case-c 300000 > multi-case.c
(reverse-i-search)`g': gcc multi-case.c
$ gdb ~/libexec/gcc/i686-pc-linux-gnu/4.3.0/cc1
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) r multi-case.c
Starting program: /home/ig25/libexec/gcc/i686-pc-linux-gnu/4.3.0/cc1 multi-case.c
Failed to read a valid object file image from memory.
 main {GC 222958k -> 184399k} {GC 274901k -> 263773k}
Execution times (seconds)
 garbage collection    :   4.16 ( 5%) usr   0.02 ( 1%) sys   4.22 ( 5%) wall    0 kB ( 0%) ggc
 cfg cleanup           :   1.83 ( 2%) usr   0.00 ( 0%) sys   1.84 ( 2%) wall    0 kB ( 0%) ggc
 CFG verifier          :  18.25 (24%) usr   0.11 ( 3%) sys  18.53 (23%) wall    0 kB ( 0%) ggc
 trivially dead code   :   0.37 ( 0%) usr   0.00 ( 0%) sys   0.36 ( 0%) wall    0 kB ( 0%) ggc
 life analysis         :   2.12 ( 3%) usr   0.01 ( 0%) sys   2.17 ( 3%) wall    0 kB ( 0%) ggc
 life info update      :   0.82 ( 1%) usr   0.01 ( 0%) sys   0.85 ( 1%) wall    0 kB ( 0%) ggc
 alias analysis        :   0.35 ( 0%) usr   0.00 ( 0%) sys   0.36 ( 0%) wall    0 kB ( 0%) ggc
 register scan         :   0.15 ( 0%) usr   0.00 ( 0%) sys   0.16 ( 0%) wall    0 kB ( 0%) ggc
 rebuild jump labels   :   0.30 ( 0%) usr   0.00 ( 0%) sys   0.30 ( 0%) wall    0 kB ( 0%) ggc
 preprocessing         :   1.41 ( 2%) usr   0.54 (14%) sys   2.39 ( 3%) wall   11181 kB ( 3%) ggc
 lexical analysis      :   0.48 ( 1%) usr   1.45 (36%) sys   1.72 ( 2%) wall    0 kB ( 0%) ggc
 parser                :   8.32 (11%) usr   0.94 (24%) sys   9.34 (11%) wall   73956 kB (17%) ggc
 inline heuristics     :   2.21 ( 3%) usr   0.13 ( 3%) sys   2.35 ( 3%) wall    0 kB ( 0%) ggc
 tree gimplify         :   3.80 ( 5%) usr   0.02 ( 1%) sys   4.11 ( 5%) wall   17283 kB ( 4%) ggc
 tree eh               :   0.29 ( 0%) usr   0.01 ( 0%) sys   0.30 ( 0%) wall    0 kB ( 0%) ggc
 tree CFG construction :   2.01 ( 3%) usr   0.09 ( 2%) sys   2.10 ( 3%) wall  127713 kB (29%) ggc
 tree CFG cleanup      :   1.63 ( 2%) usr   0.01 ( 0%) sys   1.63 ( 2%) wall    0 kB ( 0%) ggc
 tree STMT verifier    :   7.36 (10%) usr   0.26 ( 7%) sys   7.82 (10%) wall    0 kB ( 0%) ggc
 callgraph verifier    :   0.10 ( 0%) usr   0.00 ( 0%) sys   0.10 ( 0%) wall    0 kB ( 0%) ggc
 expand                :   7.56 (10%) usr   0.12 ( 3%) sys   7.79 ( 9%) wall  166651 kB (38%) ggc
 jump                  :   0.37 ( 0%) usr   0.00 ( 0%) sys   0.37 ( 0%) wall    0 kB ( 0%) ggc
 flow analysis         :   0.54 ( 1%) usr   0.01 ( 0%) sys   0.55 ( 1%) wall    0 kB ( 0%) ggc
 mode switching        :   0.04 ( 0%) usr   0.00 ( 0%) sys   0.04 ( 0%) wall    0 kB ( 0%) ggc
 local alloc           :   1.71 ( 2%) usr   0.00 ( 0%) sys   1.68 ( 2%) wall    0 kB ( 0%) ggc
 global alloc          :   6.35 ( 8%) usr   0.11 ( 3%) sys   6.81 ( 8%) wall   42188 kB (10%) ggc
 flow 2                :   0.79 ( 1%) usr   0.00 ( 0%) sys   0.79 ( 1%) wall    1 kB ( 0%) ggc
 final                 :   3.23 ( 4%) usr   0.09 ( 2%) sys   3.45 ( 4%) wall    0 kB ( 0%) ggc
 TOTAL                 :  76.56             3.99            82.20             439966 kB
Extra diagnostic checks enabled; compiler may run slowly.
Configure with --disable-checking to disable checks.

Program exited normally.

Closing.