Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions llvm/include/llvm/Object/ELFTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ struct BBAddrMap {
bool MultiBBRange : 1;
bool OmitBBEntries : 1;
bool CallsiteEndOffsets : 1;
bool BBHash : 1;

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

Expand All @@ -845,7 +846,8 @@ struct BBAddrMap {
(static_cast<uint8_t>(BrProb) << 2) |
(static_cast<uint8_t>(MultiBBRange) << 3) |
(static_cast<uint8_t>(OmitBBEntries) << 4) |
(static_cast<uint8_t>(CallsiteEndOffsets) << 5);
(static_cast<uint8_t>(CallsiteEndOffsets) << 5) |
(static_cast<uint8_t>(BBHash) << 6);
}

// Decodes from minimum bit width representation and validates no
Expand All @@ -854,7 +856,8 @@ 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 << 5))};
static_cast<bool>(Val & (1 << 4)), static_cast<bool>(Val & (1 << 5)),
static_cast<bool>(Val & (1 << 6))};
if (Feat.encode() != Val)
return createStringError(
std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
Expand All @@ -864,10 +867,10 @@ struct BBAddrMap {

bool operator==(const Features &Other) const {
return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange,
OmitBBEntries, CallsiteEndOffsets) ==
OmitBBEntries, CallsiteEndOffsets, BBHash) ==
std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
Other.MultiBBRange, Other.OmitBBEntries,
Other.CallsiteEndOffsets);
Other.CallsiteEndOffsets, Other.BBHash);
}
};

Expand Down Expand Up @@ -920,17 +923,19 @@ struct BBAddrMap {
false}; // Metdata for this basic block.
// Offsets of end of call instructions, relative to the basic block start.
SmallVector<uint32_t, 1> CallsiteEndOffsets;
uint64_t Hash = 0; // Hash for this basic block.

BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD,
SmallVector<uint32_t, 1> CallsiteEndOffsets)
SmallVector<uint32_t, 1> CallsiteEndOffsets, uint64_t Hash)
: ID(ID), Offset(Offset), Size(Size), MD(MD),
CallsiteEndOffsets(std::move(CallsiteEndOffsets)) {}
CallsiteEndOffsets(std::move(CallsiteEndOffsets)), Hash(Hash) {}

UniqueBBID getID() const { return {ID, 0}; }

bool operator==(const BBEntry &Other) const {
return ID == Other.ID && Offset == Other.Offset && Size == Other.Size &&
MD == Other.MD && CallsiteEndOffsets == Other.CallsiteEndOffsets;
MD == Other.MD && CallsiteEndOffsets == Other.CallsiteEndOffsets &&
Hash == Other.Hash;
}

bool hasReturn() const { return MD.HasReturn; }
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/ObjectYAML/ELFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct BBAddrMapEntry {
llvm::yaml::Hex64 Size;
llvm::yaml::Hex64 Metadata;
std::optional<std::vector<llvm::yaml::Hex64>> CallsiteEndOffsets;
std::optional<llvm::yaml::Hex64> Hash;
};
uint8_t Version;
llvm::yaml::Hex8 Feature;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,8 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
BrProbEnabled,
MF.hasBBSections() && NumMBBSectionRanges > 1,
static_cast<bool>(BBAddrMapSkipEmitBBEntries),
HasCalls};
HasCalls,
false};
}

void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
Expand Down
10 changes: 8 additions & 2 deletions llvm/lib/Object/ELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Version = Data.getU8(Cur);
if (!Cur)
break;
if (Version < 2 || Version > 3)
if (Version < 2 || Version > 4)
return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
Twine(static_cast<int>(Version)));
Feature = Data.getU8(Cur); // Feature byte
Expand All @@ -852,6 +852,11 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
"callsite offsets feature is enabled: version = " +
Twine(static_cast<int>(Version)) +
" feature = " + Twine(static_cast<int>(Feature)));
if (FeatEnable.BBHash && Version < 4)
return createError("version should be >= 4 for SHT_LLVM_BB_ADDR_MAP when "
"basic block hash feature is enabled: version = " +
Twine(static_cast<int>(Version)) +
" feature = " + Twine(static_cast<int>(Feature)));
uint32_t NumBlocksInBBRange = 0;
uint32_t NumBBRanges = 1;
typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0;
Expand Down Expand Up @@ -907,14 +912,15 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr) +
LastCallsiteEndOffset;
uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
uint64_t Hash = FeatEnable.BBHash ? Data.getU64(Cur) : 0;
Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
BBAddrMap::BBEntry::Metadata::decode(MD);
if (!MetadataOrErr) {
MetadataDecodeErr = MetadataOrErr.takeError();
break;
}
BBEntries.push_back({ID, Offset + PrevBBEndOffset, Size,
*MetadataOrErr, CallsiteEndOffsets});
*MetadataOrErr, CallsiteEndOffsets, Hash});
PrevBBEndOffset += Offset + Size;
}
TotalNumBlocks += BBEntries.size();
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/ObjectYAML/ELFEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,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 > 3)
if (E.Version > 4)
WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
<< static_cast<int>(E.Version)
<< "; encoding using the most recent version";
Expand Down Expand Up @@ -1526,6 +1526,12 @@ void ELFState<ELFT>::writeSectionContent(
}
SHeader.sh_size += CBA.writeULEB128(BBE.Size);
SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);
if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
uint64_t Hash =
BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
CBA.write<uint64_t>(Hash, ELFT::Endianness);
SHeader.sh_size += 8;
}
}
}
if (!PGOAnalyses)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1887,6 +1887,7 @@ void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping(
IO.mapRequired("Size", E.Size);
IO.mapRequired("Metadata", E.Metadata);
IO.mapOptional("CallsiteEndOffsets", E.CallsiteEndOffsets);
IO.mapOptional("Hash", E.Hash);
}

