LLVM provides alternatives for the majority of GNU tools, most of which we package but we don't actually use when we specify clang : yes in a package. Additionally, we build clang using GNU tooling when it could be built with clang's own tools. Let's list them to see what we could potentially implement.
- AR, NM and RANLIB
LLVM provides llvm-ar, llvm-nm and llvm-ranlib as alternatives to GNU's ar,nm and ranlib. They reportably perform better but with some limitations, e.g. llvm-nm does not accept the same full set of arguments as nm. They can be set at build time by exporting the AR NM and RANLIB global variables.
Even though this is implemented LLVM itself is still building with GCC tools here, could be a cmake thing, can set CMAKE_RANLIB and so on to circumvent.
We already package clang's linker lld, it can be used by specifying -fuse-ld=lld in LDFLAGS. Clang can be built with it's own linker with LLVM_ENABLE_LLD or LLVM_USE_LINKER=lld at build time. Importantly it doesn't understand our default LDFLAG --copy-dt-needed-entries, removing this as default will likely bloat builddeps for rebuilds.
- C library
Whilst it is possible to use musl instead of glibc with clang we want to take advantage of the AVX2 architecture we already have in place. No point in changing this.
LLVM provides libc++ which we already have packaged as a drop-in replacement to GNU's libstdc++. It can be used at build time by specifying -stdlib=libc++. It can be made clang's default C++ library by setting CLANG_DEFAULT_CXX_STDLIB=libc++ when building Clang.
You can build llvm with libcxx by passing LLVM_ENABLE_LIBCXX
LLVM's build system looks for an installed libcxx installation rather than using the in-tree compiled source, it's possible to overcome this with some trickery but it may be worth moving libcxx outside of the monolithic llvm build. This also applies to libcxxabi and libunwind.
Compiler Runtime (and atomics)
LLVM provides compiler-rt as a drop in replacement to libgcc_s. It can be used by specifying -rtlib=compiler-rt at build time, alternatively you can set clang's default compiler runtime by setting CLANG_DEFAULT_RTLIB=compiler-rt when building LLVM.
LLVM provides libc++abi as a drop-in replacement to GNU's libsupc++ which is contained within libstdc++.
You can bootstrap libc++ with libc++abi by setting LIBCXX_CXX_ABI=libcxxabi.
You can build llvm with libcxxabi by passing LLVM_ENABLE_LIBCXXABI.
There exists three unwind libraries. The one included within libgcc_s, libunwind from non-gnu and LLVM's own libunwind which we currently do not have packaged, meant for use with libcxxabi. LLVM's libunwind will conflict with non-gnu's libunwind library.
Building Clang with PGO
We want clang to compile faster, especially as we already have GCC PGO. Their provided pgo solution requires some serious cmake gymnastics to build a monolithic LLVM stack but it's fairly simple to build LLVM by: building a stage1 compiler as normal, building a stage2 instrumented compiler with LLVM_BUILD_INSTRUMENTED, build the profile, build the stage2 profiled compiler with the stage1 compiler and point it to the profile with LLVM_PROFDATA_FILE. This allows us to keep a clean environment and choose what we want to run to build a profile. Either running check-clang or compiling clang
Whilst early technology it may be worth looking at BOLT which provides an additional 12% compile time improvement over a PGO'd and LTO'd build.
To get the most performance out of clang and make it a _real_ replacement to gcc.