Skip to content

Commit 6374da5

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 d328512 commit 6374da5

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
@@ -416,6 +416,12 @@ class ELFFile {
416416
Expected<std::vector<BBAddrMap>>
417417
decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec = nullptr) const;
418418

419+
/// Decodes same as decodeBBAddrMap but also decodes extra information from
420+
/// features which are enabled.
421+
Expected<std::vector<PGOBBAddrMap>>
422+
decodePGOBBAddrMap(const Elf_Shdr &Sec,
423+
const Elf_Shdr *RelaSec = nullptr) const;
424+
419425
/// Returns a map from every section matching \p IsMatch to its relocation
420426
/// section, or \p nullptr if it has no relocation section. This function
421427
/// 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
@@ -113,6 +113,9 @@ class ELFObjectFileBase : public ObjectFile {
113113
// corresponding to the section with that index.
114114
Expected<std::vector<BBAddrMap>>
115115
readBBAddrMap(std::optional<unsigned> TextSectionIndex = std::nullopt) const;
116+
117+
Expected<std::vector<PGOBBAddrMap>> readPGOBBAddrMap(
118+
std::optional<unsigned> TextSectionIndex = std::nullopt) const;
116119
};
117120

118121
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"
@@ -805,6 +808,11 @@ struct BBAddrMap {
805808
bool HasIndirectBranch : 1; // If this block ends with an indirect branch
806809
// (branch via a register).
807810

811+
// Number of bits used when encoding Metadata, that way an extension
812+
// can pack into the extra space if possible. This must be updated when
813+
// new bits are added here.
814+
static constexpr uint32_t NumberOfBits = 5;
815+
808816
bool operator==(const Metadata &Other) const {
809817
return HasReturn == Other.HasReturn &&
810818
HasTailCall == Other.HasTailCall && IsEHPad == Other.IsEHPad &&
@@ -875,6 +883,106 @@ struct BBAddrMap {
875883
std::vector<BBEntry> BBEntries; // Basic block entries for this function.
876884
};
877885

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

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)