Skip to content

Commit 746ac2e

Browse files
committed
Implements PGOBBAddrMap in Object and ObjectYAML with enough support for tests.
Removes public and adds check for number of bits.
1 parent 1f54ef7 commit 746ac2e

File tree

15 files changed

+1080
-91
lines changed

15 files changed

+1080
-91
lines changed

llvm/include/llvm/BinaryFormat/ELF.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ enum : unsigned {
10371037
SHT_LLVM_BB_ADDR_MAP = 0x6fff4c0a, // LLVM Basic Block Address Map.
10381038
SHT_LLVM_OFFLOADING = 0x6fff4c0b, // LLVM device offloading data.
10391039
SHT_LLVM_LTO = 0x6fff4c0c, // .llvm.lto for fat LTO.
1040+
SHT_LLVM_PGO_BB_ADDR_MAP = 0x6fff4c0d, // LLVM PGO extended BB Addr Map.
10401041
// Android's experimental support for SHT_RELR sections.
10411042
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
10421043
SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.

llvm/include/llvm/Object/ELF.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ class ELFFile {
417417
Expected<std::vector<BBAddrMap>>
418418
decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec = nullptr) const;
419419

420+
/// Decodes same as decodeBBAddrMap but also decodes extra information from
421+
/// features which are enabled.
422+
Expected<std::vector<PGOBBAddrMap>>
423+
decodePGOBBAddrMap(const Elf_Shdr &Sec,
424+
const Elf_Shdr *RelaSec = nullptr) const;
425+
420426
/// Returns a map from every section matching \p IsMatch to its relocation
421427
/// section, or \p nullptr if it has no relocation section. This function
422428
/// returns an error if any of the \p IsMatch calls fail or if it fails to

llvm/include/llvm/Object/ELFObjectFile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ class ELFObjectFileBase : public ObjectFile {
114114
// corresponding to the section with that index.
115115
Expected<std::vector<BBAddrMap>>
116116
readBBAddrMap(std::optional<unsigned> TextSectionIndex = std::nullopt) const;
117+
118+
Expected<std::vector<PGOBBAddrMap>> readPGOBBAddrMap(
119+
std::optional<unsigned> TextSectionIndex = std::nullopt) const;
117120
};
118121

119122
class ELFSectionRef : public SectionRef {

llvm/include/llvm/Object/ELFTypes.h

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
#define LLVM_OBJECT_ELFTYPES_H
1111

1212
#include "llvm/ADT/ArrayRef.h"
13+
#include "llvm/ADT/BitmaskEnum.h"
1314
#include "llvm/ADT/StringRef.h"
1415
#include "llvm/BinaryFormat/ELF.h"
1516
#include "llvm/Object/Error.h"
17+
#include "llvm/Support/BlockFrequency.h"
18+
#include "llvm/Support/BranchProbability.h"
1619
#include "llvm/Support/Endian.h"
1720
#include "llvm/Support/Error.h"
1821
#include "llvm/Support/MathExtras.h"
@@ -806,6 +809,11 @@ struct BBAddrMap {
806809
bool HasIndirectBranch : 1; // If this block ends with an indirect branch
807810
// (branch via a register).
808811

812+
// Number of bits used when encoding Metadata, that way an extension
813+
// can pack into the extra space if possible. This must be updated when
814+
// new bits are added here.
815+
static constexpr uint32_t NumberOfBits = 5;
816+
809817
bool operator==(const Metadata &Other) const {
810818
return HasReturn == Other.HasReturn &&
811819
HasTailCall == Other.HasTailCall && IsEHPad == Other.IsEHPad &&
@@ -865,6 +873,106 @@ struct BBAddrMap {
865873
}
866874
};
867875

876+
/// An extension of BBAddrMap that holds information relevant to PGO.
877+
struct PGOBBAddrMap {
878+
/// Bitmask of optional features to include in the PGO extended map.
879+
enum class Features {
880+
None = 0,
881+
FuncEntryCnt = (1 << 0),
882+
BBFreq = (1 << 1),
883+
BrProb = (1 << 2),
884+
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/BrProb),
885+
};
886+
887+
/// Super-set of BBAddrMap::BBEntry with additional fields for block frequency
888+
/// and branch probability.
889+
struct BBEntry {
890+
using BaseMetadata = BBAddrMap::BBEntry::Metadata;
891+
892+
/// Enum indicating the how many successors a block has. This enum must fit
893+
/// into two bits.
894+
enum class SuccessorsType {
895+
/// None should be present if PGOBBAddrMap has disabled branch
896+
/// probability.
897+
None = 0,
898+
/// Single successor blocks are not present in the successor entries.
899+
One = 1,
900+
/// Common case for conditional branches to avoid encoding size.
901+
Two = 2,
902+
/// Uncommon case which needs successor size to be encoded.
903+
Multiple = 3,
904+
};
905+
906+
/// Single successor of a given basic block that contains the tag and branch
907+
/// probability associated with it.
908+
struct SuccessorEntry {
909+
/// Unique ID of this successor basic block.
910+
uint32_t ID;
911+
/// Branch Probability of the edge to this successor taken from MBPI
912+
BranchProbability Prob;
913+
914+
bool operator==(const SuccessorEntry &Other) const {
915+
return std::tie(ID, Prob) == std::tie(Other.ID, Other.Prob);
916+
}
917+
};
918+
919+
/// Reuse of the fields provided by regular BBAddrMap
920+
BBAddrMap::BBEntry Base;
921+
/// Block frequency taken from MBFI
922+
BlockFrequency BlockFreq;
923+
/// List of successors of the current block
924+
llvm::SmallVector<SuccessorEntry, 2> Successors;
925+
926+
/// Converts number of successors into a SuccessorsType.
927+
static SuccessorsType getSuccessorsType(unsigned SuccessorsCount) {
928+
return SuccessorsCount == 0 ? SuccessorsType::None
929+
: SuccessorsCount == 1 ? SuccessorsType::One
930+
: SuccessorsCount == 2 ? SuccessorsType::Two
931+
: SuccessorsType::Multiple;
932+
}
933+
934+
/// Encodes extra information in the free bits of the base metadata
935+
static uint32_t encodeMD(BaseMetadata MD, SuccessorsType SuccType) {
936+
return MD.encode() | static_cast<uint32_t>(SuccType)
937+
<< BaseMetadata::NumberOfBits;
938+
}
939+
940+
/// Extracts successors type then defers all errors to the base metadata
941+
static Expected<std::pair<BaseMetadata, SuccessorsType>>
942+
decodeMD(uint32_t V) {
943+
auto SuccType = SuccessorsType((V >> BaseMetadata::NumberOfBits) & 0b11);
944+
V &= ~(0b11 << BaseMetadata::NumberOfBits); // Clear extra bits
945+
BaseMetadata MD;
946+
if (llvm::Error E = BaseMetadata::decode(V).moveInto(MD))
947+
return std::move(E);
948+
return std::make_pair(MD, SuccType);
949+
}
950+
951+
bool operator==(const BBEntry &Other) const {
952+
return std::tie(Base, BlockFreq, Successors) ==
953+
std::tie(Other.Base, Other.BlockFreq, Other.Successors);
954+
}
955+
};
956+
// This field is duplicated from BBAddrMap since this class needs a different
957+
// type for the vector of entries.
958+
uint64_t Addr; // Function address
959+
std::vector<BBEntry> BBEntries; // Extended basic block entries
960+
uint64_t FuncEntryCount; // Prof count from IR function
961+
962+
// Flags to indicate if each PGO related info was enabled in this function
963+
bool FuncEntryCountEnabled : 1;
964+
bool BBFreqEnabled : 1;
965+
bool BBSuccProbEnabled : 1;
966+
967+
bool operator==(const PGOBBAddrMap &Other) const {
968+
return std::tie(Addr, FuncEntryCount, BBEntries, FuncEntryCountEnabled,
969+
BBFreqEnabled, BBSuccProbEnabled) ==
970+
std::tie(Other.Addr, Other.FuncEntryCount, Other.BBEntries,
971+
Other.FuncEntryCountEnabled, Other.BBFreqEnabled,
972+
Other.BBSuccProbEnabled);
973+
}
974+
};
975+
868976
} // end namespace object.
869977
} // end namespace llvm.
870978

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,36 @@ struct DynamicEntry {
156156
llvm::yaml::Hex64 Val;
157157
};
158158

