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
.