[m-users.] Link-time optimization

Peter Wang novalazy at gmail.com
Sat Jun 13 12:24:16 AEST 2020


Hi,

On Fri, 12 Jun 2020 22:27:28 +0200 Massimo Dentico <m.dentico at virgilio.it> wrote:
> 
> I were somewhat disappointed by the size of executable produced by the
> Mercury compiler. A cursory inspection of the C source files produced
> revealed the most probable source of such large executables: most (all?)
> of the run-time library is always linked in. More on this later.

Also the standard library.

> In the last months I were distracted by other things but the very
> interesting results in this Peter Wang's email of January caught my
> attention:
> 
>     * [m-dev.] LTO benchmarks
>  
> http://lists.mercurylang.org/archives/developers/2020-January/017070.html
> 
> I recompiled mercury-srcdist-20.01.2 with this shell script:
> 
>     export CFLAGS="-Os -flto -fuse-linker-plugin"
>     export GRADE="hlc.gc"
>     export EXTRA_MCFLAGS="-O5 --intermod-opt"
>     make PARALLEL=-j2
>     make PARALLEL=-j2 install
> 
> with this results:
> 
>     real    167m36.827s
>     user    13m42.766s
>     sys     48m28.633s
> 
>     mercury_compile.exe 21.5 MiB (22'552'436 bytes)
> 
> (Yes, it was slow, I have a 14 years old machine at home, Intel Pentium
> E2160, 1M Cache, 1.80 GHz, 800 MHz FSB; sources and target directory
> onto an SSD.)
> 
> 21.5 MiB is better than ~30 MiB of the preceding compile without LTO but
> it still isn't ~10 MiB documented by Peter (gcc-lto — yes, I see that
> GCC version is different and he is on Linux, but a difference of ~10 MiB
> seems too much to me).

The Linux binaries do not include the C standard library, which is
dynamically linked by default. I believe your Windows binaries will
statically link the C library so that would make up at least part of the
difference.

> 
> Compiling "mercury-srcdist-20.01.2/samples/hello.m" with
> 
>     $ mmc --mercury-linkage static -s hlc.gc -O5 --intermod-opt hello.m
> 
> gives a 3.02 MiB (3'174'400 bytes) "hello.exe".
> With
> 
>     $ export CFLAGS="-Os -flto -fuse-linker-plugin"
>     $ mmc --mercury-linkage static -s hlc.gc -O5 --intermod-opt hello.m
> 
> the difference is negligible: 3.02 MiB (3'173'376 bytes).

For comparison, here is hello.m built on Linux using the gcc-lto
installation I made in January:

    dynamically linked to glibc:  535032 bytes
    statically linked to glibc:  1368664 bytes

BTW, a simpler (faster?) option for reducing binary sizes is using the
gcc and clang options -ffunction-sections -fdata-sections,
and the linker option --gc-sections.
http://lists.mercurylang.org/archives/reviews/2014-August/017151.html

> b. How much effort would be needed to modify the Mercury compiler
>     (specifically the back-end that produces high-level C code)
>     to produce a single stand-alone C file? That is, a single source file
>     easy to include in other C projects, which has *only* the necessary
>     machinery from the run-time library and refers to C standard
>     libraries only, with an option to avoid them too.

A lot of effort.

Peter


More information about the users mailing list