void MappingTraits<ELFYAML::PGOAnalysisMapEntry>::mapping(
Expand Down
7 changes: 5 additions & 2 deletions llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
# CHECK-NEXT: {
# CHECK-NEXT: ID: 0
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: Hash: 0x0
# CHECK-NEXT: Size: 0x1
# CHECK-NEXT: HasReturn: No
# CHECK-NEXT: HasTailCall: Yes
Expand All @@ -50,6 +51,7 @@
# CHECK-NEXT: ID: 2
# CHECK-NEXT: Offset: 0x3
# CHECK-NEXT: Callsite End Offsets: [1, 3]
# CHECK-NEXT: Hash: 0x123
# CHECK-NEXT: Size: 0x7
# CHECK-NEXT: HasReturn: Yes
# CHECK-NEXT: HasTailCall: No
Expand Down Expand Up @@ -144,8 +146,8 @@ Sections:
ShSize: [[SIZE=<none>]]
Link: .text
Entries:
- Version: 3
Feature: 0x28
- Version: 4
Feature: 0x68
BBRanges:
- BaseAddress: [[ADDR=0x11111]]
BBEntries:
Expand All @@ -160,6 +162,7 @@ Sections:
Size: 0x4
Metadata: 0x15
CallsiteEndOffsets: [ 0x1 , 0x2 ]
Hash: 0x123
- Version: 2
BBRanges:
- BaseAddress: 0x22222
Expand Down
86 changes: 86 additions & 0 deletions llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,92 @@ Sections:
BBRanges:
- BaseAddress: 0x20

## Check that obj2yaml can dump basic block hash in the .llvm_bb_addr_map section.

# RUN: yaml2obj --docnum=4 %s -o %t4
# RUN: obj2yaml %t4 | FileCheck %s --check-prefix=BBHASH

# BBHASH: --- !ELF
# BBHASH-NEXT: FileHeader:
# BBHASH-NEXT: Class: ELFCLASS64
# BBHASH-NEXT: Data: ELFDATA2LSB
# BBHASH-NEXT: Type: ET_EXEC
# BBHASH-NEXT: Sections:
# BBHASH-NEXT: - Name: .llvm_bb_addr_map
# BBHASH-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# BBHASH-NEXT: Entries:
# BBHASH-NEXT: - Version: 4
# BBHASH-NEXT: Feature: 0x40
# BBHASH-NEXT: BBRanges:
# BBHASH-NEXT: - BBEntries:
# BBHASH-NEXT: - ID: 0
# BBHASH-NEXT: AddressOffset: 0x1
# BBHASH-NEXT: Size: 0x2
# BBHASH-NEXT: Metadata: 0x3
# BBHASH-NEXT: Hash: 0x1
# BBHASH-NEXT: - ID: 2
# BBHASH-NEXT: AddressOffset: 0x4
# BBHASH-NEXT: Size: 0x5
# BBHASH-NEXT: Metadata: 0x6
# BBHASH-NEXT: Hash: 0x2
# BBHASH-NEXT: - ID: 4
# BBHASH-NEXT: AddressOffset: 0xFFFFFFFFFFFFFFF7
# BBHASH-NEXT: Size: 0xFFFFFFFFFFFFFFF8
# BBHASH-NEXT: Metadata: 0xFFFFFFFFFFFFFFF9
# BBHASH-NEXT: Hash: 0x3
# BBHASH-NEXT: - Version: 4
# BBHASH-NEXT: Feature: 0x68
# BBHASH-NEXT: BBRanges:
# BBHASH-NEXT: - BaseAddress: 0xFFFFFFFFFFFFFF20
# BBHASH-NEXT: BBEntries:
# BBHASH-NEXT: - ID: 6
# BBHASH-NEXT: AddressOffset: 0xA
# BBHASH-NEXT: Size: 0xB
# BBHASH-NEXT: Metadata: 0xC
# BBHASH-NEXT: CallsiteEndOffsets: [ 0x1, 0x2 ]
# BBHASH-NEXT: Hash: 0x123

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Sections:
- Name: .llvm_bb_addr_map
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 4
Feature: 0x40
BBRanges:
- BaseAddress: 0x0
BBEntries:
- ID: 0
AddressOffset: 0x1
Size: 0x2
Metadata: 0x3
Hash: 0x1
- ID: 2
AddressOffset: 0x4
Size: 0x5
Metadata: 0x6
Hash: 0x2
- ID: 4
AddressOffset: 0xFFFFFFFFFFFFFFF7
Size: 0xFFFFFFFFFFFFFFF8
Metadata: 0xFFFFFFFFFFFFFFF9
Hash: 0x3
- Version: 4
Feature: 0x68
BBRanges:
- BaseAddress: 0xFFFFFFFFFFFFFF20
BBEntries:
- ID: 6
AddressOffset: 0xA
Size: 0xB
Metadata: 0xC
CallsiteEndOffsets: [ 0x1, 0x2 ]
Hash: 0x123

## Check that obj2yaml uses the "Content" tag to describe an .llvm_bb_addr_map section
## when it can't extract the entries, for example, when the section is truncated, or
## when an invalid 'NumBlocks' or 'NumBBRanges` field is specified.
Expand Down
27 changes: 25 additions & 2 deletions llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@
# CHECK-NEXT: 0000: 03202000 00000000 0000010E 01000203
# CHECK-NEXT: )

# Case 10: Specify basic block hash.
# CHECK: Name: .llvm_bb_addr_map (1)
# CHECK: SectionData (
# CHECK-NEXT: 0000: 04602000 00000000 0000010E 01000203
# CHECK-NEXT: 0010: 23010000 00000000
# CHECK-NEXT: )


--- !ELF
FileHeader:
Expand Down Expand Up @@ -176,6 +183,22 @@ Sections:
Metadata: 0x00000003
CallsiteEndOffsets: []

## 10) We can produce a SHT_LLVM_BB_ADDR_MAP section with basic block hash.
- Name: '.llvm_bb_addr_map (10)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 4
Feature: 0x60
BBRanges:
- BaseAddress: 0x0000000000000020
BBEntries:
- ID: 14
AddressOffset: 0x00000001
Size: 0x00000002
Metadata: 0x00000003
CallsiteEndOffsets: []
Hash: 0x123

## 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
Expand All @@ -197,7 +220,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: 4; encoding using the most recent version
# INVALID-VERSION: warning: unsupported SHT_LLVM_BB_ADDR_MAP version: 5; encoding using the most recent version

--- !ELF
FileHeader:
Expand All @@ -209,4 +232,4 @@ Sections:
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
## Specify unsupported version
- Version: 4
- Version: 5
2 changes: 2 additions & 0 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8160,6 +8160,8 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {
W.printHex("Offset", BBE.Offset);
if (!BBE.CallsiteEndOffsets.empty())
W.printList("Callsite End Offsets", BBE.CallsiteEndOffsets);
if (PAM.FeatEnable.BBHash)
W.printHex("Hash", BBE.Hash);
W.printHex("Size", BBE.Size);
W.printBoolean("HasReturn", BBE.hasReturn());
W.printBoolean("HasTailCall", BBE.hasTailCall());
Expand Down
7 changes: 5 additions & 2 deletions llvm/tools/obj2yaml/elf2yaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,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 > 3)
if (Cur && Version > 4)
return createStringError(
errc::invalid_argument,
"invalid SHT_LLVM_BB_ADDR_MAP section version: " +
Expand Down Expand Up @@ -946,8 +946,11 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
}
uint64_t Size = Data.getULEB128(Cur);
uint64_t Metadata = Data.getULEB128(Cur);
std::optional<llvm::yaml::Hex64> Hash;
if (FeatureOrErr->BBHash)
Hash = Data.getU64(Cur);
BBEntries.push_back(
{ID, Offset, Size, Metadata, std::move(CallsiteEndOffsets)});
{ID, Offset, Size, Metadata, std::move(CallsiteEndOffsets), Hash});
}
TotalNumBlocks += BBEntries.size();
BBRanges.push_back({BaseAddress, /*NumBlocks=*/{}, BBEntries});
Expand Down
Loading