Integrated assembler improvements in LLVM 19
maskray.me
maskray.me
- Removing per-instruction timers, which add a measurable overhead even when disabled (https://github.com/llvm/llvm-project/pull/97046)
- Splitting AsmPrinterHandler (used for unwind info) and DebugHandler (used also for per-instruction location information) to avoid two virtual function calls per instruction (https://github.com/llvm/llvm-project/pull/96785)
- Remove several maps from ELFObjectWriter, including some std::map (changed locally, need to make PR)
- Faster section allocation, remove ELF "mergeable section info" hash maps (although this is called just ~40 times per object file, it is very measurable in JIT use cases when compiling many small objects) (planned)
- X86 encoding in general; this consumes quite some time and looks very inefficient -- having written my own x86 encoder, I'm confident that there's a lot of improvement potential. (not started)
Some takeaways on a higher level -- most of these aren't really surprising, but nonetheless are very frequent problems(/patterns) in the LLVM code base:
- Maps/hash maps/sets are quite expensive when used frequently, and sometimes can be easily avoided, e.g., with a vector or, for pointer keys, a pointer dereference
- Virtual functions(/abstraction) calls comes at a cost, especially when done frequently
- raw_svector_ostream is slow, because writes are virtual function calls and don't get inlined (I previously replaced raw_svector_ostream with a SmallVector&: https://reviews.llvm.org/D145792)
- Frequent heap allocations are costly, especially with glibc's malloc
- Many small inefficiencies add up (=> many small improvements do, too)
(I aim to write blog posts every 2-3 weeks, but this latest one was postponed... I wrote this in relatively short time so that the gap would not be too long, and I really should take time to refine the post.)
Yeah, sorry, mostly my fault. I'd been producing these regularly and haven't done as well lately. I'll get one uploaded for 18 soon. :(
[1] https://github.com/llvm/llvm-project/releases/tag/llvmorg-18...
[2] https://discourse.llvm.org/t/18-1-8-has-been-tagged/79726/10...
Very nearly all of the work is done by the test-release.sh script.
You might also want to replace the malloc with mimalloc/snmalloc, which might yield ~10% performance boost.
[1] https://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html