What is lto1.exe? - gcc

when you inspect mingw you will find the c compiler cc1.exe (funny growing in size in 9.2 it is almost 25 MB ) cc1plus.exe is c++ compiler (same sizes) collect2.exe is linker (afiak) nut what is lto1.exe?
i googled for it more than hour but not found info on this.. is there some good info on this avaliable to read? tnx
ps. i suspect that it may be related to link time optimisation but found nothing more about it and i would like to know better
there is also a question what is gcc.exe g++.exe and mingw32-gcc.exe mingw32-g++.exe then
i need more informatin, the most the better , tnx

This is not mingw / Windos specific; it's a feature / component of GCC.
what is lto1.exe?
It's the lto compiler :o). lto is basically byte code written when compiled with -flto where "lto" or "LTO" stands for "link-time optimization".
These optimizations are not performed by the linker but by the compiler at link time to perform global optimizations when (byte-)code from all the modules is available. The flow is as follows:
The C/C++ compiler (cc1 for C or cc1plus for C++) compiles C/C++ to byte-code and writes it to the assembly file *.s.
Assembly is assembled by the assembler to object code *.o as usual. lto-code is shipped in dedicated sections.
At link time, the linker (plugin) calls back the compiler and supplies all the objects and libraries as requested. byte-code is extracted, and the lto1 compiler compiles it to final machine code.
The final machine code is assembled by the assembler to object code.
The linker links / locates these objects to final executable code.
You see the byte-code in the lto sections with -save-temps and having a look at the saved *.s files. Recent versions of GCC don't even bother with writing assembly code; they are just writing lto code. To see the assembly code, specify -ffat-lto-objects. Notice however that this is not the final code.
funny growing in size in 9.2 it is almost 25 MB
The sizes of GCC executables depend not only on the GCC major version, but also highly on how well the compiler used to build GCC is optimizing.
[Edit] Some information on LTO can be found on the GCC wiki for LTO. Notice however that this page is no more active. One goto place for gory GCC internals is the gcc-help#gcc.gnu.org mailing list where all the developers are. There is also a section about LTO in the GCC internals.

Related

gcc's option dose not work until newer version

I recently struggle with gcc's optimization, hope to help with performance improvement.
I found the option -freorder-blocks-and-partition.
(This option exist on very old versions of gcc, such as gcc 5.6.)
It can be used to partition cold/hot cold to separate function, together with -ffunction-sections and linker script, cold/hot code can be put into separate ELF sections (.text section and .text.cold section).
But this option only works on recent gcc version.
I test it on gcc 10.1, and use the following compiler exploration tool, make sure it works start from version 8.1:
in gcc8.1: https://godbolt.org/z/hGcnMM, the assembly code contains a function like this:
fa(int, int) [clone .cold.0]:
In gcc7.1: https://godbolt.org/z/rhqjE1, the assembly code does not contain such function.
Why does it not work on older gcc?
And is there any way to control the older version gcc to apply this optimization?

What's the relationship between "gcc linking" and "ld linking"?

