Does GCC merge files compiled together? - gcc

Let's say that you have prog.c that includes lib.h, whose functions are defined in lib.c, and you build the program with ̀gcc -O3 lib.c prog.c.
Does GCC merge both source files before compiling them?
Is GCC able to inline short functions of lib.c into the resulting binary?
Summary of answers
This does the trick: gcc -flto -O3 lib.c prog.c.
Both source files are still compiled individually, but the linker is able to inline functions from one file into the other one.

Does GCC merge both source files before compiling them?
No, it doesn't
Is GCC able to inline short functions of lib.c into the resulting binary?
Yes, at advanced optimization level. Look at Whole Program Optimization, Link Time Optimization and similar options

Related

Getting assember output from GCC/Clang in LTO mode

Normally, one can get GCC's optimized assembler output from a source file using the -S flag in GCC and Clang, as in the following example.
gcc -O3 -S -c -o foo.s foo.c
But suppose I compile all of my source files using -O3 -flto to enable link-time whole-program optimizations and want to see the final compiler-generated optimized assembly for a function, and/or see where/how code gets inlined.
The result of compiling is a bunch of .o files which are really IR files disguised as object files, as expected. In linking an executable or shared library, these are then smushed together, optimized as a whole, and then compiled into the target binary.
But what if I want assembly output from this procedure? That is, the assembly source that results after link-time optimizations, during the compilation of IR to assembly, and before the actual assembly and linkage into the final executable.
I tried simply adding a -S flag to the link step, but that didn't really work.
I know disassembling the executable is possible, even interleaving with source, but sometimes it's nicer to look at actual compiler-generated assembly, especially with -fverbose-asm.
For GCC just add -save-temps to linker command:
$ gcc -flto -save-temps ... *.o -o bin/libsortcheck.so
$ ls -1
...
libsortcheck.so.ltrans0.s
For Clang the situation is more complicated. In case you use GNU ld (default or -fuse-ld=ld) or Gold linker (enabled via -fuse-ld=gold), you need to run with -Wl,-plugin-opt=emit-asm:
$ clang tmp.c -flto -Wl,-plugin-opt=emit-asm -o tmp.s
For newer (11+) versions of LLD linker (enabled via -fuse-ld=lld) you can generate asm with -Wl,--lto-emit-asm.

Discard unused functions in GCC [duplicate]

This question already has answers here:
How to remove unused C/C++ symbols with GCC and ld?
(11 answers)
Closed 6 years ago.
I need some help for compiling with GCC under MinGW.
Say I have two files:
File a.c contains two functions, a1 and a2
File b.c contains two functions, b1 and b2.
Then I link the two objects into a shared library. The command used are like:
gcc -c a.c
gcc -c b.c
gcc -shared -Wl, --version-script v.ver -Wl, -Map=out.map -Wl, --strip-all -o mydll.dll a.o b.o
File v.ver looks like:
mylib {
global: a1;
a2;
local: *;
}
which is used to control which functions to be exported.
By checking the mapfile I can see that the two functions in b.c are also included into the .text section of the DLL file.
Because this DLL file only exports a1 and a2, and b1 and b2 are only defined in b.c, but never used anywhere. Is there an option I could add in GCC or ld so that b1 and b2 are not built into the DLL file so that I can save some space in the DLL file?
Yes, this is possible. To do this, add the following two flags when compiling your C source code to objects:
-ffunction-sections -fdata-sections
This will generate bigger object files, but will add a lot of information for the linker.
When calling the linker add the following flag:
--gc-sections
The linker will now throw away all functions and sections that are not used. Note that this might incur a performance penalty:
Only use these options when there are significant benefits from doing
so. When you specify these options, the assembler and linker create
larger object and executable files and are also slower. These options
affect code generation. They prevent
optimizations by the compiler and assembler using relative locations inside a translation unit since the locations are unknown
until link time. An example of such an optimization is relaxing calls
to short call instructions.
(man gcc)
See also this question: Query on -ffunction-section & -fdata-sections options of gcc for more information.

