[clang-tools-extra] Bfi precision (PR #66285)
Matthias Braun via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 27 14:54:27 PDT 2023
MatzeB wrote:
And digging even deeper:
- FWIW I noticed that I only used `clang -c` as benchmark previously, should have used `clang -c -O3` resulting in this:
```
Old-BFI: insn: 37,821,687,947 (baseline)
New-BFI: insn: 38,133,312,923 +0.82%
Old-BFI, no-cold: insn: 37,423,365,184 -1.05%
New-BFI, no-cold: insn: 37,438,736,713 -1.01%
```
- The problematic part of the code that is inlined/not-inlined is actually marked as `LLVM_UNLIKELY` here: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/ADT/DenseMap.h#L607 and intuitively one would think that it is probably best to not inline `grow` (as will happen with the new BFI version)
- In practice not-inlining `grow` mostly ends up being worse because of knock-on effects as far as I can tell. These are the inlining decisions I noticed for the most prominent situation:
- `grow` inlined (Old-BFI):
- Instruction::getMetadataImpl
-> Value::getMetadata not inlined
-> DenseMap::operator[] inlined
-> DenseMap::FindAndConstruct inlined
-> DenseMap::InsertIntoBucket not inlined, size
likely too big with `grow` inlined here
-> DenseMap::grow inlined
- `grow` inlined (New-BFI):
- Instruction::getMadataImpl
-> Value::getMetadata inlined
-> DenseMap::operator[] inlined
-> DenseMap::FindAndConstruct not inlined, size
-> DenseMap::InsertIntoBucket inlined
-> DenseMap::grow not inlined
Though if you look into this then I would state that the code got better for the wrong reasons! Not inlining `grow` is a sensible decision in this context and the `LLVM_UNLIKELY` annotation makes sense (I actually added some counters and see the unlikely branch taken somewhere between 1% and 10% of the cases depending on inputs, so seems sensible).
Unfortunately the particular code here `getMetadataImpl` never inserts new things into the map, but unfortunately `operator[]` gives you that behavior by default so nobody noticed. So not inlining `InsertIntoBucket` happened to be a great decision previously that the compiler did by accident without having good data to support this. Now with better but still insufficient data (as this is PGO) we happen to make the decisions that ends up being worse.
Long story short: This ended up another of the many stories where the compiler cannot make the right inlining decisions without having actual runtime data. It tends to make a better decision based on the data that ends up being wrong anyway here. I'm gonna leave things as is and rather put up some improvements to LLVM code instead!
https://github.com/llvm/llvm-project/pull/66285
More information about the cfe-commits
mailing list