159+
struct BBAddrMapCommonBase {
160+
uint8_t Version;
161+
llvm::yaml::Hex8 Feature;
162+
llvm::yaml::Hex64 Address;
163+
std::optional<uint64_t> NumBlocks;
164+
};
165+
159166
struct BBAddrMapEntry {
160167
struct BBEntry {
161168
uint32_t ID;
162169
llvm::yaml::Hex64 AddressOffset;
163170
llvm::yaml::Hex64 Size;
164171
llvm::yaml::Hex64 Metadata;
165172
};
166-
uint8_t Version;
167-
llvm::yaml::Hex8 Feature;
168-
llvm::yaml::Hex64 Address;
169-
std::optional<uint64_t> NumBlocks;
173+
BBAddrMapCommonBase Common;
174+
std::optional<std::vector<BBEntry>> BBEntries;
175+
};
176+
177+
struct PGOBBAddrMapEntry {
178+
struct BBEntry {
179+
struct SuccessorEntry {
180+
uint32_t ID;
181+
llvm::yaml::Hex32 BrProb;
182+
};
183+
BBAddrMapEntry::BBEntry Base;
184+
std::optional<uint64_t> BBFreq;
185+
std::optional<std::vector<SuccessorEntry>> Successors;
186+
};
187+
BBAddrMapCommonBase Common;
188+
std::optional<uint64_t> FuncEntryCount;
170189
std::optional<std::vector<BBEntry>> BBEntries;
171190
};
172191

