Skip to content
Merged
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
42 changes: 26 additions & 16 deletions llvm/include/llvm/Object/ELFTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,30 +834,32 @@ struct BBAddrMap {
bool OmitBBEntries : 1;
bool CallsiteEndOffsets : 1;
bool BBHash : 1;
bool PostLinkCfg : 1;

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

bool hasPGOAnalysisBBData() const { return BBFreq || BrProb; }

// Encodes to minimum bit width representation.
uint8_t encode() const {
return (static_cast<uint8_t>(FuncEntryCount) << 0) |
(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>(CallsiteEndOffsets) << 5) |
(static_cast<uint8_t>(BBHash) << 6);
uint16_t encode() const {
return (static_cast<uint16_t>(FuncEntryCount) << 0) |
(static_cast<uint16_t>(BBFreq) << 1) |
(static_cast<uint16_t>(BrProb) << 2) |
(static_cast<uint16_t>(MultiBBRange) << 3) |
(static_cast<uint16_t>(OmitBBEntries) << 4) |
(static_cast<uint16_t>(CallsiteEndOffsets) << 5) |
(static_cast<uint16_t>(BBHash) << 6) |
(static_cast<uint16_t>(PostLinkCfg) << 7);
}

// Decodes from minimum bit width representation and validates no
// unnecessary bits are used.
static Expected<Features> decode(uint8_t Val) {
static Expected<Features> decode(uint16_t Val) {
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 << 6))};
static_cast<bool>(Val & (1 << 6)), static_cast<bool>(Val & (1 << 7))};
if (Feat.encode() != Val)
return createStringError(
std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
Expand All @@ -867,10 +869,11 @@ struct BBAddrMap {

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

Expand Down Expand Up @@ -1010,23 +1013,30 @@ struct PGOAnalysisMap {
/// probability associated with it.
struct SuccessorEntry {
/// Unique ID of this successor basic block.
uint32_t ID;
uint32_t ID = 0;
/// Branch Probability of the edge to this successor taken from MBPI.
BranchProbability Prob;
/// Raw edge count from the post link profile (e.g., from bolt or
/// propeller).
uint64_t PostLinkFreq = 0;

bool operator==(const SuccessorEntry &Other) const {
return std::tie(ID, Prob) == std::tie(Other.ID, Other.Prob);
return std::tie(ID, Prob, PostLinkFreq) ==
std::tie(Other.ID, Other.Prob, Other.PostLinkFreq);
}
};

/// Block frequency taken from MBFI
BlockFrequency BlockFreq;
/// Raw block count taken from the post link profile (e.g., from bolt or
/// propeller).
uint64_t PostLinkBlockFreq = 0;
/// List of successors of the current block
llvm::SmallVector<SuccessorEntry, 2> Successors;

bool operator==(const PGOBBEntry &Other) const {
return std::tie(BlockFreq, Successors) ==
std::tie(Other.BlockFreq, Other.Successors);
return std::tie(BlockFreq, PostLinkBlockFreq, Successors) ==
std::tie(Other.BlockFreq, PostLinkBlockFreq, Other.Successors);
}
};

Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/ObjectYAML/ELFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ struct BBAddrMapEntry {
std::optional<llvm::yaml::Hex64> Hash;
};
uint8_t Version;
llvm::yaml::Hex8 Feature;
llvm::yaml::Hex16 Feature;

struct BBRangeEntry {
llvm::yaml::Hex64 BaseAddress;
Expand Down Expand Up @@ -203,8 +203,10 @@ struct PGOAnalysisMapEntry {
struct SuccessorEntry {
uint32_t ID;
llvm::yaml::Hex32 BrProb;
std::optional<uint32_t> PostLinkBrFreq;
};
std::optional<uint64_t> BBFreq;
std::optional<uint32_t> PostLinkBBFreq;
std::optional<std::vector<SuccessorEntry>> Successors;
};
std::optional<uint64_t> FuncEntryCount;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
MF.hasBBSections() && NumMBBSectionRanges > 1,
// Use static_cast to avoid breakage of tests on windows.
static_cast<bool>(BBAddrMapSkipEmitBBEntries), HasCalls,
static_cast<bool>(EmitBBHash)};
static_cast<bool>(EmitBBHash), false};
}

