Since this work has landed and is now on LLVM 14, I would like to give a quick followup describing how to use Lightweight Instrumentation and it’s results.
I added the llvm flag -debug-info-correlate
with -fprofile-generate
to create an instrumenting build that uses external debug info instead of metadata that remains in the binary. This is implemented in ⚙ D115693 [Try2][InstrProf] Attach debug info to counters and ⚙ D115915 [Try2][InstrProf] Add Correlator class to read debug info. Note that this is not yet compatible with value profiling so you’ll need to use -disable-vp=true
.
clang -fprofile-generate -mllvm -debug-info-correlate -mllvm --disable-vp=true main.cpp
./a.out
llvm-profdata merge -o default.profile --debug-info=a.out default.proflite
Then I added the llvm flag -pgo-function-entry-coverage
in ⚙ D116180 [InstrProf] Add single byte coverage mode to instrument function coverage by using a single coverage byte for each function rather than using 64 bit counters for block counts. In practice, this is useful to detect dead code.
With these two additions, I was able to create a clang binary with function coverage instrumentation that only 7M (4.9%) larger than the non-instrumented binary. In contrast, the default instrumentation without value profiling has an overhead of 31M (21.7%).
Let me know if you have any questions!