Trace gcc compilation and what code slows it down - c++

I want to find out what code causes slow compilation times in gcc. I previously had a code being compiled slowly and someone told me the command-line switch that makes gcc to print each step that it compiles, including each function/variable/symbol and so on. That helped a lot (I could literally see in console where gcc chokes), but I forgot what was the switch.

I found it (from the gcc man page):
-Q
Makes the compiler print out each function name as it is compiled, and print some statistics about each pass when it finishes.

See also this answer to a quite similar question.
You very probably want to invoke GCC with -time or more probably -ftime-report which gives you the time spent by cc1 or cc1plus ... (the compiler proper started by the gcc or g++command) which shows the time spent in each internal phases or passes of the GCC compiler. Don't forget also optimizations, debugging, and warnings flags (e.g. -Wall -O -g); they all slow down the compilation.
You'll learn that for C programs, parsing is a small fraction of the compilation time, as soon as you ask for some optimization, e.g. -O1 or -O2. (This is less true for C++, when parsing can take half of the time, notably since template expansion is considered as parsing).
Empirically, what slows down GCC are very long function bodies. Better have 50 functions of 1000 lines each than one single function of 50000 lines (and this could happen in programs generating some of their C++ code, e.g. RefPerSys or perhaps -in spring 2021- Bismon).

Try the -v (verbose) compilation.
See this link:
http://www.network-theory.co.uk/docs/gccintro/gccintro_75.html
edit:
I understand. Maybe this will help:
gcc -fdump-tree-all -fdump-rtl-all
and the like (-fdump-passes). See here: http://fizz.phys.dal.ca/~jordan/gcc-4.0.1/gcc/Debugging-Options.html

Related

g++/clang++ Invert compilation error order

g++ and clang++ report compilation errors with the first erroneous line encountered at the top of their output. That is, the first line clang/g++ print on a compilation error are the one you usually care about. As I'm sure we have all experienced, you have to scroll up (often a lot) to see what the nasty error is. Is there any compilation flag (in clang++ or in g++) that presents compilation errors in reverse order?
I saw this question which asked the same thing I'm asking, but about GHC and thought about how much of a useful option this would be for C++ projects. I've never heard of this for clang++ or g++, and I couldn't find anything online nor on their man pages.

Why does gcc -O1 behave differently than gcc -O0 + options

Given that the gcc documentation (https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc.pdf) specifies that -O1 is -O0 plus a specific list of options, why is it when I time compiling my code with -O1 it takes 2 times longer to compile than using -O0 + all the options listed as being enabled when -O1 is turned on? Are there other options that are being enabled that are not specified in the documentation (my suspicion), or is there something else, more sinister, happening in the background?
If the documentation is just out of date, that would be something I'd be interested in knowing about, if only to better understand the optimization options available for GCC and my code.
If the documentation is just out of date ...
It is a fair assumption that the documentation is inaccurate. Stuff like that happens.
Another possibility is that you have misread the documentation. My reading of the document you linked to (page 111) is that -O and -O1 are supposed to mean the same thing. If that is correct, then what you are apparently trying to do doesn't make much sense.
I suggest that you look at the GCC source code to figure out exactly how -O1 is implemented. That should tell you whether the behavior you are seeing can be explained by inaccurate documentation1, or whether there is something else going on here.
1 - If the problem is inaccurate documentation, you can help the GCC folks and ultimately other GCC users by submitting a bug report with corrections.

max number of allowable warnings while compiling

Is it possible to 'tell' compiler that if total number of warnings (while compiling a C++ program) are more than say 10 then stop compiling further, and emit an error?
Or is it possible to hack a compiler like clang to provide this functionality.
GCC has two options together would achieve this, from gnu online docs:
-Werror
Make all warnings into errors.
-fmax-errors=n
Limits the maximum number of error messages to n, at which point GCC bails out rather than attempting to continue processing the source
code.
This would make a build with any warnings fail though, the options just define when to stop parsing.
I haven't seen this kind of feature in gcc or clang. You can certainly try to patch it into either of them, both are open source. There is also -Werror (accepted by both compilers) which simply treats warnings as errors.
How about using -Werror to make warnings into errors and -fmax-errors=n to set the limit.
(Also, perhaps making your code completely warning free would be a good thing).

