[llvm] 8d7a8fc - [SHT_LLVM_BB_ADDR_MAP] Encode and decode callsite offsets in a newly-introduced SHT_LLVM_BB_ADDR_MAP version. (#144426)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 23 09:25:17 PDT 2025
Author: Rahman Lavaee
Date: 2025-06-23T09:25:14-07:00
New Revision: 8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f
URL: https://github.com/llvm/llvm-project/commit/8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f
DIFF: https://github.com/llvm/llvm-project/commit/8d7a8fcc3ab9f6d4c4a7e4312876fe94ed3d6c4f.diff
LOG: [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.
Added:
Modified:
llvm/include/llvm/Object/ELFTypes.h
llvm/include/llvm/ObjectYAML/ELFYAML.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/Object/ELF.cpp
llvm/lib/ObjectYAML/ELFEmitter.cpp
llvm/lib/ObjectYAML/ELFYAML.cpp
llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
llvm/tools/llvm-readobj/ELFDumper.cpp
llvm/tools/obj2yaml/elf2yaml.cpp
llvm/unittests/Object/ELFObjectFileTest.cpp
llvm/unittests/Object/ELFTypesTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h
index 87e4dbe448091..d7a468f1116d7 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -831,6 +831,7 @@ struct BBAddrMap {
bool BrProb : 1;
bool MultiBBRange : 1;
bool OmitBBEntries : 1;
+ bool CallsiteOffsets : 1;
bool hasPGOAnalysis() const { return FuncEntryCount || BBFreq || BrProb; }
@@ -842,7 +843,8 @@ struct BBAddrMap {
(static_cast<uint8_t>(BBFreq) << 1) |
(static_cast<uint8_t>(BrProb) << 2) |
(static_cast<uint8_t>(MultiBBRange) << 3) |
- (static_cast<uint8_t>(OmitBBEntries) << 4);
+ (static_cast<uint8_t>(OmitBBEntries) << 4) |
+ (static_cast<uint8_t>(CallsiteOffsets) << 5);
}
// Decodes from minimum bit width representation and validates no
@@ -851,7 +853,7 @@ struct BBAddrMap {
Features Feat{
static_cast<bool>(Val & (1 << 0)), static_cast<bool>(Val & (1 << 1)),
static_cast<bool>(Val & (1 << 2)), static_cast<bool>(Val & (1 << 3)),
- static_cast<bool>(Val & (1 << 4))};
+ static_cast<bool>(Val & (1 << 4)), static_cast<bool>(Val & (1 << 5))};
if (Feat.encode() != Val)
return createStringError(
std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
@@ -861,9 +863,10 @@ struct BBAddrMap {
bool operator==(const Features &Other) const {
return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange,
- OmitBBEntries) ==
+ OmitBBEntries, CallsiteOffsets) ==
std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
- Other.MultiBBRange, Other.OmitBBEntries);
+ Other.MultiBBRange, Other.OmitBBEntries,
+ Other.CallsiteOffsets);
}
};
@@ -914,13 +917,18 @@ struct BBAddrMap {
uint32_t Size = 0; // Size of the basic block.
Metadata MD = {false, false, false, false,
false}; // Metdata for this basic block.
+ // Offsets of callsites (end of call instructions), relative to the basic
+ // block start.
+ SmallVector<uint32_t, 1> CallsiteOffsets;
- BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD)
- : ID(ID), Offset(Offset), Size(Size), MD(MD){};
+ BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD,
+ SmallVector<uint32_t, 1> CallsiteOffsets)
+ : ID(ID), Offset(Offset), Size(Size), MD(MD),
+ CallsiteOffsets(std::move(CallsiteOffsets)) {}
bool operator==(const BBEntry &Other) const {
return ID == Other.ID && Offset == Other.Offset && Size == Other.Size &&
- MD == Other.MD;
+ MD == Other.MD && CallsiteOffsets == Other.CallsiteOffsets;
}
bool hasReturn() const { return MD.HasReturn; }
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index dfdfa055d65fa..e883f2f3e1447 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -162,6 +162,7 @@ struct BBAddrMapEntry {
llvm::yaml::Hex64 AddressOffset;
llvm::yaml::Hex64 Size;
llvm::yaml::Hex64 Metadata;
+ std::optional<std::vector<llvm::yaml::Hex64>> CallsiteOffsets;
};
uint8_t Version;
llvm::yaml::Hex8 Feature;
@@ -180,6 +181,20 @@ struct BBAddrMapEntry {
return 0;
return BBRanges->front().BaseAddress;
}
+
+ // Returns if any BB entries have non-empty callsite offsets.
+ bool hasAnyCallsiteOffsets() const {
+ if (!BBRanges)
+ return false;
+ for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *BBRanges) {
+ if (!BBR.BBEntries)
+ continue;
+ for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries)
+ if (BBE.CallsiteOffsets && !BBE.CallsiteOffsets->empty())
+ return true;
+ }
+ return false;
+ }
};
struct PGOAnalysisMapEntry {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 3fc550c6dd1a5..83673f4606982 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1426,9 +1426,12 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) {
"BB entries info is required for BBFreq and BrProb "
"features");
}
- return {FuncEntryCountEnabled, BBFreqEnabled, BrProbEnabled,
+ return {FuncEntryCountEnabled,
+ BBFreqEnabled,
+ BrProbEnabled,
MF.hasBBSections() && NumMBBSectionRanges > 1,
- static_cast<bool>(BBAddrMapSkipEmitBBEntries)};
+ static_cast<bool>(BBAddrMapSkipEmitBBEntries),
+ false};
}
void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index e6864ca508a54..6ee33d94ee861 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();
}
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 9ae76a71ede5e..6de87a88d0060 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1452,7 +1452,7 @@ void ELFState<ELFT>::writeSectionContent(
for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) {
// Write version and feature values.
if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) {
- if (E.Version > 2)
+ if (E.Version > 3)
WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
<< static_cast<int>(E.Version)
<< "; encoding using the most recent version";
@@ -1483,6 +1483,8 @@ void ELFState<ELFT>::writeSectionContent(
if (!E.BBRanges)
continue;
uint64_t TotalNumBlocks = 0;
+ bool EmitCallsiteOffsets =
+ FeatureOrErr->CallsiteOffsets || E.hasAnyCallsiteOffsets();
for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
// Write the base address of the range.
CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);
@@ -1500,6 +1502,15 @@ void ELFState<ELFT>::writeSectionContent(
if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1)
SHeader.sh_size += CBA.writeULEB128(BBE.ID);
SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);
+ if (EmitCallsiteOffsets) {
+ size_t NumCallsiteOffsets =
+ BBE.CallsiteOffsets ? BBE.CallsiteOffsets->size() : 0;
+ SHeader.sh_size += CBA.writeULEB128(NumCallsiteOffsets);
+ if (BBE.CallsiteOffsets) {
+ for (uint32_t Offset : *BBE.CallsiteOffsets)
+ SHeader.sh_size += CBA.writeULEB128(Offset);
+ }
+ }
SHeader.sh_size += CBA.writeULEB128(BBE.Size);
SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);
}
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index fc485b6656e0d..b28191730f018 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1883,6 +1883,7 @@ void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping(
IO.mapRequired("AddressOffset", E.AddressOffset);
IO.mapRequired("Size", E.Size);
IO.mapRequired("Metadata", E.Metadata);
+ IO.mapOptional("CallsiteOffsets", E.CallsiteOffsets);
}
void MappingTraits<ELFYAML::PGOAnalysisMapEntry>::mapping(
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
index c5d071c11d1de..5d7bc8baa9b25 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
@@ -49,7 +49,8 @@
# CHECK-NEXT: {
# CHECK-NEXT: ID: 2
# CHECK-NEXT: Offset: 0x3
-# CHECK-NEXT: Size: 0x4
+# CHECK-NEXT: Callsite Offsets: [1, 3]
+# CHECK-NEXT: Size: 0x7
# CHECK-NEXT: HasReturn: Yes
# CHECK-NEXT: HasTailCall: No
# CHECK-NEXT: IsEHPad: Yes
@@ -75,7 +76,7 @@
# CHECK-NEXT: HasTailCall: No
# CHECK-NEXT: IsEHPad: No
# CHECK-NEXT: CanFallThrough: Yes
-# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: HasIndirectBranch: No
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
@@ -143,8 +144,8 @@ Sections:
ShSize: [[SIZE=<none>]]
Link: .text
Entries:
- - Version: 2
- Feature: 0x8
+ - Version: 3
+ Feature: 0x28
BBRanges:
- BaseAddress: [[ADDR=0x11111]]
BBEntries:
@@ -158,6 +159,7 @@ Sections:
AddressOffset: 0x3
Size: 0x4
Metadata: 0x15
+ CallsiteOffsets: [ 0x1 , 0x2 ]
- Version: 2
BBRanges:
- BaseAddress: 0x22222
diff --git a/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml b/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
index 8dbf97ef2bc12..861cb94692947 100644
--- a/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
@@ -14,7 +14,7 @@
# VALID-NEXT: - Name: .llvm_bb_addr_map
# VALID-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# VALID-NEXT: Entries:
-# VALID-NEXT: - Version: 2
+# VALID-NEXT: - Version: 3
# VALID-NEXT: BBRanges:
## The 'BaseAddress' field is omitted when it's zero.
# VALID-NEXT: - BBEntries:
@@ -30,15 +30,16 @@
# VALID-NEXT: AddressOffset: 0xFFFFFFFFFFFFFFF7
# VALID-NEXT: Size: 0xFFFFFFFFFFFFFFF8
# VALID-NEXT: Metadata: 0xFFFFFFFFFFFFFFF9
-# VALID-NEXT: - Version: 2
-# VALID-NEXT: Feature: 0x8
+# VALID-NEXT: - Version: 3
+# VALID-NEXT: Feature: 0x28
# VALID-NEXT: BBRanges:
# VALID-NEXT: - BaseAddress: 0xFFFFFFFFFFFFFF20
# VALID-NEXT: BBEntries:
-# VALID-NEXT: - ID: 6
-# VALID-NEXT: AddressOffset: 0xA
-# VALID-NEXT: Size: 0xB
-# VALID-NEXT: Metadata: 0xC
+# VALID-NEXT: - ID: 6
+# VALID-NEXT: AddressOffset: 0xA
+# VALID-NEXT: Size: 0xB
+# VALID-NEXT: Metadata: 0xC
+# VALID-NEXT: CallsiteOffsets: [ 0x1, 0x2 ]
--- !ELF
FileHeader:
@@ -50,7 +51,7 @@ Sections:
Type: SHT_LLVM_BB_ADDR_MAP
ShSize: [[SIZE=<none>]]
Entries:
- - Version: 2
+ - Version: 3
Feature: 0x0
BBRanges:
- BaseAddress: 0x0
@@ -67,17 +68,18 @@ Sections:
AddressOffset: 0xFFFFFFFFFFFFFFF7
Size: 0xFFFFFFFFFFFFFFF8
Metadata: 0xFFFFFFFFFFFFFFF9
- - Version: 2
- Feature: 0x8
+ - Version: 3
+ Feature: 0x28
NumBBRanges: [[NUMBBRANGES=<none>]]
BBRanges:
- BaseAddress: 0xFFFFFFFFFFFFFF20
NumBlocks: [[NUMBLOCKS=<none>]]
BBEntries:
- - ID: 6
- AddressOffset: 0xA
- Size: 0xB
- Metadata: 0xC
+ - ID: 6
+ AddressOffset: 0xA
+ Size: 0xB
+ Metadata: 0xC
+ CallsiteOffsets: [ 0x1, 0x2 ]
## Check obj2yaml can dump empty .llvm_bb_addr_map sections.
diff --git a/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml b/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
index 709938babffbf..9fd0577b1e0fd 100644
--- a/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
@@ -36,7 +36,8 @@
# Case 4: Specify Entries.
# CHECK: Name: .llvm_bb_addr_map (1)
# CHECK: SectionData (
-# CHECK-NEXT: 0000: 02002000 00000000 0000010B 010203
+# CHECK-NEXT: 0000: 03002000 00000000 0000010B 01020102
+# CHECK-NEXT: 0010: 0203
# CHECK-NEXT: )
# Case 5: Specify Entries and omit the Address field.
@@ -44,28 +45,32 @@
# CHECK: Address:
# CHECK-SAME: {{^ 0x0$}}
# CHECK: SectionData (
-# CHECK-NEXT: 0000: 02000000 00000000 0000010C 010203
+# CHECK-NEXT: 0000: 03000000 00000000 0000010C 010203
# CHECK-NEXT: )
# Case 6: Override the NumBlocks field.
# CHECK: Name: .llvm_bb_addr_map (1)
# CHECK: SectionData (
-# CHECK-NEXT: 0000: 02002000 00000000 0000020D 010203
+# CHECK-NEXT: 0000: 03002000 00000000 0000020D 010203
# CHECK-NEXT: )
# Case 7: Specify empty BBRanges.
# CHECK: Name: .llvm_bb_addr_map (1)
# CHECK: SectionData (
-# CHECK-NEXT: 0000: 020000
+# CHECK-NEXT: 0000: 030000
# CHECK-NEXT: )
# Case 8: Specify empty BBRanges with multi-bb-range.
# CHECK: Name: .llvm_bb_addr_map (1)
# CHECK: SectionData (
-# CHECK-NEXT: 0000: 020800
+# CHECK-NEXT: 0000: 030800
# CHECK-NEXT: )
-
+# Case 9: Specify empty CallsiteOffsets.
+# CHECK: Name: .llvm_bb_addr_map (1)
+# CHECK: SectionData (
+# CHECK-NEXT: 0000: 03202000 00000000 0000010E 01000203
+# CHECK-NEXT: )
--- !ELF
@@ -100,7 +105,7 @@ Sections:
- Name: '.llvm_bb_addr_map (4)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- - Version: 2
+ - Version: 3
BBRanges:
- BaseAddress: 0x0000000000000020
BBEntries:
@@ -108,13 +113,14 @@ Sections:
AddressOffset: 0x00000001
Size: 0x00000002
Metadata: 0x00000003
+ CallsiteOffsets: [0x1, 0x2]
## 5) When specifying the description with Entries, the 'Address' field will be
## zero when omitted.
- Name: '.llvm_bb_addr_map (5)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- - Version: 2
+ - Version: 3
BBRanges:
- BBEntries:
- ID: 12
@@ -127,7 +133,7 @@ Sections:
- Name: '.llvm_bb_addr_map (6)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- - Version: 2
+ - Version: 3
BBRanges:
- BaseAddress: 0x0000000000000020
NumBlocks: 2
@@ -142,7 +148,7 @@ Sections:
- Name: '.llvm_bb_addr_map (7)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- - Version: 2
+ - Version: 3
BBRanges: []
## 8) We can produce a SHT_LLVM_BB_ADDR_MAP section from a multi-bb-range
@@ -150,10 +156,26 @@ Sections:
- Name: '.llvm_bb_addr_map (8)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- - Version: 2
+ - Version: 3
Feature: 0x8
BBRanges: []
+## 9) We can produce a SHT_LLVM_BB_ADDR_MAP section from a description
+## with empty callsite offsets.
+ - Name: '.llvm_bb_addr_map (9)'
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Entries:
+ - Version: 3
+ Feature: 0x20
+ BBRanges:
+ - BaseAddress: 0x0000000000000020
+ BBEntries:
+ - ID: 14
+ AddressOffset: 0x00000001
+ Size: 0x00000002
+ Metadata: 0x00000003
+ CallsiteOffsets: []
+
## Check we can't use Entries at the same time as either Content or Size.
# RUN: not yaml2obj --docnum=2 -DCONTENT="00" %s 2>&1 | FileCheck %s --check-prefix=INVALID
# RUN: not yaml2obj --docnum=2 -DSIZE="0" %s 2>&1 | FileCheck %s --check-prefix=INVALID
@@ -175,7 +197,7 @@ Sections:
## Check that yaml2obj generates a warning when we use unsupported versions.
# RUN: yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --check-prefix=INVALID-VERSION
-# INVALID-VERSION: warning: unsupported SHT_LLVM_BB_ADDR_MAP version: 3; encoding using the most recent version
+# INVALID-VERSION: warning: unsupported SHT_LLVM_BB_ADDR_MAP version: 4; encoding using the most recent version
--- !ELF
FileHeader:
@@ -187,4 +209,4 @@ Sections:
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
## Specify unsupported version
- - Version: 3
+ - Version: 4
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 7be61dcce841a..101079f09e1d2 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -7879,6 +7879,8 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {
DictScope BBED(W);
W.printNumber("ID", BBE.ID);
W.printHex("Offset", BBE.Offset);
+ if (!BBE.CallsiteOffsets.empty())
+ W.printList("Callsite Offsets", BBE.CallsiteOffsets);
W.printHex("Size", BBE.Size);
W.printBoolean("HasReturn", BBE.hasReturn());
W.printBoolean("HasTailCall", BBE.hasTailCall());
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index c56ed15501b40..53455b8c7580a 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -899,7 +899,7 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
while (Cur && Cur.tell() < Content.size()) {
if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
Version = Data.getU8(Cur);
- if (Cur && Version > 2)
+ if (Cur && Version > 3)
return createStringError(
errc::invalid_argument,
"invalid SHT_LLVM_BB_ADDR_MAP section version: " +
@@ -934,9 +934,19 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
++BlockIndex) {
uint32_t ID = Version >= 2 ? Data.getULEB128(Cur) : BlockIndex;
uint64_t Offset = Data.getULEB128(Cur);
+ std::optional<std::vector<llvm::yaml::Hex64>> CallsiteOffsets;
+ if (FeatureOrErr->CallsiteOffsets) {
+ uint32_t NumCallsites = Data.getULEB128(Cur);
+ CallsiteOffsets = std::vector<llvm::yaml::Hex64>(NumCallsites, 0);
+ for (uint32_t CallsiteIndex = 0; Cur && CallsiteIndex < NumCallsites;
+ ++CallsiteIndex) {
+ (*CallsiteOffsets)[CallsiteIndex] = Data.getULEB128(Cur);
+ }
+ }
uint64_t Size = Data.getULEB128(Cur);
uint64_t Metadata = Data.getULEB128(Cur);
- BBEntries.push_back({ID, Offset, Size, Metadata});
+ BBEntries.push_back(
+ {ID, Offset, Size, Metadata, std::move(CallsiteOffsets)});
}
TotalNumBlocks += BBEntries.size();
BBRanges.push_back({BaseAddress, /*NumBlocks=*/{}, BBEntries});
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index 1073df95c379a..423f92ea07b39 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -531,7 +531,7 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
// Check that we can detect unsupported versions.
SmallString<128> UnsupportedVersionYamlString(CommonYamlString);
UnsupportedVersionYamlString += R"(
- - Version: 3
+ - Version: 4
BBRanges:
- BaseAddress: 0x11111
BBEntries:
@@ -543,12 +543,12 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
{
SCOPED_TRACE("unsupported version");
DoCheck(UnsupportedVersionYamlString,
- "unsupported SHT_LLVM_BB_ADDR_MAP version: 3");
+ "unsupported SHT_LLVM_BB_ADDR_MAP version: 4");
}
SmallString<128> ZeroBBRangesYamlString(CommonYamlString);
ZeroBBRangesYamlString += R"(
- - Version: 2
+ - Version: 3
Feature: 0x8
BBRanges: []
)";
@@ -561,7 +561,7 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
SmallString<128> CommonVersionedYamlString(CommonYamlString);
CommonVersionedYamlString += R"(
- - Version: 2
+ - Version: 3
BBRanges:
- BaseAddress: 0x11111
BBEntries:
@@ -669,6 +669,26 @@ TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
)";
DoCheck(OverLimitNumBBRanges,
"ULEB128 value at offset 0x2 exceeds UINT32_MAX (0x100000000)");
+
+ // Check that we can detect unsupported version for callsite offsets.
+ SmallString<128> UnsupportedLowVersionYamlString(CommonYamlString);
+ UnsupportedLowVersionYamlString += R"(
+ - Version: 2
+ Feature: 0x20
+ BBRanges:
+ - BBEntries:
+ - AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
+ CallsiteOffsets: [ 0x1 ]
+)";
+
+ {
+ SCOPED_TRACE("unsupported version");
+ DoCheck(UnsupportedLowVersionYamlString,
+ "version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when callsite"
+ " offsets feature is enabled: version = 2 feature = 32");
+ }
}
// Test for the ELFObjectFile::readBBAddrMap API.
@@ -684,19 +704,21 @@ TEST(ELFObjectFileTest, ReadBBAddrMap) {
Type: SHT_LLVM_BB_ADDR_MAP
Link: 1
Entries:
- - Version: 2
+ - Version: 3
+ Feature: 0x20
BBRanges:
- BaseAddress: 0x11111
BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
+ CallsiteOffsets: [ 0x1 , 0x1 ]
- Name: .llvm_bb_addr_map_2
Type: SHT_LLVM_BB_ADDR_MAP
Link: 1
Entries:
- - Version: 2
+ - Version: 3
Feature: 0x8
BBRanges:
- BaseAddress: 0x22222
@@ -738,14 +760,15 @@ TEST(ELFObjectFileTest, ReadBBAddrMap) {
)");
BBAddrMap E1 = {
- {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
+ {{0x11111,
+ {{1, 0x0, 0x3, {false, true, false, false, false}, {0x1, 0x2}}}}}};
BBAddrMap E2 = {
- {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}},
- {0xFFFFF, {{15, 0xF0, 0xF1, {true, true, true, true, true}}}}}};
+ {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}, {}}}},
+ {0xFFFFF, {{15, 0xF0, 0xF1, {true, true, true, true, true}, {}}}}}};
BBAddrMap E3 = {
- {{0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}}}}}};
+ {{0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}, {}}}}}};
BBAddrMap E4 = {
- {{0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}}}}}};
+ {{0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}, {}}}}}};
std::vector<BBAddrMap> Section0BBAddrMaps = {E4};
std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
@@ -1137,28 +1160,29 @@ TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
)");
BBAddrMap E1 = {
- {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
- PGOAnalysisMap P1 = {892, {}, {true, false, false, false, false}};
+ {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}, {}}}}}};
+ PGOAnalysisMap P1 = {892, {}, {true, false, false, false, false, false}};
BBAddrMap E2 = {
- {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
- PGOAnalysisMap P2 = {
- {}, {{BlockFrequency(343), {}}}, {false, true, false, false, false}};
+ {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}, {}}}}}};
+ PGOAnalysisMap P2 = {{},
+ {{BlockFrequency(343), {}}},
+ {false, true, false, false, false, false}};
BBAddrMap E3 = {{{0x33333,
- {{0, 0x0, 0x3, {false, true, true, false, false}},
- {1, 0x3, 0x3, {false, false, true, false, false}},
- {2, 0x6, 0x3, {false, false, false, false, false}}}}}};
+ {{0, 0x0, 0x3, {false, true, true, false, false}, {}},
+ {1, 0x3, 0x3, {false, false, true, false, false}, {}},
+ {2, 0x6, 0x3, {false, false, false, false, false}, {}}}}}};
PGOAnalysisMap P3 = {{},
{{{},
{{1, BranchProbability::getRaw(0x1111'1111)},
{2, BranchProbability::getRaw(0xeeee'eeee)}}},
{{}, {{2, BranchProbability::getRaw(0xffff'ffff)}}},
{{}, {}}},
- {false, false, true, false, false}};
+ {false, false, true, false, false, false}};
BBAddrMap E4 = {{{0x44444,
- {{0, 0x0, 0x4, {false, false, false, true, true}},
- {1, 0x4, 0x4, {false, false, false, false, false}},
- {2, 0x8, 0x4, {false, false, false, false, false}},
- {3, 0xc, 0x4, {false, false, false, false, false}}}}}};
+ {{0, 0x0, 0x4, {false, false, false, true, true}, {}},
+ {1, 0x4, 0x4, {false, false, false, false, false}, {}},
+ {2, 0x8, 0x4, {false, false, false, false, false}, {}},
+ {3, 0xc, 0x4, {false, false, false, false, false}, {}}}}}};
PGOAnalysisMap P4 = {
1000,
{{BlockFrequency(1000),
@@ -1170,22 +1194,22 @@ TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
{3, BranchProbability::getRaw(0xeeee'eeee)}}},
{BlockFrequency(18), {{3, BranchProbability::getRaw(0xffff'ffff)}}},
{BlockFrequency(1000), {}}},
- {true, true, true, false, false}};
+ {true, true, true, false, false, false}};
BBAddrMap E5 = {
- {{0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
- PGOAnalysisMap P5 = {{}, {}, {false, false, false, false, false}};
+ {{0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}, {}}}}}};
+ PGOAnalysisMap P5 = {{}, {}, {false, false, false, false, false, false}};
BBAddrMap E6 = {
{{0x66666,
- {{0, 0x0, 0x6, {false, true, true, false, false}},
- {1, 0x6, 0x6, {false, false, true, false, false}}}},
- {0x666661, {{2, 0x0, 0x6, {false, false, false, false, false}}}}}};
+ {{0, 0x0, 0x6, {false, true, true, false, false}, {}},
+ {1, 0x6, 0x6, {false, false, true, false, false}, {}}}},
+ {0x666661, {{2, 0x0, 0x6, {false, false, false, false, false}, {}}}}}};
PGOAnalysisMap P6 = {{},
{{{},
{{1, BranchProbability::getRaw(0x2222'2222)},
{2, BranchProbability::getRaw(0xcccc'cccc)}}},
{{}, {{2, BranchProbability::getRaw(0x8888'8888)}}},
{{}, {}}},
- {false, false, true, true, false}};
+ {false, false, true, true, false, false}};
std::vector<BBAddrMap> Section0BBAddrMaps = {E4, E5, E6};
std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
diff --git a/llvm/unittests/Object/ELFTypesTest.cpp b/llvm/unittests/Object/ELFTypesTest.cpp
index 13130dde80ef1..f88931b5f544c 100644
--- a/llvm/unittests/Object/ELFTypesTest.cpp
+++ b/llvm/unittests/Object/ELFTypesTest.cpp
@@ -101,18 +101,21 @@ static_assert(
"PGOAnalysisMap should use the same type for basic block ID as BBAddrMap");
TEST(ELFTypesTest, BBAddrMapFeaturesEncodingTest) {
- const std::array<BBAddrMap::Features, 9> Decoded = {
- {{false, false, false, false, false},
- {true, false, false, false, false},
- {false, true, false, false, false},
- {false, false, true, false, false},
- {false, false, false, true, false},
- {true, true, false, false, false},
- {false, true, true, false, false},
- {false, true, true, true, false},
- {true, true, true, true, false}}};
- const std::array<uint8_t, 9> Encoded = {
- {0b0000, 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b0110, 0b1110, 0b1111}};
+ const std::array<BBAddrMap::Features, 11> Decoded = {
+ {{false, false, false, false, false, false},
+ {true, false, false, false, false, false},
+ {false, true, false, false, false, false},
+ {false, false, true, false, false, false},
+ {false, false, false, true, false, false},
+ {true, true, false, false, false, false},
+ {false, true, true, false, false, false},
+ {false, true, true, true, false, false},
+ {true, true, true, true, false, false},
+ {false, false, false, false, true, false},
+ {false, false, false, false, false, true}}};
+ const std::array<uint8_t, 11> Encoded = {{0b0000, 0b0001, 0b0010, 0b0100,
+ 0b1000, 0b0011, 0b0110, 0b1110,
+ 0b1111, 0b1'0000, 0b10'0000}};
for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded))
EXPECT_EQ(Feat.encode(), EncodedVal);
for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded)) {
@@ -125,9 +128,9 @@ TEST(ELFTypesTest, BBAddrMapFeaturesEncodingTest) {
TEST(ELFTypesTest, BBAddrMapFeaturesInvalidEncodingTest) {
const std::array<std::string, 2> Errors = {
- "invalid encoding for BBAddrMap::Features: 0x20",
+ "invalid encoding for BBAddrMap::Features: 0x40",
"invalid encoding for BBAddrMap::Features: 0xf0"};
- const std::array<uint8_t, 2> Values = {{0b10'0000, 0b1111'0000}};
+ const std::array<uint8_t, 2> Values = {{0b100'0000, 0b1111'0000}};
for (const auto &[Val, Error] : llvm::zip(Values, Errors)) {
EXPECT_THAT_ERROR(BBAddrMap::Features::decode(Val).takeError(),
FailedWithMessage(Error));
More information about the llvm-commits
mailing list