by MaskRay on 7/1/24, 2:57 AM with 27 comments
by aengelke on 7/1/24, 7:11 AM
- 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)
by Keyframe on 7/1/24, 4:41 PM
by mncharity on 7/1/24, 5:07 PM
[1] https://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html
by matrix_overload on 7/1/24, 6:04 AM