Apologies for the cross-post, this effects both clang and llvm.
I was looking into the startup time of clang on small files
and discovered that a significant amount of our startup time was being
spent in the linker resolving weak symbols. At least on Darwin, this was
actually the dominant factor in our startup time. Our use of C++ means
that by default we tend to have quite a few weak symbols in our binaries.
There are two ways to reduce this startup cost, one start is to use
-fvisibility-inlines-hidden for compilers which support it (GCC). This marks
inline member functions as hidden which means they do not appear as
weak external symbols in the final linked image.
The second is to use an explicit list of exports which is provided to the
linker. For applications like llvm-as which do no loading of plugins the
export list is simply “_main” which is easy to specify.
Here are some timing results on Darwin of versions of clang, llc, and llvm-as
for each option. The -cur command is the way the current executable is build, -vih
is the executable compiled with -visibility-inlines-hidden, and -export is the
executable built with an export list of “_main” only (this subsumes
These are all Release builds. empty.ll is in fact empty, empty.bc is the resultant
.bc, and empty.c has one int variable. runN is a program which simply fork-execs
the given program N times (1000 in this case).