void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
Expand Down
26 changes: 21 additions & 5 deletions llvm/lib/Object/ELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,17 +831,17 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
};

uint8_t Version = 0;
uint8_t Feature = 0;
uint16_t Feature = 0;
BBAddrMap::Features FeatEnable{};
while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
Cur.tell() < Content.size()) {
Version = Data.getU8(Cur);
if (!Cur)
break;
if (Version < 2 || Version > 4)
if (Version < 2 || Version > 5)
return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
Twine(static_cast<int>(Version)));
Feature = Data.getU8(Cur); // Feature byte
Feature = Version < 5 ? Data.getU8(Cur) : Data.getU16(Cur);
if (!Cur)
break;
auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
Expand All @@ -858,6 +858,11 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
"basic block hash feature is enabled: version = " +
Twine(static_cast<int>(Version)) +
" feature = " + Twine(static_cast<int>(Feature)));
if (FeatEnable.PostLinkCfg && Version < 5)
return createError("version should be >= 5 for SHT_LLVM_BB_ADDR_MAP when "
"post link cfg 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 @@ -946,6 +951,10 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
uint64_t BBF = FeatEnable.BBFreq
? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
: 0;
uint32_t PostLinkBBFreq =
FeatEnable.PostLinkCfg
? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
: 0;

// Branch probability
llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2>
Expand All @@ -955,13 +964,20 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
for (uint64_t I = 0; I < SuccCount; ++I) {
uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
uint32_t PostLinkFreq =
FeatEnable.PostLinkCfg
? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
: 0;

if (PGOAnalyses)
Successors.push_back({BBID, BranchProbability::getRaw(BrProb)});
Successors.push_back(
{BBID, BranchProbability::getRaw(BrProb), PostLinkFreq});
}
}

if (PGOAnalyses)
PGOBBEntries.push_back({BlockFrequency(BBF), std::move(Successors)});
PGOBBEntries.push_back(
{BlockFrequency(BBF), PostLinkBBFreq, std::move(Successors)});
}

