Skip to content

Commit 26f0eba

Browse files
committed
Introduce the new SHT_LLVM_BB_ADDR_MAP version 3, to allow encoding callsite offsets.
1 parent f83d09a commit 26f0eba

File tree

12 files changed

+211
-93
lines changed

12 files changed

+211
-93
lines changed

llvm/include/llvm/Object/ELFTypes.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ struct BBAddrMap {
831831
bool BrProb : 1;
832832
bool MultiBBRange : 1;
833833
bool OmitBBEntries : 1;
834+
bool CallsiteOffsets : 1;
834835

835836
bool hasPGOAnalysis() const { return FuncEntryCount || BBFreq || BrProb; }
836837

@@ -842,7 +843,8 @@ struct BBAddrMap {
842843
(static_cast<uint8_t>(BBFreq) << 1) |
843844
(static_cast<uint8_t>(BrProb) << 2) |
844845
(static_cast<uint8_t>(MultiBBRange) << 3) |
845-
(static_cast<uint8_t>(OmitBBEntries) << 4);
846+
(static_cast<uint8_t>(OmitBBEntries) << 4) |
847+
(static_cast<uint8_t>(CallsiteOffsets) << 5);
846848
}
847849

848850
// Decodes from minimum bit width representation and validates no
@@ -851,7 +853,7 @@ struct BBAddrMap {
851853
Features Feat{
852854
static_cast<bool>(Val & (1 << 0)), static_cast<bool>(Val & (1 << 1)),
853855
static_cast<bool>(Val & (1 << 2)), static_cast<bool>(Val & (1 << 3)),
854-
static_cast<bool>(Val & (1 << 4))};
856+
static_cast<bool>(Val & (1 << 4)), static_cast<bool>(Val & (1 << 5))};
855857
if (Feat.encode() != Val)
856858
return createStringError(
857859
std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
@@ -861,9 +863,10 @@ struct BBAddrMap {
861863

862864
bool operator==(const Features &Other) const {
863865
return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange,
864-
OmitBBEntries) ==
866+
OmitBBEntries, CallsiteOffsets) ==
865867
std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
866-
Other.MultiBBRange, Other.OmitBBEntries);
868+
Other.MultiBBRange, Other.OmitBBEntries,
869+
Other.CallsiteOffsets);
867870
}
868871
};
869872

@@ -914,13 +917,18 @@ struct BBAddrMap {
914917
uint32_t Size = 0; // Size of the basic block.
915918
Metadata MD = {false, false, false, false,
916919
false}; // Metdata for this basic block.
920+
// Offsets of callsites (end of call instructions), relative to the basic
921+
// block start.
922+
SmallVector<uint32_t, 1> CallsiteOffsets;
917923

918-
BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD)
919-
: ID(ID), Offset(Offset), Size(Size), MD(MD){};
924+
BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD,
925+
SmallVector<uint32_t, 1> CallsiteOffsets)
926+
: ID(ID), Offset(Offset), Size(Size), MD(MD),
927+
CallsiteOffsets(std::move(CallsiteOffsets)) {}
920928

921929
bool operator==(const BBEntry &Other) const {
922930
return ID == Other.ID && Offset == Other.Offset && Size == Other.Size &&
923-
MD == Other.MD;
931+
MD == Other.MD && CallsiteOffsets == Other.CallsiteOffsets;
924932
}
925933

926934
bool hasReturn() const { return MD.HasReturn; }

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct BBAddrMapEntry {
162162
llvm::yaml::Hex64 AddressOffset;
163163
llvm::yaml::Hex64 Size;
164164
llvm::yaml::Hex64 Metadata;
165+
std::optional<std::vector<llvm::yaml::Hex64>> CallsiteOffsets;
165166
};
166167
uint8_t Version;
167168
llvm::yaml::Hex8 Feature;

