diff options
author | Rahman Lavaee <rahmanl@google.com> | 2025-06-23 09:25:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-23 09:25:14 -0700 |
commit | 8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f (patch) | |
tree | 78d5208432daee8bb294f6714203fa5e7dda1927 /llvm/lib/Object/ELF.cpp | |
parent | 698e9f56558e20ceb80c08c4a880bed15970b777 (diff) | |
download | llvm-8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f.zip llvm-8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f.tar.gz llvm-8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f.tar.bz2 |
[SHT_LLVM_BB_ADDR_MAP] Encode and decode callsite offsets in a newly-introduced SHT_LLVM_BB_ADDR_MAP version. (#144426)
Recently, we have been looking at some optimizations targeting
individual calls. In particular, we plan to extend the address mapping
technique to map to individual callsites. For example, in this piece of
code for a basic blocks:
```
<BB>:
1200: lea 0x1(%rcx), %rdx
1204: callq foo
1209: cmpq 0x10, %rdx
120d: ja L1
```
We want to emit 0x9 as the call site offset for `callq foo` (the offset
from the block entry to right after the call), so that we know if a
sampled address is before the call or after.
This PR implements the decode/encode/emit capability. The Codegen change
will be implemented in a later PR.
Diffstat (limited to 'llvm/lib/Object/ELF.cpp')
-rw-r--r-- | llvm/lib/Object/ELF.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index e6864ca..6ee33d9 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -837,7 +837,7 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF, Version = Data.getU8(Cur); if (!Cur) break; - if (Version > 2) + if (Version > 3) return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " + Twine(static_cast<int>(Version))); Feature = Data.getU8(Cur); // Feature byte @@ -847,12 +847,18 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF, if (!FeatEnableOrErr) return FeatEnableOrErr.takeError(); FeatEnable = *FeatEnableOrErr; - if (Feature != 0 && Version < 2 && Cur) + if (FeatEnable.hasPGOAnalysis() && Version < 2) return createError( "version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when " "PGO features are enabled: version = " + Twine(static_cast<int>(Version)) + " feature = " + Twine(static_cast<int>(Feature))); + if (FeatEnable.CallsiteOffsets && Version < 3) + return createError( + "version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when " + "callsite offsets feature is enabled: version = " + + Twine(static_cast<int>(Version)) + + " feature = " + Twine(static_cast<int>(Feature))); } uint32_t NumBlocksInBBRange = 0; uint32_t NumBBRanges = 1; @@ -893,7 +899,23 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF, ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) : BlockIndex; uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); - uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); + // Read the callsite offsets. + uint32_t LastCallsiteOffset = 0; + SmallVector<uint32_t, 1> CallsiteOffsets; + if (FeatEnable.CallsiteOffsets) { + uint32_t NumCallsites = + readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); + CallsiteOffsets.reserve(NumCallsites); + for (uint32_t CallsiteIndex = 0; + !ULEBSizeErr && Cur && (CallsiteIndex < NumCallsites); + ++CallsiteIndex) { + LastCallsiteOffset += + readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); + CallsiteOffsets.push_back(LastCallsiteOffset); + } + } + uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) + + LastCallsiteOffset; uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr); if (Version >= 1) { // Offset is calculated relative to the end of the previous BB. @@ -906,7 +928,8 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF, MetadataDecodeErr = MetadataOrErr.takeError(); break; } - BBEntries.push_back({ID, Offset, Size, *MetadataOrErr}); + BBEntries.push_back( + {ID, Offset, Size, *MetadataOrErr, CallsiteOffsets}); } TotalNumBlocks += BBEntries.size(); } |