aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ELF.cpp
diff options
context:
space:
mode:
authorRahman Lavaee <rahmanl@google.com>2025-06-23 09:25:14 -0700
committerGitHub <noreply@github.com>2025-06-23 09:25:14 -0700
commit8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f (patch)
tree78d5208432daee8bb294f6714203fa5e7dda1927 /llvm/lib/Object/ELF.cpp
parent698e9f56558e20ceb80c08c4a880bed15970b777 (diff)
downloadllvm-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.cpp31
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();
}