Using -flto with autotools

Given a C++ program that uses GNU autotools, what's the easiest way to compile it with -flto (link time optimization)? My understanding is that it is customary on Unix for such optimization flags to be specified by the user or packager, not by the programmer.
According to this post, the -flto flag needs to be passed as a compilation flag and as a linker flag, so:
./configure CXXFLAGS="-flto" LDFLAGS="-flto" ...
or possibly:
./configure CXXFLAGS="-flto" LDFLAGS="-Wc,-flto" ...
might work.

using openmp with a makefile and g++

I am building a large project with a makefile that was originally built with icpc, and now I need to get it running with g++.
When it compiles the file that uses openmp, it uses the -c flag, and doesn't use any libraries, so it ends up being serial instead of openmp. All of the examples I am seeing aren't using this -c flag.
Is there some way to compile without linking, but using openmp?
edit:
I've been using the -lgomp flag(and the library is on the library path):
g++ -lgomp -c -w -O4 mainS.cpp
g++: -lgomp: linker input file unused because linking not done
Edit: my boss made several mistakes in the code, the makefile, and the documentation. Sorry to have wasted your time, at least it was less than the 5 hours I spend on it =/
Are you passing the flag to enable OpenMP (IIRC it's something like -fopenmp? If you don't chances are the compiler will ignore the OpenMP-related primitives and just produce serial code.
I don't think that -c (ie, compile only, don't like) has anything to do with your problem.
Perhaps the documentation helps...

optimization and debugging options in Makefile

I wonder where to put the optimization and debugging options in Makefile: linking stage or compiling stage? I am reading a Makefile:
ifeq ($(STATIC),yes)
LDFLAGS=-static -lm -ljpeg -lpng -lz
else
LDFLAGS=-lm -ljpeg -lpng
endif
ifeq ($(DEBUG),yes)
OPTIMIZE_FLAG = -ggdb3 -DDEBUG
else
OPTIMIZE_FLAG = -ggdb3 -O3
endif
ifeq ($(PROFILE),yes)
PROFILE_FLAG = -pg
endif
CXXFLAGS = -Wall $(OPTIMIZE_FLAG) $(PROFILE_FLAG) $(CXXGLPK)
test: test.o rgb_image.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
Makefile.depend: *.h *.cc Makefile
$(CC) -M *.cc > Makefile.depend
clean:
\rm -f absurdity *.o Makefile.depend TAGS
-include Makefile.depend
What surprises me is CXXFLAGS is used in linking. I know it is also used in the implicit rule for compiling to generate .o files but is it necessary to use it again for linking? Specifically, where should I put optimization and debugging: linking stage or compiling stage?
Short answer:
optimization: needed at compiler time
debug flag: needed at compile time
debugging symbols: need at both compile and linking time
Take note that the linker decides what bits of each object file and library need to be included in the final executable. It could throw out the debugging symbols (I don't know what the default behavior is), so you need to tell it not to.
Further, the linker will silently ignore options which do not apply to it.
To the comments:
The above are very general claims based on knowing what happens at each stage of compilation, so no reference.
A few more details:
optimization: takes two major forms: peephole optimization can occur very late, because it works on a few assembly instructions at a time (I presume that in the GNU tool chain the assembler is responsible for this step), but the big gains are in structural optimizations that are generally accomplished by re-writing the Abstract Syntax Tree (AST) which is only possible during compilation.
debug flag: In your example this is a preprocessor directive, and only affects the first part of the compilation process.
debugging symbols: Look up the ELF file format (for instance), you'll see that various bits of code and data are organized into different blocks. Debugging symbols are stored in the same file along as the code they relate to, but are necessarily kept separate from the actual code. As such, any program that manipulates these files could just dump it. Therefore both the compiler and the linker need to know if you want them or not.

Resources