llvm/lib/Object/ELF.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
837837
Version = Data.getU8(Cur);
838838
if (!Cur)
839839
break;
840-
if (Version > 2)
840+
if (Version > 3)
841841
return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
842842
Twine(static_cast<int>(Version)));
843843
Feature = Data.getU8(Cur); // Feature byte
@@ -893,7 +893,32 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
893893
? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
894894
: BlockIndex;
895895
uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
896-
uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
896+
// Read the callsite offsets.
897+
uint32_t LastCallsiteOffset = 0;
898+
SmallVector<uint32_t, 1> CallsiteOffsets;
899+
if (FeatEnable.CallsiteOffsets) {
900+
if (Version < 3) {
901+
return createError(
902+
"version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when "
903+
"callsite offsets feature is enabled: version = " +
904+
Twine(static_cast<int>(Version)) +
905+
" feature = " + Twine(static_cast<int>(Feature)));
906+
}
907+
uint32_t NumCallsites =
908+
readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
909+
CallsiteOffsets.reserve(NumCallsites);
910+
for (uint32_t CallsiteIndex = 0;
911+
!ULEBSizeErr && Cur && (CallsiteIndex < NumCallsites);
912+
++CallsiteIndex) {
913+
LastCallsiteOffset +=
914+
readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
915+
CallsiteOffsets.push_back(LastCallsiteOffset);
916+
}
917+
if (!Cur || ULEBSizeErr)
918+
break;
919+
}
920+
uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) +
921+
LastCallsiteOffset;
897922
uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
898923
if (Version >= 1) {
899924
// Offset is calculated relative to the end of the previous BB.
@@ -906,7 +931,8 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
906931
MetadataDecodeErr = MetadataOrErr.takeError();
907932
break;
908933
}
909-
BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
934+
BBEntries.push_back(
935+
{ID, Offset, Size, *MetadataOrErr, CallsiteOffsets});
910936
}
911937
TotalNumBlocks += BBEntries.size();
912938
}

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1452,7 +1452,7 @@ void ELFState<ELFT>::writeSectionContent(
14521452
for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) {
14531453
// Write version and feature values.
14541454
if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) {
1455-
if (E.Version > 2)
1455+
if (E.Version > 3)
14561456
WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
14571457
<< static_cast<int>(E.Version)
14581458
<< "; encoding using the most recent version";
@@ -1483,6 +1483,13 @@ void ELFState<ELFT>::writeSectionContent(
14831483
if (!E.BBRanges)
14841484
continue;
14851485
uint64_t TotalNumBlocks = 0;
1486+
bool EmitCallsiteOffsets = FeatureOrErr->CallsiteOffsets;
1487+
if (!EmitCallsiteOffsets) {
1488+
for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges)
1489+
for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries)
1490+
EmitCallsiteOffsets |=
1491+
BBE.CallsiteOffsets.has_value() && !BBE.CallsiteOffsets->empty();
1492+
}
14861493
for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
14871494
// Write the base address of the range.
14881495
CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);
@@ -1500,6 +1507,15 @@ void ELFState<ELFT>::writeSectionContent(
15001507
if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1)
15011508
SHeader.sh_size += CBA.writeULEB128(BBE.ID);
15021509
SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);
1510+
if (EmitCallsiteOffsets) {
1511+
uint32_t NumCallsites =
1512+
BBE.CallsiteOffsets.has_value() ? BBE.CallsiteOffsets->size() : 0;
1513+
SHeader.sh_size += CBA.writeULEB128(NumCallsites);
1514+
if (BBE.CallsiteOffsets.has_value()) {
1515+
for (uint32_t Offset : *BBE.CallsiteOffsets)
1516+
SHeader.sh_size += CBA.writeULEB128(Offset);
1517+
}
1518+
}
15031519
SHeader.sh_size += CBA.writeULEB128(BBE.Size);
15041520
SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);
15051521
}

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,7 @@ void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping(
18821882
IO.mapRequired("AddressOffset", E.AddressOffset);
18831883
IO.mapRequired("Size", E.Size);
18841884
IO.mapRequired("Metadata", E.Metadata);
1885+
IO.mapOptional("CallsiteOffsets", E.CallsiteOffsets);
18851886
}
18861887