if (PGOAnalyses)
Expand Down
18 changes: 14 additions & 4 deletions llvm/lib/ObjectYAML/ELFEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1465,13 +1465,19 @@ 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 > 4)
if (E.Version > 5)
WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
<< static_cast<int>(E.Version)
<< "; encoding using the most recent version";
CBA.write(E.Version);
CBA.write(E.Feature);
SHeader.sh_size += 2;
SHeader.sh_size += 1;
if (E.Version < 5) {
CBA.write(static_cast<uint8_t>(E.Feature));
SHeader.sh_size += 1;
} else {
CBA.write<uint16_t>(E.Feature, ELFT::Endianness);
SHeader.sh_size += 2;
}
}
auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
bool MultiBBRangeFeatureEnabled = false;
Expand Down Expand Up @@ -1556,11 +1562,15 @@ void ELFState<ELFT>::writeSectionContent(
for (const auto &PGOBBE : PGOBBEntries) {
if (PGOBBE.BBFreq)
SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);
if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
SHeader.sh_size += CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
if (PGOBBE.Successors) {
SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());
for (const auto &[ID, BrProb] : *PGOBBE.Successors) {
for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
SHeader.sh_size += CBA.writeULEB128(ID);
SHeader.sh_size += CBA.writeULEB128(BrProb);
if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
SHeader.sh_size += CBA.writeULEB128(PostLinkBrFreq.value_or(0));
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1886,7 +1886,7 @@ void MappingTraits<ELFYAML::BBAddrMapEntry>::mapping(
IO &IO, ELFYAML::BBAddrMapEntry &E) {
assert(IO.getContext() && "The IO context is not initialized");
IO.mapRequired("Version", E.Version);
IO.mapOptional("Feature", E.Feature, Hex8(0));
IO.mapOptional("Feature", E.Feature, Hex16(0));
IO.mapOptional("NumBBRanges", E.NumBBRanges);
IO.mapOptional("BBRanges", E.BBRanges);
}
Expand Down Expand Up @@ -1920,6 +1920,7 @@ void MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry>::mapping(
IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &E) {
assert(IO.getContext() && "The IO context is not initialized");
IO.mapOptional("BBFreq", E.BBFreq);
IO.mapOptional("PostLinkBBFreq", E.PostLinkBBFreq);
IO.mapOptional("Successors", E.Successors);
}

Expand All @@ -1929,6 +1930,7 @@ void MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry>::
assert(IO.getContext() && "The IO context is not initialized");
IO.mapRequired("ID", E.ID);
IO.mapRequired("BrProb", E.BrProb);
IO.mapOptional("PostLinkBrFreq", E.PostLinkBrFreq);
}

void MappingTraits<ELFYAML::GnuHashHeader>::mapping(IO &IO,
Expand Down
37 changes: 37 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/bb-addr-map-feature-warning.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## This test checks that we output a warning when the specified version is too old to support the given features.

# RUN: yaml2obj %s -o %t
# RUN: llvm-readobj --bb-addr-map %t 2>&1 | FileCheck -DFILE=%t %s

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC

# CHECK: BBAddrMap [
# CHECK-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 1: version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when callsite offsets feature is enabled: version = 2 feature = 32
Sections:
- Name: '.llvm_bb_addr_map (1)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 2
Feature: 0x20

# CHECK: BBAddrMap [
# CHECK-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 2: version should be >= 4 for SHT_LLVM_BB_ADDR_MAP when basic block hash feature is enabled: version = 3 feature = 64

- Name: '.llvm_bb_addr_map (2)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 3
Feature: 0x40

# CHECK: BBAddrMap [
# CHECK-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: version should be >= 5 for SHT_LLVM_BB_ADDR_MAP when post link cfg feature is enabled: version = 4 feature = 128

- Name: '.llvm_bb_addr_map (3)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 4
Feature: 0x80
17 changes: 11 additions & 6 deletions llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

## Check that a malformed section can be handled.
# RUN: yaml2obj %s -DBITS=32 -DSIZE=24 -o %t2.o
# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck --match-full-lines %s -DOFFSET=0x00000018 -DFILE=%t2.o --check-prefix=TRUNCATED
# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck --match-full-lines %s -DOFFSET=0x00000015 -DFILE=%t2.o --check-prefix=TRUNCATED

## Check that missing features can be handled.
# RUN: yaml2obj %s -DBITS=32 -DFEATURE=0x2 -o %t3.o
Expand Down Expand Up @@ -59,17 +59,20 @@
# CHECK-NEXT: {
# RAW-NEXT: Frequency: 100
# PRETTY-NEXT: Frequency: 1.0
# CHECK-NEXT: PostLink Frequency: 10
# CHECK-NEXT: Successors [
# CHECK-NEXT: {
# CHECK-NEXT: ID: 2
# RAW-NEXT: Probability: 0x80000000
# PRETTY-NEXT: Probability: 0x80000000 / 0x80000000 = 100.00%
# CHECK-NEXT: PostLink Probability: 7
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: {
# RAW-NEXT: Frequency: 100
# PRETTY-NEXT: Frequency: 1.0
# CHECK-NEXT: PostLink Frequency: 0
# CHECK-NEXT: Successors [
# CHECK-NEXT: ]
# CHECK-NEXT: }
Expand Down Expand Up @@ -172,8 +175,8 @@ Sections:
ShSize: [[SIZE=<none>]]
Link: .text
Entries:
- Version: 2
Feature: 0x7
- Version: 5
Feature: 0x87
BBRanges:
- BaseAddress: [[ADDR=0x11111]]
BBEntries:
Expand All @@ -197,10 +200,12 @@ Sections:
PGOAnalyses:
- FuncEntryCount: 100
PGOBBEntries:
- BBFreq: 100
- BBFreq: 100
PostLinkBBFreq: 10
Successors:
- ID: 2
BrProb: 0x80000000
- ID: 2
BrProb: 0x80000000
PostLinkBrFreq: 7
- BBFreq: 100
Successors: []
- FuncEntryCount: 8888
Expand Down
Loading