g++ Optimization Flags: -fuse-linker-plugin vs -fwhole-program

I am reading:
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
It first suggests:
In combination with -flto using this option (-fwhole-program) should not be used. Instead relying on a linker plugin should provide safer and more precise information.
And then, it suggests:
If the program does not require any symbols to be exported, it is possible to combine -flto and -fwhole-program to allow the interprocedural optimizers to use more aggressive assumptions which may lead to improved optimization opportunities. Use of -fwhole-program is not needed when linker plugin is active (see -fuse-linker-plugin).
Does it mean that in theory, using -fuse-linker-plugin with -flto always gets a better optimized executable than using -fwhole-program with -flto?
I tried to use ld to link with -fuse-linker-plugin and -fwhole-program separately, and the executables' sizes at least are different.
P.S. I am using gcc 4.6.2, and ld 2.21.53.0.1 on CentOS 6.
UPDATE: See #PeterCordes comment below. Essentially, -fuse-linker-plugin is no longer necessary.
These differences are subtle. First, understand what -flto actually does. It essentially creates an output that can be optimized later (at "link-time").
What -fwhole-program does is assumes "that the current compilation unit represents the whole program being compiled" whether or not that is actually the case. Therefore, GCC will assume that it knows all of the places that call a particular function. As it says, it might use more aggressive inter-procedural optimizers. I'll explain that in a bit.
Lastly, what -fuse-linker-plugin does is actually perform the optimizations at link time that would normally be done as each compilation unit is performed. So, this one is designed to pair with -flto because -flto means save enough information to do optimizations later and -fuse-linker-plugin means actually do those optimizations.
So, where do they differ? Well, as GCC doc suggests, there is no advantage in principle of using -fwhole-program because that option assumes something that you then have to ensure is true. To break it, simply define a function in one .cpp file and use it in another. You will get a linker error.
Is there any advantage to -fwhole-program? Well, if you only have one compilation unit then you can use it, but honestly, it won't be any better. I was able to get different sized executables by using equivalent programs, but when checking the actual generated machine code, they were identical. In fact, the only differences that I saw were that line numbers with debugging information were different.

g++ compilation of a separately preprocessed file gives error depending on the architecture

I am using g++ version 4.1.2 on a x64_86 GNU linux architecture. Code base is very huge and I don't have sufficient understanding of makefiles used in the project. The code compiles fine as it is.
For some debugging purpose, I need to preprocess (g++ -E) few source files individually and then re-compile it. I am giving the required include paths using -I. Ideally the compilation should go fine.
But I am getting few discrepancies in standard headers like:
typedef unsigned long size_t; causes errors with operator new()
declaration generated by compiler (if I change to unsigned int
manually then this error disappears)
In library functions like unsigned long numeric_limits<>::max(),
compiler complains for big numbers such as 922...807L; it generates
compiler error as integer constant is too large for long type
Mismatch declaration of __errorno_location() gives compiler error
I am having hard time finding what is going wrong. Why compilation goes fine when I do make on unchanged file and why standard headers start cribbing when I give g++ -I <> -E option on individual file ?
(Note that there is no problem with the code we have written, it's just from standard library side. I tried locating the stddef.h which has unsigned int as typedef, but that just fixes the 1st problem. )
Any idea to fix this errors would be highly appreciated.
Don't preprocess and compile separately, or if you must then use consistent compiler options and a consistent environment.
It sounds a though you're running the preprocessor on a 32-bit machine (or using the -m32 option) then compiling on a 64-bit machine.
When compiling the output of the preprocessor, make sure that you use the-fpreprocessed compiler option so that the preprocessor will not run again.
If you don't pass in that option certain constructs that produced identifiers that look like macros may get expanded again into something they shouldn't get expanded to. It's hard for me to come up with a case that shows a difference (I'm sure I can, but it would take a bit of puzzling out and would be pretty contrived). However, the implementation headers may well use some arcane macro techniques that might be sensitive to this option.