18871888
void MappingTraits<ELFYAML::PGOAnalysisMapEntry>::mapping(

llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
# CHECK-NEXT: {
5050
# CHECK-NEXT: ID: 2
5151
# CHECK-NEXT: Offset: 0x3
52-
# CHECK-NEXT: Size: 0x4
52+
# CHECK-NEXT: Callsite Offsets: [1, 3]
53+
# CHECK-NEXT: Size: 0x7
5354
# CHECK-NEXT: HasReturn: Yes
5455
# CHECK-NEXT: HasTailCall: No
5556
# CHECK-NEXT: IsEHPad: Yes
@@ -75,7 +76,7 @@
7576
# CHECK-NEXT: HasTailCall: No
7677
# CHECK-NEXT: IsEHPad: No
7778
# CHECK-NEXT: CanFallThrough: Yes
78-
# CHECK-NEXT: HasIndirectBranch: No
79+
# CHECK-NEXT: HasIndirectBranch: No
7980
# CHECK-NEXT: }
8081
# CHECK-NEXT: ]
8182
# CHECK-NEXT: }
@@ -143,8 +144,8 @@ Sections:
143144
ShSize: [[SIZE=<none>]]
144145
Link: .text
145146
Entries:
146-
- Version: 2
147-
Feature: 0x8
147+
- Version: 3
148+
Feature: 0x28
148149
BBRanges:
149150
- BaseAddress: [[ADDR=0x11111]]
150151
BBEntries:
@@ -158,6 +159,7 @@ Sections:
158159
AddressOffset: 0x3
159160
Size: 0x4
160161
Metadata: 0x15
162+
CallsiteOffsets: [ 0x1 , 0x2 ]
161163
- Version: 2
162164
BBRanges:
163165
- BaseAddress: 0x22222

llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# VALID-NEXT: - Name: .llvm_bb_addr_map
1515
# VALID-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
1616
# VALID-NEXT: Entries:
17-
# VALID-NEXT: - Version: 2
17+
# VALID-NEXT: - Version: 3
1818
# VALID-NEXT: BBRanges:
1919
## The 'BaseAddress' field is omitted when it's zero.
2020
# VALID-NEXT: - BBEntries:
@@ -30,15 +30,16 @@
3030
# VALID-NEXT: AddressOffset: 0xFFFFFFFFFFFFFFF7
3131
# VALID-NEXT: Size: 0xFFFFFFFFFFFFFFF8
3232
# VALID-NEXT: Metadata: 0xFFFFFFFFFFFFFFF9
33-
# VALID-NEXT: - Version: 2
34-
# VALID-NEXT: Feature: 0x8
33+
# VALID-NEXT: - Version: 3
34+
# VALID-NEXT: Feature: 0x28
3535
# VALID-NEXT: BBRanges:
3636
# VALID-NEXT: - BaseAddress: 0xFFFFFFFFFFFFFF20
3737
# VALID-NEXT: BBEntries:
38-
# VALID-NEXT: - ID: 6
39-
# VALID-NEXT: AddressOffset: 0xA
40-
# VALID-NEXT: Size: 0xB
41-
# VALID-NEXT: Metadata: 0xC
38+
# VALID-NEXT: - ID: 6
39+
# VALID-NEXT: AddressOffset: 0xA
40+
# VALID-NEXT: Size: 0xB
41+
# VALID-NEXT: Metadata: 0xC
42+
# VALID-NEXT: CallsiteOffsets: [ 0x1, 0x2 ]
4243

4344
--- !ELF
4445
FileHeader:
@@ -50,7 +51,7 @@ Sections:
5051
Type: SHT_LLVM_BB_ADDR_MAP
5152
ShSize: [[SIZE=<none>]]
5253
Entries:
53-
- Version: 2
54+
- Version: 3
5455
Feature: 0x0
5556
BBRanges:
5657
- BaseAddress: 0x0
@@ -67,17 +68,18 @@ Sections:
6768
AddressOffset: 0xFFFFFFFFFFFFFFF7
6869
Size: 0xFFFFFFFFFFFFFFF8
6970
Metadata: 0xFFFFFFFFFFFFFFF9
70-
- Version: 2
71-
Feature: 0x8
71+
- Version: 3
72+
Feature: 0x28
7273
NumBBRanges: [[NUMBBRANGES=<none>]]
7374
BBRanges:
7475
- BaseAddress: 0xFFFFFFFFFFFFFF20
7576
NumBlocks: [[NUMBLOCKS=<none>]]
7677
BBEntries:
77-
- ID: 6
78-
AddressOffset: 0xA
79-
Size: 0xB
80-
Metadata: 0xC
78+
- ID: 6
79+
AddressOffset: 0xA
80+
Size: 0xB
81+
Metadata: 0xC
82+
CallsiteOffsets: [ 0x1, 0x2 ]
8183

8284
## Check obj2yaml can dump empty .llvm_bb_addr_map sections.
8385

0 commit comments

Comments
 (0)