@@ -204,6 +223,7 @@ struct Chunk {
204223
DependentLibraries,
205224
CallGraphProfile,
206225
BBAddrMap,
226+
PGOBBAddrMap,
207227

208228
// Special chunks.
209229
SpecialChunksStart,
@@ -329,6 +349,20 @@ struct BBAddrMapSection : Section {
329349
}
330350
};
331351

352+
struct PGOBBAddrMapSection : Section {
353+
std::optional<std::vector<PGOBBAddrMapEntry>> Entries;
354+
355+
PGOBBAddrMapSection() : Section(ChunkKind::PGOBBAddrMap) {}
356+
357+
std::vector<std::pair<StringRef, bool>> getEntries() const override {
358+
return {{"Entries", Entries.has_value()}};
359+
};
360+
361+
static bool classof(const Chunk *S) {
362+
return S->Kind == ChunkKind::PGOBBAddrMap;
363+
}
364+
};
365+
332366
struct StackSizesSection : Section {
333367
std::optional<std::vector<StackSizeEntry>> Entries;
334368

@@ -737,6 +771,10 @@ bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
737771
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
738772
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
739773
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
774+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOBBAddrMapEntry)
775+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOBBAddrMapEntry::BBEntry)
776+
LLVM_YAML_IS_SEQUENCE_VECTOR(
777+
llvm::ELFYAML::PGOBBAddrMapEntry::BBEntry::SuccessorEntry)
740778
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
741779
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
742780
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
@@ -905,6 +943,20 @@ template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
905943
static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
906944
};
907945

946+
template <> struct MappingTraits<ELFYAML::PGOBBAddrMapEntry> {
947+
static void mapping(IO &IO, ELFYAML::PGOBBAddrMapEntry &Rel);
948+
};
949+
950+
template <> struct MappingTraits<ELFYAML::PGOBBAddrMapEntry::BBEntry> {
951+
static void mapping(IO &IO, ELFYAML::PGOBBAddrMapEntry::BBEntry &Rel);
952+
};
953+
954+
template <>
955+
struct MappingTraits<ELFYAML::PGOBBAddrMapEntry::BBEntry::SuccessorEntry> {
956+
static void mapping(IO &IO,
957+
ELFYAML::PGOBBAddrMapEntry::BBEntry::SuccessorEntry &Rel);
958+
};
959+
908960
template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
909961
static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
910962
};

llvm/lib/MC/MCParser/ELFAsmParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,8 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
673673
Type = ELF::SHT_LLVM_SYMPART;
674674
else if (TypeName == "llvm_bb_addr_map")
675675
Type = ELF::SHT_LLVM_BB_ADDR_MAP;
676+
else if (TypeName == "llvm_pgo_bb_addr_map")
677+
Type = ELF::SHT_LLVM_PGO_BB_ADDR_MAP;
676678
else if (TypeName == "llvm_offloading")
677679
Type = ELF::SHT_LLVM_OFFLOADING;
678680
else if (TypeName == "llvm_lto")

llvm/lib/MC/MCSectionELF.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
170170
OS << "llvm_bb_addr_map";
171171
else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP_V0)
172172
OS << "llvm_bb_addr_map_v0";
173+
else if (Type == ELF::SHT_LLVM_PGO_BB_ADDR_MAP)
174+
OS << "llvm_pgo_bb_addr_map";
173175
else if (Type == ELF::SHT_LLVM_OFFLOADING)
174176
OS << "llvm_offloading";
175177
else if (Type == ELF::SHT_LLVM_LTO)

0 commit comments

Comments
 (0)