]> git.ipfire.org Git - thirdparty/gcc.git/commit
c: Speed up compilation of large char array initializers when not using #embed
authorJakub Jelinek <jakub@redhat.com>
Wed, 16 Oct 2024 08:22:44 +0000 (10:22 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 16 Oct 2024 08:32:28 +0000 (10:32 +0200)
commitf9bac238840155e1539aa68daf1507ea63c9ed80
tree06ad8bd26b1a0068b711cc8923ab58c692a5247a
parent60ad1e40649244aa219b411c1a1ef5e00ec6a87b
c: Speed up compilation of large char array initializers when not using #embed

The following patch on attempts to speed up compilation of large char array
initializers when one doesn't use #embed in the source.

My testcase has been
unsigned char a[] = {
 #embed "cc1gm2" limit (100000000)
};
and corresponding variant which has the middle line replaced with
dd if=cc1gm bs=100000000 count=1 | xxd -i
With embed 95.3MiB is really fast:
time ./cc1 -quiet -O2 -o test4a.s test4a.c

real    0m0.700s
user    0m0.576s
sys     0m0.123s
Without embed and without this patch it needs around 11GB of RAM and
time ./cc1 -quiet -O2 -o test4b.s test4b.c

real    2m47.230s
user    2m41.548s
sys     0m4.328s
Without embed and with this patch it needs around 3.5GB of RAM and
time ./cc1 -quiet -O2 -o test4b.s2 test4b.c

real    0m25.004s
user    0m23.655s
sys     0m1.308s
Not perfect (but one needs to parse all the numbers, libcpp also creates
strings which are pointed by CPP_NUMBER tokens (that can take up to 4 bytes
per byte), but still almost 7x speed improvement and 3x compile time memory.

One drawback of the patch is that for the larger initializers the precise
locations for -Wconversion warnings are gone when initializing signed char
(or char when it is signed) arrays.

If that is important, perhaps c_maybe_optimize_large_byte_initializer could
tell the caller this is the case and c_parser_initval could emit the
warnings directly when it still knows the location_t and suppress warnings
on the RAW_DATA_CST.

2024-10-16  Jakub Jelinek  <jakub@redhat.com>

* c-tree.h (c_maybe_optimize_large_byte_initializer): Declare.
* c-parser.cc (c_parser_initval): Attempt to optimize large char array
initializers into RAW_DATA_CST.
* c-typeck.cc (c_maybe_optimize_large_byte_initializer): New function.

* c-c++-common/init-1.c: New test.
* c-c++-common/init-2.c: New test.
* c-c++-common/init-3.c: New test.
gcc/c/c-parser.cc
gcc/c/c-tree.h
gcc/c/c-typeck.cc
gcc/testsuite/c-c++-common/init-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/init-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/init-3.c [new file with mode: 0644]