Reputation: 685
Consider something like the following scenario:
main.c contains something like this:
#include "sub.h"
main(){
int i = 0;
while(i < 1000000000){
f();
i++;
}
}
while sub.h contains:
void f();
and sub.c contains something like this:
void f(){
int a = 1;
}
Now, if this were all in one source file, the compiler (gcc in my case) would notice that f() doesn't actually do anything and optimize the loop away. But since compiling happens before linking, that optimization can't happen in this case.
This can be avoided for local include files by including the raw .c files rather tan the headers, but when including headers from other libraries this becomes impossible. Is there any way around this?
Upvotes: 0
Views: 220
Reputation:
If I'm understanding correctly, you would like to only link library functions that are being used by your program. Using the GCC tool chain this is possible with the optimization flags:
-O2 -fdata-sections -ffunction-sections
The first flag should optimize away loops that do nothing. The other two flags place each function or data item into its own section in the compiled output file. This allows the linker to perform optimizations. Note: it will take longer to compile and you won't be able to use gprof.
You will also need to then pass the linker the -gc-sections
flag so that it won't include unused function and data sections.
All in all, you would execute:
gcc -O2 -fdata-sections -ffunction-sections main.c sub.c -Wl,-gc-sections
If you were to instead call GCC to produce assembly files you could inspect them to find that _main does not execute a loop or call the function f():
$ gcc -O2 -S -fdata-sections -ffunction-sections main.c sub.c -Wl,-gc-sections
$ cat main.s
Sources:
Upvotes: 3
Reputation: 13085
In windows, the vs system has whole program optimization
Sqlite uses a script to build a single C file to compile
Upvotes: 0
Reputation: 17658
The compiler cannot guess and cannot make assumptions on what's outside the individual translation unit that it compiles. Some toolchains (end-to-end compiler+linker+supporting-utilities) may detect some such cases within a project being built from sources, depending on their sophistication of optimizations. It would not be common, and not guaranteed. It would most certainly not, and could not, apply to opaque 3rd party libraries being linked in.
In practice however, would you really use a 3rd party library that exported some no-op function, in hope that someone (your toolchain) would notice and safely optimize it away?
Upvotes: 2