$ 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)
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
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??
(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)
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.