It's said that linux loader is /usr/bin/ld, but usually we use gcc/g++ to link libraries and executables, we barely use "ld".
The last time I used "ld" manually was when I was learning linux assembly, the only way to generate executable is to ld a .o file to generate executable directly without any library.
My question is, is gcc/g++ containing some function wrappers of "ld", because raw "ld" is too difficult to use? Or we should never use "ld" explicitly for c/c++ program linking, because of blablabla?
gcc supplies a few default options to ld.
ld doesn't know anything about C++, or any other language. ld has no idea what libraries your code needs to link with. If you try to link your compiled C++ code with ld directly, it'll bail out on you, since ld, by itself, has no idea where it can find libstdc++, gcc's C++ runtime library. Do you use strings? vectors? Most of that is template code that gets compiled as part of your object module. But there are a still few precompiled bits, in libstdc++, that need to be linked with.
When you give your compiled code to gcc to link, gcc will be courteous enough to pass all your files along to ld, and tell ld which libraries, in addition to any ones you explicitly specify.
You can link with ld directly, if you want to, as long as you specify the same libraries and link option gcc uses. But why would you want to do that? Just use gcc to link your gcc-compiled code.
You shouldn't attempt to directly use ld to link a C++ program because you need to know the implementation detail of where the static part of the C++ runtime library is located. g++ knows these implementation details, such as where to find the file libstdc++.a. If you tried to use ld directly, you would have to supply all these "missing" static libraries.
My question is, is gcc/g++ containing some function wrappers of "ld"
That's right.
because raw "ld" is too difficult to use?
Well, not really; you could use it yourself without too much trouble, but it's convenient to manage the entire build process through a single executable, with a single suite of flags, and often with a single command.
It's also likely that you'd have to provide absolute paths to some runtime libraries (e.g. libstdc++.a) yourself if you bypassed the wrapper (though I haven't tested this).
Or we should never use "ld" explicitly for c/c++ program linking, because of blablabla?
You're free to do so if you want. The only reason people might raise their eyebrows is to ask why you're not doing it in the conventional manner. If you have a good reason to invoke ld directly, rather than going through g++ and passing through any linker flags that way, then go right ahead!

When to use certain optimizations such as -fwhole-program and -fprofile-generate with several shared libraries

Probably a simple answer; I get quite confused with the language used in the GCC documentation for some of these flags!
Anyway, I have three libraries and a program which uses all these three. I compile each of my libraries separately with individual (potentially) different sets of warning flags. However, I compile all three libraries with the same set of optimisation flags.
I then compile my main programme linking in these three libraries with its own set of warning flags and the same optimisation flags used during the libraries' compilation.
1) Do I have to compile the libraries with optimisation flags present or can I just use these flags when compiling the final program and linking to the libraries? If the latter, will it then optimise all or just some (presumably that which is called) of the code in these libraries?
2) I would like to use -fwhole-program -flto -fuse-linker-plugin and the linker plugin gold. At which stage do I compile with these on ... just the final compilation or do these flags need to be present during the compilation of the libraries?
3) Pretty much the same as 2) however with, -fprofile-generate -fprofile-arcs and -fprofile-use. I understand one first runs a programme with generate, and then with use. However, do I have to compile each of the libraries with generate/use etc. or just the final programme? And if it is just the last program, when I then compile with -fprofile-use will it also optimise the libraries functionality?
I then compile my main programme linking in these three libraries with
its own set of warning flags and the same optimisation flags used
during the libraries' compilation.
There are two steps here, not one. Compiling the main program to produce an object file is the first and then linking everything together to produce an executable binary is the second step.
1) Do I have to compile the libraries with optimisation flags present
or can I just use these flags when compiling the final program and
linking to the libraries? If the latter, will it then optimise all or
just some (presumably that which is called) of the code in these
libraries?
Optimization flags and any other compiler-level flags must be specified per source code file. Every time a source file is compiled to produce an object file, you need to specify the flags. Then producing a library or an executable is done by the linker using a different set of flags for the linker.
2) I would like to use -fwhole-program -flto -fuse-linker-plugin and
the linker plugin gold. At which stage do I compile with these on ...
just the final compilation or do these flags need to be present during
the compilation of the libraries?
You have to specify -flto when compiling each source code file (or those that are available to you). You do not need to specify -fuse-linker-plugin and -fwhole-program when using the gold linker or GNU ld 2.21 or newer. For more information, see the documentation on -flto.
3) Pretty much the same as 2) however with, -fprofile-generate
-fprofile-arcs and -fprofile-use. I understand one first runs a programme with generate, and then with use. However, do I have to
compile each of the libraries with generate/use etc. or just the final
programme? And if it is just the last program, when I then compile
with -fprofile-use will it also optimise the libraries functionality?
Same as 2. These flags need to be specified per source code file so that all code is optimized.
Note that, in case you don't have the source code, you can still link static or dynamic libraries that were not optimized with the same flags and the code will work. That is, you can mix code that is optimized at different levels.

How can I optimize LLVM assembly cross-compiled with gcc?

I am using LLVM to generate Alpha assembly. Their Alpha ISA support is experimental and I cannot find a way to work around a bug. If I use -O0 during LLVM bytecode-to-Alpha assembly creation, the assembly generated is fine.
I want optimized assembly, however. Is there some option in gcc (which is my final cross compiler) that would optimize the assembly? I tried -O3 while converting the Alpha assembly to object file, but I did not see any optimization happening. Is it even possible to do back-end optimization after assembly creation?
If you want optimized assembly, you obviously should ask LLVM for it. So pass -O3 to llc, not to gcc.

Migrating from Winarm to Yagarto

This question must apply to so few people...
I am busy mrigrating my ARM C project from Winarm GCC 4.1.2 to Yagarto GCC 4.3.3.
I did not expect any differences and both compile my project happily using the same makefile and .ld files.
However while the Winarm version runs the Yagarto version doesn't. The processor is an Atmel AT91SAM7S.
Any ideas on where to look would be most welcome. i am thinking that my assumption that a makefile is a makefile is incorrect or that the .ld file for Winarm is not applicable to Yagarto.
Since they are both GCC toolchains and presumably use the same linker they must surely be compatable.
TIA
Ends.
I agree that the gcc's and the other binaries (ld) should be the same or close enough for you not to notice the differences. but the startup code whether it is your or theirs, and the C library can make a big difference. Enough to make the difference between success and failure when trying to use the same source and linker script. Now if this is 100% your code, no libraries or any other files being used from WinARM or Yagarto then this doesnt make much sense. 3.x.x to 4.x.x yes I had to re-spin my linker scripts, but 4.1.x to 4.3.x I dont remember having problems there.
It could also be a subtle difference in compiler behavior: code generation does change from gcc release to gcc release, and if your code contains pieces which are implementation-dependent for their semantics, it might well bite you in this way. Memory layouts of data might change, for example, and code that accidentally relied on it would break.
Seen that happen a lot of times.
Try it with different optimization options in the compile and see if that makes a difference.
Both WinARM and YAGARTO are based on gcc and should treat ld files equally. Also both are using gnu make utility - make files will be processed the same way. You can compare the two toolchains here and here.
If you are running your project with an OCD, then there is a difference between the implementation of the OpenOCD debugger. Also the commands sent to the debugger to configure it could be different.
If you are producing an hex file, then this could be different as the two toolchains are not using the same version of newlib library.
In order to be on the safe side, make sure that in both cases the correct binutils are first in the path.
If I were you I'd check the compilation/linker flags - specifically the defaults. It is very common for different toolchains to have different default ABIs or FP conventions. It might even be compiling using an instruction set extension that isn't supported by your CPU.

Resources