aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.def1
-rw-r--r--clang/include/clang/Driver/Options.td4
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp1
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp11
-rw-r--r--clang/test/Driver/basic-block-address-map.c8
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp3
-rw-r--r--lld/ELF/LTO.cpp2
-rw-r--r--lld/ELF/Options.td3
-rw-r--r--lld/test/ELF/lto/basic-block-address-map.ll28
-rw-r--r--llvm/include/llvm/CodeGen/CommandFlags.h2
-rw-r--r--llvm/include/llvm/Object/ELFTypes.h146
-rw-r--r--llvm/include/llvm/ObjectYAML/ELFYAML.h27
-rw-r--r--llvm/include/llvm/Target/TargetOptions.h6
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp91
-rw-r--r--llvm/lib/CodeGen/BasicBlockSections.cpp39
-rw-r--r--llvm/lib/CodeGen/CommandFlags.cpp7
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp1
-rw-r--r--llvm/lib/CodeGen/TargetPassConfig.cpp28
-rw-r--r--llvm/lib/Object/ELF.cpp132
-rw-r--r--llvm/lib/ObjectYAML/ELFEmitter.cpp58
-rw-r--r--llvm/lib/ObjectYAML/ELFYAML.cpp9
-rw-r--r--llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll (renamed from llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll)1
-rw-r--r--llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll71
-rw-r--r--llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll89
-rw-r--r--llvm/test/CodeGen/X86/basic-block-address-map.ll (renamed from llvm/test/CodeGen/X86/basic-block-sections-labels.ll)2
-rw-r--r--llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-disassemble-symbolize-operands.yaml214
-rw-r--r--llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-symbolize-relocatable.yaml50
-rw-r--r--llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml87
-rw-r--r--llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test164
-rw-r--r--llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test107
-rw-r--r--llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test272
-rw-r--r--llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml218
-rw-r--r--llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml71
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp206
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp43
-rw-r--r--llvm/tools/obj2yaml/elf2yaml.cpp46
-rw-r--r--llvm/unittests/Object/ELFObjectFileTest.cpp461
-rw-r--r--llvm/unittests/Object/ELFTypesTest.cpp38
39 files changed, 1697 insertions, 1051 deletions
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 7c0bfe3..6ad0503 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -96,6 +96,7 @@ ENUM_CODEGENOPT(InlineAsmDialect, InlineAsmDialectKind, 1, IAD_ATT)
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
///< are required.
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
+CODEGENOPT(BBAddrMap , 1, 0) ///< Set when -fbasic-block-address-map is enabled.
CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
///< enabled.
CODEGENOPT(InstrumentFunctionsAfterInlining , 1, 0) ///< Set when
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index a4b35e3..73071a6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3988,6 +3988,10 @@ defm function_sections : BoolFOption<"function-sections",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Place each function in its own section">,
NegFlag<SetFalse>>;
+defm basic_block_address_map : BoolFOption<"basic-block-address-map",
+ CodeGenOpts<"BBAddrMap">, DefaultFalse,
+ PosFlag<SetTrue, [], [CC1Option], "Emit the basic block address map section.">,
+ NegFlag<SetFalse>>;
def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group<f_Group>,
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Place each function's basic blocks in unique sections (ELF Only)">,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 7877e20..e2511aa 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -374,6 +374,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
LangOptions::FPModeKind::FPM_FastHonorPragmas);
Options.ApproxFuncFPMath = LangOpts.ApproxFunc;
+ Options.BBAddrMap = CodeGenOpts.BBAddrMap;
Options.BBSections =
llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
.Case("all", llvm::BasicBlockSection::All)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 6a5f0b3..7009248 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5944,6 +5944,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-ffunction-sections");
}
+ if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_address_map,
+ options::OPT_fno_basic_block_address_map)) {
+ if (Triple.isX86() && Triple.isOSBinFormatELF()) {
+ if (A->getOption().matches(options::OPT_fbasic_block_address_map))
+ A->render(Args, CmdArgs);
+ } else {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getAsString(Args) << TripleStr;
+ }
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_sections_EQ)) {
StringRef Val = A->getValue();
if (Triple.isX86() && Triple.isOSBinFormatELF()) {
diff --git a/clang/test/Driver/basic-block-address-map.c b/clang/test/Driver/basic-block-address-map.c
new file mode 100644
index 0000000..022f972
--- /dev/null
+++ b/clang/test/Driver/basic-block-address-map.c
@@ -0,0 +1,8 @@
+// RUN: %clang -### -target x86_64 -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s
+// CHECK-PRESENT: -fbasic-block-address-map
+
+// RUN: %clang -### -target x86_64 -fno-basic-block-address-map %s -S 2>&1 | FileCheck %s --check-prefix=CHECK-ABSENT
+// CHECK-ABSENT-NOT: -fbasic-block-address-map
+
+// RUN: not %clang -c -target x86_64-apple-darwin10 -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s
+// CHECK-TRIPLE: error: unsupported option '-fbasic-block-address-map' for target
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 3a4a47d..fcca8c4 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -187,6 +187,7 @@ struct Config {
llvm::StringRef cmseOutputLib;
StringRef zBtiReport = "none";
StringRef zCetReport = "none";
+ bool ltoBBAddrMap;
llvm::StringRef ltoBasicBlockSections;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
llvm::StringRef thinLTOPrefixReplaceOld;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index f4b7d1c..c19fba6 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1298,6 +1298,9 @@ static void readConfigs(opt::InputArgList &args) {
config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
+ config->ltoBBAddrMap =
+ args.hasFlag(OPT_lto_basic_block_address_map,
+ OPT_no_lto_basic_block_address_map, false);
config->ltoBasicBlockSections =
args.getLastArgValue(OPT_lto_basic_block_sections);
config->ltoUniqueBasicBlockSectionNames =
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index c39c6e6..3d92007 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -61,6 +61,8 @@ static lto::Config createConfig() {
c.Options.FunctionSections = true;
c.Options.DataSections = true;
+ c.Options.BBAddrMap = config->ltoBBAddrMap;
+
// Check if basic block sections must be used.
// Allowed values for --lto-basic-block-sections are "all", "labels",
// "<file name specifying basic block ids>", or none. This is the equivalent
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index c2c9cab..c10a73e 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -637,6 +637,9 @@ def save_temps_eq: JJ<"save-temps=">, HelpText<"Save select intermediate LTO com
Values<"resolution,preopt,promote,internalize,import,opt,precodegen,prelink,combinedindex">;
def lto_basic_block_sections: JJ<"lto-basic-block-sections=">,
HelpText<"Enable basic block sections for LTO">;
+defm lto_basic_block_address_map: BB<"lto-basic-block-address-map",
+ "Emit basic block address map for LTO",
+ "Do not emit basic block address map for LTO (default)">;
defm lto_unique_basic_block_section_names: BB<"lto-unique-basic-block-section-names",
"Give unique names to every basic block section for LTO",
"Do not give unique names to every basic block section for LTO (default)">;
diff --git a/lld/test/ELF/lto/basic-block-address-map.ll b/lld/test/ELF/lto/basic-block-address-map.ll
new file mode 100644
index 0000000..b96e7a8
--- /dev/null
+++ b/lld/test/ELF/lto/basic-block-address-map.ll
@@ -0,0 +1,28 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld %t.o -o %t --lto-basic-block-address-map --lto-O0 --save-temps
+; RUN: llvm-readobj --sections %t.lto.o | FileCheck --check-prefix=SECNAMES %s
+
+; SECNAMES: Type: SHT_LLVM_BB_ADDR_MAP
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define dso_local void @foo(i32 %b) local_unnamed_addr {
+entry:
+ %tobool.not = icmp eq i32 %b, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ tail call void @foo(i32 0)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ ret void
+}
+
+define void @_start() {
+ call void @foo(i32 1)
+ ret void
+}
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index bf166a6..d74d724 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -159,6 +159,8 @@ struct RegisterCodeGenFlags {
RegisterCodeGenFlags();
};
+bool getEnableBBAddrMap();
+
llvm::BasicBlockSection getBBSectionsMode(llvm::TargetOptions &Options);
/// Common utility function tightly tied to the options listed here. Initializes
diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h
index 956f781..4986ecf 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -796,6 +796,47 @@ template <class ELFT> struct Elf_Mips_ABIFlags {
// Struct representing the BBAddrMap for one function.
struct BBAddrMap {
+
+ // Bitfield of optional features to control the extra information
+ // emitted/encoded in the the section.
+ struct Features {
+ bool FuncEntryCount : 1;
+ bool BBFreq : 1;
+ bool BrProb : 1;
+ bool MultiBBRange : 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);
+ }
+
+ // Decodes from minimum bit width representation and validates no
+ // unnecessary bits are used.
+ static Expected<Features> decode(uint8_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))};
+ if (Feat.encode() != Val)
+ return createStringError(
+ std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
+ Val);
+ return Feat;
+ }
+
+ bool operator==(const Features &Other) const {
+ return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange) ==
+ std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
+ Other.MultiBBRange);
+ }
+ };
+
// Struct representing the BBAddrMap information for one basic block.
struct BBEntry {
struct Metadata {
@@ -838,10 +879,11 @@ struct BBAddrMap {
}
};
- uint32_t ID; // Unique ID of this basic block.
- uint32_t Offset; // Offset of basic block relative to function start.
- uint32_t Size; // Size of the basic block.
- Metadata MD; // Metdata for this basic block.
+ uint32_t ID = 0; // Unique ID of this basic block.
+ uint32_t Offset = 0; // Offset of basic block relative to the base address.
+ uint32_t Size = 0; // Size of the basic block.
+ Metadata MD = {false, false, false, false,
+ false}; // Metdata for this basic block.
BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD)
: ID(ID), Offset(Offset), Size(Size), MD(MD){};
@@ -858,62 +900,64 @@ struct BBAddrMap {
bool hasIndirectBranch() const { return MD.HasIndirectBranch; }
};
- BBAddrMap(uint64_t Addr, std::vector<BBEntry> BBEntries)
- : Addr(Addr), BBEntries(std::move(BBEntries)) {}
+ // Struct representing the BBAddrMap information for a contiguous range of
+ // basic blocks (a function or a basic block section).
+ struct BBRangeEntry {
+ uint64_t BaseAddress = 0; // Base address of the range.
+ std::vector<BBEntry> BBEntries; // Basic block entries for this range.
+
+ // Equality operator for unit testing.
+ bool operator==(const BBRangeEntry &Other) const {
+ return BaseAddress == Other.BaseAddress &&
+ std::equal(BBEntries.begin(), BBEntries.end(),
+ Other.BBEntries.begin());
+ }
+ };
- // Returns the address of the corresponding function.
- uint64_t getFunctionAddress() const { return Addr; }
+ // All ranges for this function. Cannot be empty. The first range always
+ // corresponds to the function entry.
+ std::vector<BBRangeEntry> BBRanges;
- // Returns the basic block entries for this function.
- const std::vector<BBEntry> &getBBEntries() const { return BBEntries; }
+ // Returns the function address associated with this BBAddrMap, which is
+ // stored as the `BaseAddress` of its first BBRangeEntry.
+ uint64_t getFunctionAddress() const {
+ assert(!BBRanges.empty());
+ return BBRanges.front().BaseAddress;
+ }
+
+ // Returns the total number of bb entries in all bb ranges.
+ size_t getNumBBEntries() const {
+ size_t NumBBEntries = 0;
+ for (const auto &BBR : BBRanges)
+ NumBBEntries += BBR.BBEntries.size();
+ return NumBBEntries;
+ }
+
+ // Returns the index of the bb range with the given base address, or
+ // `std::nullopt` if no such range exists.
+ std::optional<size_t>
+ getBBRangeIndexForBaseAddress(uint64_t BaseAddress) const {
+ for (size_t I = 0; I < BBRanges.size(); ++I)
+ if (BBRanges[I].BaseAddress == BaseAddress)
+ return I;
+ return {};
+ }
+
+ // Returns bb entries in the first range.
+ const std::vector<BBEntry> &getBBEntries() const {
+ return BBRanges.front().BBEntries;
+ }
+
+ const std::vector<BBRangeEntry> &getBBRanges() const { return BBRanges; }
// Equality operator for unit testing.
bool operator==(const BBAddrMap &Other) const {
- return Addr == Other.Addr && std::equal(BBEntries.begin(), BBEntries.end(),
- Other.BBEntries.begin());
+ return std::equal(BBRanges.begin(), BBRanges.end(), Other.BBRanges.begin());
}
-
- uint64_t Addr; // Function address
- std::vector<BBEntry> BBEntries; // Basic block entries for this function.
};
/// A feature extension of BBAddrMap that holds information relevant to PGO.
struct PGOAnalysisMap {
- /// Bitfield of optional features to include in the PGO extended map.
- struct Features {
- bool FuncEntryCount : 1;
- bool BBFreq : 1;
- bool BrProb : 1;
-
- // True if at least one feature is enabled
- bool anyEnabled() const { return FuncEntryCount || 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);
- }
-
- // Decodes from minimum bit width representation and validates no
- // unnecessary bits are used.
- static Expected<Features> decode(uint8_t Val) {
- Features Feat{static_cast<bool>(Val & (1 << 0)),
- static_cast<bool>(Val & (1 << 1)),
- static_cast<bool>(Val & (1 << 2))};
- if (Feat.encode() != Val)
- return createStringError(
- std::error_code(),
- "invalid encoding for PGOAnalysisMap::Features: 0x%x", Val);
- return Feat;
- }
-
- bool operator==(const Features &Other) const {
- return std::tie(FuncEntryCount, BBFreq, BrProb) ==
- std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb);
- }
- };
-
/// Extra basic block data with fields for block frequency and branch
/// probability.
struct PGOBBEntry {
@@ -945,7 +989,7 @@ struct PGOAnalysisMap {
std::vector<PGOBBEntry> BBEntries; // Extended basic block entries
// Flags to indicate if each PGO related info was enabled in this function
- Features FeatEnable;
+ BBAddrMap::Features FeatEnable;
bool operator==(const PGOAnalysisMap &Other) const {
return std::tie(FuncEntryCount, BBEntries, FeatEnable) ==
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index 12b47c2..8f045d6 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -165,9 +165,21 @@ struct BBAddrMapEntry {
};
uint8_t Version;
llvm::yaml::Hex8 Feature;
- llvm::yaml::Hex64 Address;
- std::optional<uint64_t> NumBlocks;
- std::optional<std::vector<BBEntry>> BBEntries;
+
+ struct BBRangeEntry {
+ llvm::yaml::Hex64 BaseAddress;
+ std::optional<uint64_t> NumBlocks;
+ std::optional<std::vector<BBEntry>> BBEntries;
+ };
+
+ std::optional<uint64_t> NumBBRanges;
+ std::optional<std::vector<BBRangeEntry>> BBRanges;
+
+ llvm::yaml::Hex64 getFunctionAddress() const {
+ if (!BBRanges || BBRanges->empty())
+ return 0;
+ return BBRanges->front().BaseAddress;
+ }
};
struct PGOAnalysisMapEntry {
@@ -751,6 +763,7 @@ bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(
@@ -916,11 +929,15 @@ template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
};
template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
- static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
+ static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
+};
+
+template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
+ static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
};
template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
- static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
+ static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
};
template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index d02d169..7df8010 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -148,7 +148,7 @@ namespace llvm {
EmulatedTLS(false), EnableTLSDESC(false), EnableIPRA(false),
EmitStackSizeSection(false), EnableMachineOutliner(false),
EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
- EmitAddrsig(false), EmitCallSiteInfo(false),
+ EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
@@ -316,6 +316,10 @@ namespace llvm {
/// Emit address-significance table.
unsigned EmitAddrsig : 1;
+ // Emit the SHT_LLVM_BB_ADDR_MAP section containing basic block address
+ // which can be used to map virtual addresses to machine basic blocks.
+ unsigned BBAddrMap : 1;
+
/// Emit basic blocks into separate sections.
BasicBlockSection BBSections = BasicBlockSection::None;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0d57356..b961fc2 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -151,8 +151,9 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
"Basic Block Frequency"),
clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob",
"Branch Probability")),
- cl::desc("Enable extended information within the BBAddrMap that is "
- "extracted from PGO related analysis."));
+ cl::desc(
+ "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "
+ "extracted from PGO related analysis."));
const char DWARFGroupName[] = "dwarf";
const char DWARFGroupDescription[] = "DWARF Emission";
@@ -1371,6 +1372,14 @@ static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
.encode();
}
+static llvm::object::BBAddrMap::Features
+getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) {
+ return {PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::FuncEntryCount),
+ PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BBFreq),
+ PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb),
+ MF.hasBBSections() && NumMBBSectionRanges > 1};
+}
+
void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
MCSection *BBAddrMapSection =
getObjFileLowering().getBBAddrMapSection(*MF.getSection());
@@ -1384,17 +1393,48 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion();
OutStreamer->emitInt8(BBAddrMapVersion);
OutStreamer->AddComment("feature");
- auto FeaturesBits = static_cast<uint8_t>(PgoAnalysisMapFeatures.getBits());
- OutStreamer->emitInt8(FeaturesBits);
- OutStreamer->AddComment("function address");
- OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
- OutStreamer->AddComment("number of basic blocks");
- OutStreamer->emitULEB128IntValue(MF.size());
- const MCSymbol *PrevMBBEndSymbol = FunctionSymbol;
+ auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size());
+ OutStreamer->emitInt8(Features.encode());
// Emit BB Information for each basic block in the function.
+ if (Features.MultiBBRange) {
+ OutStreamer->AddComment("number of basic block ranges");
+ OutStreamer->emitULEB128IntValue(MBBSectionRanges.size());
+ }
+ // Number of blocks in each MBB section.
+ MapVector<unsigned, unsigned> MBBSectionNumBlocks;
+ const MCSymbol *PrevMBBEndSymbol = nullptr;
+ if (!Features.MultiBBRange) {
+ OutStreamer->AddComment("function address");
+ OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
+ OutStreamer->AddComment("number of basic blocks");
+ OutStreamer->emitULEB128IntValue(MF.size());
+ PrevMBBEndSymbol = FunctionSymbol;
+ } else {
+ unsigned BBCount = 0;
+ for (const MachineBasicBlock &MBB : MF) {
+ BBCount++;
+ if (MBB.isEndSection()) {
+ // Store each section's basic block count when it ends.
+ MBBSectionNumBlocks[MBB.getSectionIDNum()] = BBCount;
+ // Reset the count for the next section.
+ BBCount = 0;
+ }
+ }
+ }
+ // Emit the BB entry for each basic block in the function.
for (const MachineBasicBlock &MBB : MF) {
const MCSymbol *MBBSymbol =
MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
+ bool IsBeginSection =
+ Features.MultiBBRange && (MBB.isBeginSection() || MBB.isEntryBlock());
+ if (IsBeginSection) {
+ OutStreamer->AddComment("base address");
+ OutStreamer->emitSymbolValue(MBBSymbol, getPointerSize());
+ OutStreamer->AddComment("number of basic blocks");
+ OutStreamer->emitULEB128IntValue(
+ MBBSectionNumBlocks[MBB.getSectionIDNum()]);
+ PrevMBBEndSymbol = MBBSymbol;
+ }
// TODO: Remove this check when version 1 is deprecated.
if (BBAddrMapVersion > 1) {
OutStreamer->AddComment("BB id");
@@ -1416,35 +1456,32 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
PrevMBBEndSymbol = MBB.getEndSymbol();
}
- if (FeaturesBits != 0) {
+ if (Features.hasPGOAnalysis()) {
assert(BBAddrMapVersion >= 2 &&
"PGOAnalysisMap only supports version 2 or later");
- auto FeatEnable =
- cantFail(object::PGOAnalysisMap::Features::decode(FeaturesBits));
-
- if (FeatEnable.FuncEntryCount) {
+ if (Features.FuncEntryCount) {
OutStreamer->AddComment("function entry count");
auto MaybeEntryCount = MF.getFunction().getEntryCount();
OutStreamer->emitULEB128IntValue(
MaybeEntryCount ? MaybeEntryCount->getCount() : 0);
}
const MachineBlockFrequencyInfo *MBFI =
- FeatEnable.BBFreq
+ Features.BBFreq
? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
: nullptr;
const MachineBranchProbabilityInfo *MBPI =
- FeatEnable.BrProb ? &getAnalysis<MachineBranchProbabilityInfo>()
- : nullptr;
+ Features.BrProb ? &getAnalysis<MachineBranchProbabilityInfo>()
+ : nullptr;
- if (FeatEnable.BBFreq || FeatEnable.BrProb) {
+ if (Features.BBFreq || Features.BrProb) {
for (const MachineBasicBlock &MBB : MF) {
- if (FeatEnable.BBFreq) {
+ if (Features.BBFreq) {
OutStreamer->AddComment("basic block frequency");
OutStreamer->emitULEB128IntValue(
MBFI->getBlockFreq(&MBB).getFrequency());
}
- if (FeatEnable.BrProb) {
+ if (Features.BrProb) {
unsigned SuccCount = MBB.succ_size();
OutStreamer->AddComment("basic block successor count");
OutStreamer->emitULEB128IntValue(SuccCount);
@@ -1833,7 +1870,7 @@ void AsmPrinter::emitFunctionBody() {
// We must emit temporary symbol for the end of this basic block, if either
// we have BBLabels enabled or if this basic blocks marks the end of a
// section.
- if (MF->hasBBLabels() ||
+ if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap ||
(MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection()))
OutStreamer->emitLabel(MBB.getEndSymbol());
@@ -1986,7 +2023,7 @@ void AsmPrinter::emitFunctionBody() {
// Emit section containing BB address offsets and their metadata, when
// BB labels are requested for this function. Skip empty functions.
if (HasAnyRealCode) {
- if (MF->hasBBLabels())
+ if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap)
emitBBAddrMapSection(*MF);
else if (PgoAnalysisMapFeatures.getBits() != 0)
MF->getContext().reportWarning(
@@ -2580,9 +2617,9 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
bool NeedsLocalForSize = MAI->needsLocalForSize();
if (F.hasFnAttribute("patchable-function-entry") ||
F.hasFnAttribute("function-instrument") ||
- F.hasFnAttribute("xray-instruction-threshold") ||
- needFuncLabels(MF) || NeedsLocalForSize ||
- MF.getTarget().Options.EmitStackSizeSection || MF.hasBBLabels()) {
+ F.hasFnAttribute("xray-instruction-threshold") || needFuncLabels(MF) ||
+ NeedsLocalForSize || MF.getTarget().Options.EmitStackSizeSection ||
+ MF.getTarget().Options.BBAddrMap || MF.hasBBLabels()) {
CurrentFnBegin = createTempSymbol("func_begin");
if (NeedsLocalForSize)
CurrentFnSymForSize = CurrentFnBegin;
@@ -4049,7 +4086,9 @@ bool AsmPrinter::shouldEmitLabelForBasicBlock(
// With `-fbasic-block-sections=`, a label is needed for every non-entry block
// in the labels mode (option `=labels`) and every section beginning in the
// sections mode (`=all` and `=list=`).
- if ((MF->hasBBLabels() || MBB.isBeginSection()) && !MBB.isEntryBlock())
+ if ((MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap ||
+ MBB.isBeginSection()) &&
+ !MBB.isEntryBlock())
return true;
// A label is needed for any block with at least one predecessor (when that
// predecessor is not the fallthrough predecessor, or if it is an EH funclet
diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp
index dbb6ebb..eb3f9e7 100644
--- a/llvm/lib/CodeGen/BasicBlockSections.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSections.cpp
@@ -57,10 +57,10 @@
// function into potentially several disjoint pieces, and CFI needs to be
// emitted per cluster. This also bloats the object file and binary sizes.
//
-// Basic Block Labels
+// Basic Block Address Map
// ==================
//
-// With -fbasic-block-sections=labels, we encode the offsets of BB addresses of
+// With -fbasic-block-address-map, we emit the offsets of BB addresses of
// every function into the .llvm_bb_addr_map section. Along with the function
// symbols, this allows for mapping of virtual addresses in PMU profiles back to
// the corresponding basic blocks. This logic is implemented in AsmPrinter. This
@@ -118,6 +118,10 @@ public:
/// Identify basic blocks that need separate sections and prepare to emit them
/// accordingly.
bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+ bool handleBBSections(MachineFunction &MF);
+ bool handleBBAddrMap(MachineFunction &MF);
};
} // end anonymous namespace
@@ -280,10 +284,12 @@ bool llvm::hasInstrProfHashMismatch(MachineFunction &MF) {
return false;
}
-bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
+// Identify, arrange, and modify basic blocks which need separate sections
+// according to the specification provided by the -fbasic-block-sections flag.
+bool BasicBlockSections::handleBBSections(MachineFunction &MF) {
auto BBSectionsType = MF.getTarget().getBBSectionsType();
- assert(BBSectionsType != BasicBlockSection::None &&
- "BB Sections not enabled!");
+ if (BBSectionsType == BasicBlockSection::None)
+ return false;
// Check for source drift. If the source has changed since the profiles
// were obtained, optimizing basic blocks might be sub-optimal.
@@ -300,7 +306,7 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
if (BBSectionsType == BasicBlockSection::Labels) {
MF.setBBSectionsType(BBSectionsType);
- return false;
+ return true;
}
DenseMap<UniqueBBID, BBClusterInfo> FuncClusterInfo;
@@ -364,6 +370,27 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
return true;
}
+// When the BB address map needs to be generated, this renumbers basic blocks to
+// make them appear in increasing order of their IDs in the function. This
+// avoids the need to store basic block IDs in the BB address map section, since
+// they can be determined implicitly.
+bool BasicBlockSections::handleBBAddrMap(MachineFunction &MF) {
+ if (MF.getTarget().getBBSectionsType() == BasicBlockSection::Labels)
+ return false;
+ if (!MF.getTarget().Options.BBAddrMap)
+ return false;
+ MF.RenumberBlocks();
+ return true;
+}
+
+bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
+ // First handle the basic block sections.
+ auto R1 = handleBBSections(MF);
+ // Handle basic block address map after basic block sections are finalized.
+ auto R2 = handleBBAddrMap(MF);
+ return R1 || R2;
+}
+
void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<BasicBlockSectionsProfileReaderWrapperPass>();
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 51406fb..d82b2a8 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -90,6 +90,7 @@ CGOPT_EXP(bool, DataSections)
CGOPT_EXP(bool, FunctionSections)
CGOPT(bool, IgnoreXCOFFVisibility)
CGOPT(bool, XCOFFTracebackTable)
+CGOPT(bool, EnableBBAddrMap)
CGOPT(std::string, BBSections)
CGOPT(unsigned, TLSSize)
CGOPT_EXP(bool, EmulatedTLS)
@@ -390,6 +391,11 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(true));
CGBINDOPT(XCOFFTracebackTable);
+ static cl::opt<bool> EnableBBAddrMap(
+ "basic-block-address-map",
+ cl::desc("Emit the basic block address map section"), cl::init(false));
+ CGBINDOPT(EnableBBAddrMap);
+
static cl::opt<std::string> BBSections(
"basic-block-sections",
cl::desc("Emit basic blocks into separate sections"),
@@ -568,6 +574,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
Options.FunctionSections = getFunctionSections();
Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
Options.XCOFFTracebackTable = getXCOFFTracebackTable();
+ Options.BBAddrMap = getEnableBBAddrMap();
Options.BBSections = getBBSectionsMode(Options);
Options.UniqueSectionNames = getUniqueSectionNames();
Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 57af571..323f1a6 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -467,6 +467,7 @@ MachineFunction::CreateMachineBasicBlock(const BasicBlock *BB,
// `-basic-block-sections=list` to allow robust mapping of profiles to basic
// blocks.
if (Target.getBBSectionsType() == BasicBlockSection::Labels ||
+ Target.Options.BBAddrMap ||
Target.getBBSectionsType() == BasicBlockSection::List)
MBB->setBBID(BBID.has_value() ? *BBID : UniqueBBID{NextBBID++, 0});
return MBB;
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 599ca48..e82f14e 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -1221,19 +1221,13 @@ void TargetPassConfig::addMachinePasses() {
addPass(createMIRAddFSDiscriminatorsPass(
sampleprof::FSDiscriminatorPass::PassLast));
+ bool NeedsBBSections =
+ TM->getBBSectionsType() != llvm::BasicBlockSection::None;
// Machine function splitter uses the basic block sections feature. Both
- // cannot be enabled at the same time. Basic block sections takes precedence.
- // FIXME: In principle, BasicBlockSection::Labels and splitting can used
- // together. Update this check once we have addressed any issues.
- if (TM->getBBSectionsType() != llvm::BasicBlockSection::None) {
- if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) {
- addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass(
- TM->getBBSectionsFuncListBuf()));
- addPass(llvm::createBasicBlockPathCloningPass());
- }
- addPass(llvm::createBasicBlockSectionsPass());
- } else if (TM->Options.EnableMachineFunctionSplitter ||
- EnableMachineFunctionSplitter) {
+ // cannot be enabled at the same time. We do not apply machine function
+ // splitter if -basic-block-sections is requested.
+ if (!NeedsBBSections && (TM->Options.EnableMachineFunctionSplitter ||
+ EnableMachineFunctionSplitter)) {
const std::string ProfileFile = getFSProfileFile(TM);
if (!ProfileFile.empty()) {
if (EnableFSDiscriminator) {
@@ -1250,6 +1244,16 @@ void TargetPassConfig::addMachinePasses() {
}
addPass(createMachineFunctionSplitterPass());
}
+ // We run the BasicBlockSections pass if either we need BB sections or BB
+ // address map (or both).
+ if (NeedsBBSections || TM->Options.BBAddrMap) {
+ if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) {
+ addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass(
+ TM->getBBSectionsFuncListBuf()));
+ addPass(llvm::createBasicBlockPathCloningPass());
+ }
+ addPass(llvm::createBasicBlockSectionsPass());
+ }
addPostBBSections();
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index f24395b..137f606 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -693,6 +693,17 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
}
+ auto GetAddressForRelocation =
+ [&](unsigned RelocationOffsetInSection) -> Expected<unsigned> {
+ auto FOTIterator =
+ FunctionOffsetTranslations.find(RelocationOffsetInSection);
+ if (FOTIterator == FunctionOffsetTranslations.end()) {
+ return createError("failed to get relocation data for offset: " +
+ Twine::utohexstr(RelocationOffsetInSection) +
+ " in section " + describe(EF, Sec));
+ }
+ return FOTIterator->second;
+ };
Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);
if (!ContentsOrErr)
return ContentsOrErr.takeError();
@@ -704,9 +715,26 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Error ULEBSizeErr = Error::success();
Error MetadataDecodeErr = Error::success();
+ // Helper lampda to extract the (possiblly relocatable) address stored at Cur.
+ auto ExtractAddress = [&]() -> Expected<typename ELFFile<ELFT>::uintX_t> {
+ uint64_t RelocationOffsetInSection = Cur.tell();
+ auto Address =
+ static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));
+ if (!Cur)
+ return Cur.takeError();
+ if (!IsRelocatable)
+ return Address;
+ assert(Address == 0);
+ Expected<unsigned> AddressOrErr =
+ GetAddressForRelocation(RelocationOffsetInSection);
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ return *AddressOrErr;
+ };
+
uint8_t Version = 0;
uint8_t Feature = 0;
- PGOAnalysisMap::Features FeatEnable{};
+ BBAddrMap::Features FeatEnable{};
while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
Cur.tell() < Content.size()) {
if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
@@ -719,11 +747,10 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Feature = Data.getU8(Cur); // Feature byte
if (!Cur)
break;
- auto FeatEnableOrErr = PGOAnalysisMap::Features::decode(Feature);
+ auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
if (!FeatEnableOrErr)
return FeatEnableOrErr.takeError();
- FeatEnable =
- FeatEnableOrErr ? *FeatEnableOrErr : PGOAnalysisMap::Features{};
+ FeatEnable = *FeatEnableOrErr;
if (Feature != 0 && Version < 2 && Cur)
return createError(
"version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when "
@@ -731,50 +758,65 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
Twine(static_cast<int>(Version)) +
" feature = " + Twine(static_cast<int>(Feature)));
}
- uint64_t SectionOffset = Cur.tell();
- auto Address =
- static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));
- if (!Cur)
- return Cur.takeError();
- if (IsRelocatable) {
- assert(Address == 0);
- auto FOTIterator = FunctionOffsetTranslations.find(SectionOffset);
- if (FOTIterator == FunctionOffsetTranslations.end()) {
- return createError("failed to get relocation data for offset: " +
- Twine::utohexstr(SectionOffset) + " in section " +
- describe(EF, Sec));
- }
- Address = FOTIterator->second;
- }
- uint32_t NumBlocks = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
-
+ uint32_t NumBlocksInBBRange = 0;
+ uint32_t NumBBRanges = 1;
+ typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0;
std::vector<BBAddrMap::BBEntry> BBEntries;
- uint32_t PrevBBEndOffset = 0;
- for (uint32_t BlockIndex = 0;
- !MetadataDecodeErr && !ULEBSizeErr && Cur && (BlockIndex < NumBlocks);
- ++BlockIndex) {
- uint32_t ID = Version >= 2
- ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
- : BlockIndex;
- uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
- if (Version >= 1) {
- // Offset is calculated relative to the end of the previous BB.
- Offset += PrevBBEndOffset;
- PrevBBEndOffset = Offset + Size;
- }
- Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
- BBAddrMap::BBEntry::Metadata::decode(MD);
- if (!MetadataOrErr) {
- MetadataDecodeErr = MetadataOrErr.takeError();
+ if (FeatEnable.MultiBBRange) {
+ NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ if (!Cur || ULEBSizeErr)
break;
+ if (!NumBBRanges)
+ return createError("invalid zero number of BB ranges at offset " +
+ Twine::utohexstr(Cur.tell()) + " in " +
+ describe(EF, Sec));
+ } else {
+ auto AddressOrErr = ExtractAddress();
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ RangeBaseAddress = *AddressOrErr;
+ NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ }
+ std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries;
+ uint32_t TotalNumBlocks = 0;
+ for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges;
+ ++BBRangeIndex) {
+ uint32_t PrevBBEndOffset = 0;
+ if (FeatEnable.MultiBBRange) {
+ auto AddressOrErr = ExtractAddress();
+ if (!AddressOrErr)
+ return AddressOrErr.takeError();
+ RangeBaseAddress = *AddressOrErr;
+ NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ }
+ for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr && Cur &&
+ (BlockIndex < NumBlocksInBBRange);
+ ++BlockIndex) {
+ uint32_t ID = Version >= 2
+ ? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
+ : BlockIndex;
+ uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ if (Version >= 1) {
+ // Offset is calculated relative to the end of the previous BB.
+ Offset += PrevBBEndOffset;
+ PrevBBEndOffset = Offset + Size;
+ }
+ Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
+ BBAddrMap::BBEntry::Metadata::decode(MD);
+ if (!MetadataOrErr) {
+ MetadataDecodeErr = MetadataOrErr.takeError();
+ break;
+ }
+ BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
}
- BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
+ TotalNumBlocks += BBEntries.size();
+ BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});
}
- FunctionEntries.emplace_back(Address, std::move(BBEntries));
+ FunctionEntries.push_back({std::move(BBRangeEntries)});
- if (PGOAnalyses || FeatEnable.anyEnabled()) {
+ if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {
// Function entry count
uint64_t FuncEntryCount =
FeatEnable.FuncEntryCount
@@ -783,8 +825,8 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;
for (uint32_t BlockIndex = 0;
- (FeatEnable.BBFreq || FeatEnable.BrProb) && !MetadataDecodeErr &&
- !ULEBSizeErr && Cur && (BlockIndex < NumBlocks);
+ FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&
+ !ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);
++BlockIndex) {
// Block frequency
uint64_t BBF = FeatEnable.BBFreq
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index b044d50..58a725f 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1419,24 +1419,43 @@ void ELFState<ELFT>::writeSectionContent(
CBA.write(E.Feature);
SHeader.sh_size += 2;
}
-
- if (Section.PGOAnalyses) {
- if (E.Version < 2)
- WithColor::warning()
- << "unsupported SHT_LLVM_BB_ADDR_MAP version when using PGO: "
- << static_cast<int>(E.Version) << "; must use version >= 2";
+ auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
+ bool MultiBBRangeFeatureEnabled = false;
+ if (!FeatureOrErr)
+ WithColor::warning() << toString(FeatureOrErr.takeError());
+ else
+ MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
+ bool MultiBBRange =
+ MultiBBRangeFeatureEnabled ||
+ (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||
+ (E.BBRanges && E.BBRanges->size() != 1);
+ if (MultiBBRange && !MultiBBRangeFeatureEnabled)
+ WithColor::warning() << "feature value(" << E.Feature
+ << ") does not support multiple BB ranges.";
+ if (MultiBBRange) {
+ // Write the number of basic block ranges, which is overridden by the
+ // 'NumBBRanges' field when specified.
+ uint64_t NumBBRanges =
+ E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);
+ SHeader.sh_size += CBA.writeULEB128(NumBBRanges);
}
-
- // Write the address of the function.
- CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness);
- // Write number of BBEntries (number of basic blocks in the function). This
- // is overridden by the 'NumBlocks' YAML field when specified.
- uint64_t NumBlocks =
- E.NumBlocks.value_or(E.BBEntries ? E.BBEntries->size() : 0);
- SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
- // Write all BBEntries.
- if (E.BBEntries) {
- for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *E.BBEntries) {
+ if (!E.BBRanges)
+ continue;
+ uint64_t TotalNumBlocks = 0;
+ for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
+ // Write the base address of the range.
+ CBA.write<uintX_t>(BBR.BaseAddress, ELFT::TargetEndianness);
+ // Write number of BBEntries (number of basic blocks in this basic block
+ // range). This is overridden by the 'NumBlocks' YAML field when
+ // specified.
+ uint64_t NumBlocks =
+ BBR.NumBlocks.value_or(BBR.BBEntries ? BBR.BBEntries->size() : 0);
+ SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
+ // Write all BBEntries in this BBRange.
+ if (!BBR.BBEntries)
+ continue;
+ for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) {
+ ++TotalNumBlocks;
if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1)
SHeader.sh_size += CBA.writeULEB128(BBE.ID);
SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);
@@ -1444,7 +1463,6 @@ void ELFState<ELFT>::writeSectionContent(
SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);
}
}
-
if (!PGOAnalyses)
continue;
const ELFYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);
@@ -1456,11 +1474,11 @@ void ELFState<ELFT>::writeSectionContent(
continue;
const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();
- if (!E.BBEntries || E.BBEntries->size() != PGOBBEntries.size()) {
+ if (TotalNumBlocks != PGOBBEntries.size()) {
WithColor::warning() << "PBOBBEntries must be the same length as "
"BBEntries in SHT_LLVM_BB_ADDR_MAP.\n"
<< "Mismatch on function with address: "
- << E.Address;
+ << E.getFunctionAddress();
continue;
}
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 6ad4a06..31e90fe 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1680,7 +1680,6 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
Section.reset(new ELFYAML::CallGraphProfileSection());
sectionMapping(IO, *cast<ELFYAML::CallGraphProfileSection>(Section.get()));
break;
- case ELF::SHT_LLVM_BB_ADDR_MAP_V0:
case ELF::SHT_LLVM_BB_ADDR_MAP:
if (!IO.outputting())
Section.reset(new ELFYAML::BBAddrMapSection());
@@ -1812,7 +1811,13 @@ void MappingTraits<ELFYAML::BBAddrMapEntry>::mapping(
assert(IO.getContext() && "The IO context is not initialized");
IO.mapRequired("Version", E.Version);
IO.mapOptional("Feature", E.Feature, Hex8(0));
- IO.mapOptional("Address", E.Address, Hex64(0));
+ IO.mapOptional("NumBBRanges", E.NumBBRanges);
+ IO.mapOptional("BBRanges", E.BBRanges);
+}
+
+void MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry>::mapping(
+ IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E) {
+ IO.mapOptional("BaseAddress", E.BaseAddress, Hex64(0));
IO.mapOptional("NumBlocks", E.NumBlocks);
IO.mapOptional("BBEntries", E.BBEntries);
}
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
index 3be3ab7..d767860 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=labels | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-address-map | FileCheck %s
$_Z4fooTIiET_v = comdat any
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
new file mode 100644
index 0000000..6354e2e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
@@ -0,0 +1,71 @@
+;; Check that the -basic-block-address-map option works when used along with -basic-block-sections.
+;; Let a function with 4 basic blocks get split into 2 sections.
+; RUN: echo '!_Z3bazb' > %t
+; RUN: echo '!!0 2' >> %t
+; RUN: llc < %s -mtriple=x86_64 -basic-block-address-map -basic-block-sections=%t | FileCheck %s
+
+define void @_Z3bazb(i1 zeroext) personality i32 (...)* @__gxx_personality_v0 {
+ br i1 %0, label %2, label %7
+
+2:
+ %3 = invoke i32 @_Z3barv()
+ to label %7 unwind label %5
+ br label %9
+
+5:
+ landingpad { i8*, i32 }
+ catch i8* null
+ br label %9
+
+7:
+ %8 = call i32 @_Z3foov()
+ br label %9
+
+9:
+ ret void
+}
+
+declare i32 @_Z3barv() #1
+
+declare i32 @_Z3foov() #1
+
+declare i32 @__gxx_personality_v0(...)
+
+; CHECK: .text
+; CHECK-LABEL: _Z3bazb:
+; CHECK-LABEL: .Lfunc_begin0:
+; CHECK-LABEL: .LBB_END0_0:
+; CHECK-LABEL: .LBB0_1:
+; CHECK-LABEL: .LBB_END0_1:
+; CHECK: .section .text.split._Z3bazb,"ax",@progbits
+; CHECK-LABEL: _Z3bazb.cold:
+; CHECK-LABEL: .LBB_END0_2:
+; CHECK-LABEL: .LBB0_3:
+; CHECK-LABEL: .LBB_END0_3:
+; CHECK-LABEL: .Lfunc_end0:
+
+; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text.hot._Z3bazb
+; CHECK-NEXT: .byte 2 # version
+; CHECK-NEXT: .byte 8 # feature
+; CHECK-NEXT: .byte 2 # number of basic block ranges
+; CHECK-NEXT: .quad .Lfunc_begin0 # base address
+; CHECK-NEXT: .byte 2 # number of basic blocks
+; CHECK-NEXT: .byte 0 # BB id
+; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0
+; CHECK-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 2 # BB id
+; CHECK-NEXT: .uleb128 .LBB0_1-.LBB_END0_0
+; CHECK-NEXT: .uleb128 .LBB_END0_1-.LBB0_1
+; CHECK-NEXT: .byte 5
+; CHECK-NEXT: .quad _Z3bazb.cold # base address
+; CHECK-NEXT: .byte 2 # number of basic blocks
+; CHECK-NEXT: .byte 1 # BB id
+; CHECK-NEXT: .uleb128 _Z3bazb.cold-_Z3bazb.cold
+; CHECK-NEXT: .uleb128 .LBB_END0_2-_Z3bazb.cold
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 3 # BB id
+; CHECK-NEXT: .uleb128 .LBB0_3-.LBB_END0_2
+; CHECK-NEXT: .uleb128 .LBB_END0_3-.LBB0_3
+; CHECK-NEXT: .byte 1
+
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
new file mode 100644
index 0000000..2565db23
--- /dev/null
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
@@ -0,0 +1,89 @@
+; COM: Emitting basic-block-address-map when machine function splitting is enabled.
+; RUN: llc < %s -mtriple=x86_64 -function-sections -split-machine-functions -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,BASIC
+
+; COM: Emitting basic-block-address-map with PGO analysis with machine function splitting enabled.
+; RUN: llc < %s -mtriple=x86_64 -function-sections -split-machine-functions -basic-block-address-map -pgo-analysis-map=func-entry-count,bb-freq,br-prob | FileCheck %s --check-prefixes=CHECK,PGO
+
+define void @foo(i1 zeroext %0) nounwind !prof !14 {
+ br i1 %0, label %2, label %4, !prof !15
+
+2: ; preds = %1
+ %3 = call i32 @bar()
+ br label %6
+
+4: ; preds = %1
+ %5 = call i32 @baz()
+ br label %6
+
+6: ; preds = %4, %2
+ %7 = tail call i32 @qux()
+ ret void
+}
+
+declare i32 @bar()
+declare i32 @baz()
+declare i32 @qux()
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"ProfileSummary", !1}
+!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
+!2 = !{!"ProfileFormat", !"InstrProf"}
+!3 = !{!"TotalCount", i64 10000}
+!4 = !{!"MaxCount", i64 10}
+!5 = !{!"MaxInternalCount", i64 1}
+!6 = !{!"MaxFunctionCount", i64 1000}
+!7 = !{!"NumCounts", i64 3}
+!8 = !{!"NumFunctions", i64 5}
+!9 = !{!"DetailedSummary", !10}
+!10 = !{!11, !12, !13}
+!11 = !{i32 10000, i64 100, i32 1}
+!12 = !{i32 999900, i64 100, i32 1}
+!13 = !{i32 999999, i64 1, i32 2}
+!14 = !{!"function_entry_count", i64 7000}
+!15 = !{!"branch_weights", i32 7000, i32 0}
+
+; CHECK: .section .text.hot.foo,"ax",@progbits
+; CHECK-LABEL: foo:
+; CHECK-LABEL: .Lfunc_begin0:
+; CHECK-LABEL: .LBB_END0_0:
+; CHECK-LABEL: .LBB0_1:
+; CHECK-LABEL: .LBB_END0_1:
+; CHECK: .section .text.split.foo,"ax",@progbits
+; CHECK-LABEL: foo.cold:
+; CHECK-LABEL: .LBB_END0_2:
+; CHECK-LABEL: .Lfunc_end0:
+
+; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text.hot.foo
+; CHECK-NEXT: .byte 2 # version
+; BASIC-NEXT: .byte 8 # feature
+; PGO-NEXT: .byte 15 # feature
+; CHECK-NEXT: .byte 2 # number of basic block ranges
+; CHECK-NEXT: .quad .Lfunc_begin0 # base address
+; CHECK-NEXT: .byte 2 # number of basic blocks
+; CHECK-NEXT: .byte 0 # BB id
+; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0
+; CHECK-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 1 # BB id
+; CHECK-NEXT: .uleb128 .LBB0_1-.LBB_END0_0
+; CHECK-NEXT: .uleb128 .LBB_END0_1-.LBB0_1
+; CHECK-NEXT: .byte 3
+; CHECK-NEXT: .quad foo.cold # base address
+; CHECK-NEXT: .byte 1 # number of basic blocks
+; CHECK-NEXT: .byte 2 # BB id
+; CHECK-NEXT: .uleb128 foo.cold-foo.cold
+; CHECK-NEXT: .uleb128 .LBB_END0_2-foo.cold
+; CHECK-NEXT: .byte 3
+
+;; PGO Analysis Map
+; PGO: .ascii "\3306" # function entry count
+; PGO-NEXT: .ascii "\200\200\200\200\200\200\200 " # basic block frequency
+; PGO-NEXT: .byte 2 # basic block successor count
+; PGO-NEXT: .byte 1 # successor BB ID
+; PGO-NEXT: .ascii "\200\200\200\200\b" # successor branch probability
+; PGO-NEXT: .byte 2 # successor BB ID
+; PGO-NEXT: .byte 0 # successor branch probability
+; PGO-NEXT: .ascii "\200\200\200\374\377\377\377\037" # basic block frequency
+; PGO-NEXT: .byte 0 # basic block successor count
+; PGO-NEXT: .ascii "\200\200\200\004" # basic block frequency
+; PGO-NEXT: .byte 0 # basic block successor count
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll b/llvm/test/CodeGen/X86/basic-block-address-map.ll
index 0b0b00a..6ab24b4 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map.ll
@@ -1,5 +1,7 @@
; Check the basic block sections labels option
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,UNIQ
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-sections=labels | FileCheck %s --check-prefixes=CHECK,UNIQ
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=false -basic-block-address-map | FileCheck %s --check-prefixes=CHECK,NOUNIQ
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=false -basic-block-sections=labels | FileCheck %s --check-prefixes=CHECK,NOUNIQ
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-sections=labels -split-machine-functions | FileCheck %s --check-prefixes=CHECK,UNIQ
diff --git a/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-disassemble-symbolize-operands.yaml b/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-disassemble-symbolize-operands.yaml
index 6864932..cc7faea 100644
--- a/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-disassemble-symbolize-operands.yaml
+++ b/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-disassemble-symbolize-operands.yaml
@@ -1,30 +1,32 @@
## Test that in the presence of SHT_LLVM_BB_ADDR_MAP sections,
## --symbolize-operands can display <BB*> labels.
-## Executable object file.
-# RUN: yaml2obj --docnum=1 -DFOO_ADDR=0x4000 -DBAR_ADDR=0x5000 %s -o %t1
-# RUN: llvm-objdump %t1 -d --symbolize-operands -M intel --no-show-raw-insn --no-leading-addr | \
-# RUN: FileCheck %s -DSYM=symbol --match-full-lines --check-prefixes=INTEL
-# RUN: llvm-objdump %t1 -d --symbolize-operands -M att --no-show-raw-insn --no-leading-addr | \
-# RUN: FileCheck %s -DSYM=symbol --match-full-lines --check-prefixes=ATT
+## Executable object file with separate SHT_LLVM_BB_ADDR_MAP sections for multiple text sections.
+## RUN: yaml2obj --docnum=1 %s -o %t1
+## RUN: llvm-objdump %t1 -d --symbolize-operands -M intel --no-show-raw-insn --no-leading-addr | \
+## RUN: FileCheck %s --match-full-lines --check-prefixes=INTEL
+## RUN: llvm-objdump %t1 -d --symbolize-operands -M att --no-show-raw-insn --no-leading-addr | \
+## RUN: FileCheck %s --match-full-lines --check-prefixes=ATT
## Executable object file with a single SHT_LLVM_BB_ADDR_MAP for multiple text sections.
-# RUN: yaml2obj --docnum=2 %s -o %t3
-# RUN: llvm-objdump %t3 -d --symbolize-operands -M intel --no-show-raw-insn --no-leading-addr | \
-# RUN: FileCheck %s -DSYM=symbol --match-full-lines --check-prefixes=INTEL
-# RUN: llvm-objdump %t3 -d --symbolize-operands -M att --no-show-raw-insn --no-leading-addr | \
-# RUN: FileCheck %s -DSYM=symbol --match-full-lines --check-prefixes=ATT
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: llvm-objdump %t2 -d --symbolize-operands -M intel --no-show-raw-insn --no-leading-addr | \
+# RUN: FileCheck %s --match-full-lines --check-prefixes=INTEL
+# RUN: llvm-objdump %t2 -d --symbolize-operands -M att --no-show-raw-insn --no-leading-addr | \
+# RUN: FileCheck %s --match-full-lines --check-prefixes=ATT
## Expect to find the branch and basic block labels and global variable name.
# ATT: <foo>:
# ATT-NEXT: <BB3>:
# ATT-NEXT: pushq %rax
# ATT-NEXT: <BB1>:
-# ATT-NEXT: cmpl , %eax <[[SYM]]>
+# ATT-NEXT: cmpl , %eax <symbol>
# ATT-NEXT: nop
# ATT-NEXT: <BB2>:
# ATT-NEXT: jge <BB5>
# ATT-NEXT: jmp <BB1>
+# ATT-NEXT: <BB4>:
+# ATT-NEXT: jge <foo.cold>
# ATT-NEXT: <BB5>:
# ATT-NEXT: retq
# ATT: <bar>:
@@ -37,16 +39,21 @@
# ATT-NEXT: <BB2>:
# ATT-NEXT: callq <bar>
# ATT-NEXT: retq
+# ATT: <foo.cold>:
+# ATT-NEXT: <BB6>:
+# ATT-NEXT: retq
# INTEL: <foo>:
# INTEL-NEXT: <BB3>:
# INTEL-NEXT: push rax
# INTEL-NEXT: <BB1>:
-# INTEL-NEXT: cmp eax, dword ptr <[[SYM]]>
+# INTEL-NEXT: cmp eax, dword ptr <symbol>
# INTEL-NEXT: nop
# INTEL-NEXT: <BB2>:
# INTEL-NEXT: jge <BB5>
# INTEL-NEXT: jmp <BB1>
+# INTEL-NEXT: <BB4>:
+# INTEL-NEXT: jge <foo.cold>
# INTEL-NEXT: <BB5>:
# INTEL-NEXT: ret
# INTEL: <bar>:
@@ -59,6 +66,9 @@
# INTEL-NEXT: <BB2>:
# INTEL-NEXT: call <bar>
# INTEL-NEXT: ret
+# INTEL: <foo.cold>:
+# INTEL-NEXT: <BB6>:
+# INTEL-NEXT: ret
## This object file contains a separate text section and SHT_LLVM_BB_ADDR_MAP
## section for each of the two functions foo and bar.
@@ -73,68 +83,89 @@ FileHeader:
Sections:
- Name: .text.foo
Type: SHT_PROGBITS
- Address: [[FOO_ADDR]]
+ Address: 0x4000
Flags: [SHF_ALLOC, SHF_EXECINSTR]
- Content: '503b0505200000907d02ebf5c3'
+ Content: '503b0505300000907d08ebf50f8dee1f0000c3'
- Name: .text.bar
Type: SHT_PROGBITS
- Address: [[BAR_ADDR]]
+ Address: 0x5000
Flags: [SHF_ALLOC, SHF_EXECINSTR]
Content: '5089d0740231f6e8f4ffffffc3'
+ - Name: .text.split
+ Type: SHT_PROGBITS
+ Address: 0x6000
+ Flags: [SHF_ALLOC, SHF_EXECINSTR]
+ Content: 'c3'
- Name: .data
Type: SHT_PROGBITS
Flags: [SHF_ALLOC, SHF_WRITE]
- Address: 0x6000
+ Address: 0x7000
- Name: .llvm_bb_addr_map.foo
Type: SHT_LLVM_BB_ADDR_MAP
Link: .text.foo
Entries:
- Version: 2
- Address: [[FOO_ADDR]]
- BBEntries:
- - ID: 3
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
- - ID: 1
- AddressOffset: 0x0
- Size: 0x6
- Metadata: 0x0
- - ID: 2
- AddressOffset: 0x1
- Size: 0x4
- Metadata: 0x0
- - ID: 5
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ Feature: 0x8
+ BBRanges:
+ - BaseAddress: 0x4000
+ BBEntries:
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
+ - ID: 2
+ AddressOffset: 0x1
+ Size: 0x4
+ Metadata: 0x0
+ - ID: 4
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x1
+ - ID: 5
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
+ - BaseAddress: 0x6000
+ BBEntries:
+ - ID: 6
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
- Name: .llvm_bb_addr_map.bar
Type: SHT_LLVM_BB_ADDR_MAP
Link: .text.bar
Entries:
- Version: 1
- Address: [[BAR_ADDR]]
- BBEntries:
- - AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
- - AddressOffset: 0x4
- Size: 0x2
- Metadata: 0x0
- - AddressOffset: 0x0
- Size: 0x6
- Metadata: 0x0
+ BBRanges:
+ - BaseAddress: 0x5000
+ BBEntries:
+ - AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ - AddressOffset: 0x4
+ Size: 0x2
+ Metadata: 0x0
+ - AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
Symbols:
- Name: foo
Section: .text.foo
- Value: [[FOO_ADDR]]
+ Value: 0x4000
+ - Name: foo.cold
+ Section: .text.split
+ Value: 0x6000
- Name: bar
Section: .text.bar
- Value: [[BAR_ADDR]]
+ Value: 0x5000
- Name: symbol
Section: .data
- Value: 0x600c
+ Value: 0x700c
## This object file contains a single SHT_LLVM_BB_ADDR_MAP for two text
## sections .text.foo and .text.bar.
@@ -149,59 +180,80 @@ Sections:
Type: SHT_PROGBITS
Address: 0x4000
Flags: [SHF_ALLOC, SHF_EXECINSTR]
- Content: '503b0505200000907d02ebf5c3'
+ Content: '503b0505300000907d08ebf50f8dee1f0000c3'
- Name: .text.bar
Type: SHT_PROGBITS
Address: 0x5000
Flags: [SHF_ALLOC, SHF_EXECINSTR]
Content: '5089d0740231f6e8f4ffffffc3'
+ - Name: .text.split
+ Type: SHT_PROGBITS
+ Address: 0x6000
+ Flags: [SHF_ALLOC, SHF_EXECINSTR]
+ Content: 'c3'
- Name: .data
Type: SHT_PROGBITS
Flags: [SHF_ALLOC, SHF_WRITE]
- Address: 0x6000
+ Address: 0x7000
- Name: .llvm_bb_addr_map.foo
Type: SHT_LLVM_BB_ADDR_MAP
Link: .text.foo
Entries:
- Version: 2
- Address: 0x4000
- BBEntries:
- - ID: 3
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
- - ID: 1
- AddressOffset: 0x0
- Size: 0x6
- Metadata: 0x0
- - ID: 2
- AddressOffset: 0x1
- Size: 0x4
- Metadata: 0x0
- - ID: 5
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ Feature: 0x8
+ BBRanges:
+ - BaseAddress: 0x4000
+ BBEntries:
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
+ - ID: 2
+ AddressOffset: 0x1
+ Size: 0x4
+ Metadata: 0x0
+ - ID: 4
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x1
+ - ID: 5
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
+ - BaseAddress: 0x6000
+ BBEntries:
+ - ID: 6
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
- Version: 1
- Address: 0x5000
- BBEntries:
- - AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
- - AddressOffset: 0x4
- Size: 0x2
- Metadata: 0x0
- - AddressOffset: 0x0
- Size: 0x6
- Metadata: 0x0
+ BBRanges:
+ - BaseAddress: 0x5000
+ BBEntries:
+ - AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ - AddressOffset: 0x4
+ Size: 0x2
+ Metadata: 0x0
+ - AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
Symbols:
- Name: foo
Section: .text.foo
Value: 0x4000
+ - Name: foo.cold
+ Section: .text.split
+ Value: 0x6000
- Name: bar
Section: .text.bar
Value: 0x5000
- Name: symbol
Section: .data
- Value: 0x600c
+ Value: 0x700c
diff --git a/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-symbolize-relocatable.yaml b/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-symbolize-relocatable.yaml
index f796963..706d386 100644
--- a/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-symbolize-relocatable.yaml
+++ b/llvm/test/tools/llvm-objdump/X86/elf-bbaddrmap-symbolize-relocatable.yaml
@@ -24,17 +24,32 @@ Sections:
Link: .text
Entries:
- Version: 2
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
+ BBRanges:
+ - BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0xa
- Version: 2
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
+ BBRanges:
+ - BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0xb
+ - Version: 2
+ Feature: 0x8
+ BBRanges:
+ - BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0xc
+ - BBEntries:
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0xd
- Name: .rela.llvm_bb_addr_map
Type: SHT_RELA
Flags: [ SHF_INFO_LINK ]
@@ -48,6 +63,15 @@ Sections:
Symbol: .text
Type: R_X86_64_64
Addend: 1
+ - Offset: 0x21
+ Symbol: .text
+ Type: R_X86_64_64
+ Addend: 0x2
+ - Offset: 0x2e
+ Symbol: .text
+ Type: R_X86_64_64
+ Addend: 0x3
+
Symbols:
- Name: a
Section: .text
@@ -55,6 +79,12 @@ Symbols:
- Name: c
Section: .text
Value: 0x1
+ - Name: h
+ Section: .text
+ Value: 0x2
+ - Name: h1
+ Section: .text
+ Value: 0x3
- Name: .text
Type: STT_SECTION
Section: .text
diff --git a/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml b/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
index c4bf443..732fab3 100644
--- a/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
+++ b/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
@@ -25,13 +25,14 @@ Sections:
Link: .text.foo
Entries:
- Version: 2
- Address: 0x0
Feature: 0x1
- BBEntries:
- - ID: 3
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
+ BBRanges:
+ - BaseAddress: 0x0
+ BBEntries:
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
PGOAnalyses:
- FuncEntryCount: 1000
Symbols:
@@ -65,25 +66,26 @@ Sections:
Link: .text.foo
Entries:
- Version: 2
- Address: 0x0
Feature: 0x3
- BBEntries:
- - ID: 3
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
- - ID: 1
- AddressOffset: 0x0
- Size: 0x6
- Metadata: 0x0
- - ID: 2
- AddressOffset: 0x1
- Size: 0x4
- Metadata: 0x0
- - ID: 5
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BaseAddress: 0x0
+ BBEntries:
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
+ - ID: 2
+ AddressOffset: 0x1
+ Size: 0x4
+ Metadata: 0x0
+ - ID: 5
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
PGOAnalyses:
- FuncEntryCount: 1000
PGOBBEntries:
@@ -126,25 +128,26 @@ Sections:
Link: .text.foo
Entries:
- Version: 2
- Address: 0x0
Feature: 0x7
- BBEntries:
- - ID: 3
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x1
- - ID: 1
- AddressOffset: 0x0
- Size: 0x6
- Metadata: 0x0
- - ID: 2
- AddressOffset: 0x1
- Size: 0x4
- Metadata: 0x0
- - ID: 5
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BaseAddress: 0x0
+ BBEntries:
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
+ - ID: 2
+ AddressOffset: 0x1
+ Size: 0x4
+ Metadata: 0x0
+ - ID: 5
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
PGOAnalyses:
- FuncEntryCount: 1000
PGOBBEntries:
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
index 91b3d7e..e5a9400 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
@@ -24,26 +24,31 @@
# CHECK-NEXT: At: [[ADDR]]
# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
# CHECK-NEXT: Name: <?>
-# CHECK-NEXT: BB entries [
+# CHECK-NEXT: BB Ranges [
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 0
-# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: Size: 0x1
-# CHECK-NEXT: HasReturn: No
-# CHECK-NEXT: HasTailCall: Yes
-# CHECK-NEXT: IsEHPad: No
-# CHECK-NEXT: CanFallThrough: No
-# CHECK-NEXT: HasIndirectBranch: No
-# CHECK-NEXT: }
-# CHECK-NEXT: {
-# CHECK-NEXT: ID: 2
-# CHECK-NEXT: Offset: 0x4
-# CHECK-NEXT: Size: 0x4
-# CHECK-NEXT: HasReturn: Yes
-# CHECK-NEXT: HasTailCall: No
-# CHECK-NEXT: IsEHPad: Yes
-# CHECK-NEXT: CanFallThrough: No
-# CHECK-NEXT: HasIndirectBranch: Yes
+# CHECK-NEXT: Base Address: [[ADDR]]
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 0
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: Size: 0x1
+# CHECK-NEXT: HasReturn: No
+# CHECK-NEXT: HasTailCall: Yes
+# CHECK-NEXT: IsEHPad: No
+# CHECK-NEXT: CanFallThrough: No
+# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: }
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 2
+# CHECK-NEXT: Offset: 0x4
+# CHECK-NEXT: Size: 0x4
+# CHECK-NEXT: HasReturn: Yes
+# CHECK-NEXT: HasTailCall: No
+# CHECK-NEXT: IsEHPad: Yes
+# CHECK-NEXT: CanFallThrough: No
+# CHECK-NEXT: HasIndirectBranch: Yes
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: PGO analyses {
@@ -69,16 +74,21 @@
# CHECK-NEXT: Function {
# CHECK-NEXT: At: 0x22222
# CHECK-NEXT: Name: foo
-# CHECK-NEXT: BB entries [
+# CHECK-NEXT: BB Ranges [
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 4
-# CHECK-NEXT: Offset: 0x6
-# CHECK-NEXT: Size: 0x7
-# CHECK-NEXT: HasReturn: No
-# CHECK-NEXT: HasTailCall: No
-# CHECK-NEXT: IsEHPad: No
-# CHECK-NEXT: CanFallThrough: Yes
-# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: Base Address: 0x22222
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 4
+# CHECK-NEXT: Offset: 0x6
+# CHECK-NEXT: Size: 0x7
+# CHECK-NEXT: HasReturn: No
+# CHECK-NEXT: HasTailCall: No
+# CHECK-NEXT: IsEHPad: No
+# CHECK-NEXT: CanFallThrough: Yes
+# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: PGO analyses {
@@ -102,26 +112,31 @@
# TRUNCATED-NEXT: Function {
# TRUNCATED-NEXT: At: 0x33333
# TRUNCATED-NEXT: Name: bar
-# TRUNCATED-NEXT: BB entries [
-# TRUNCATED-NEXT: {
-# TRUNCATED-NEXT: ID: 6
-# TRUNCATED-NEXT: Offset: 0x9
-# TRUNCATED-NEXT: Size: 0xA
-# TRUNCATED-NEXT: HasReturn: Yes
-# TRUNCATED-NEXT: HasTailCall: Yes
-# TRUNCATED-NEXT: IsEHPad: No
-# TRUNCATED-NEXT: CanFallThrough: Yes
-# TRUNCATED-NEXT: HasIndirectBranch: Yes
-# TRUNCATED-NEXT: }
+# TRUNCATED-NEXT: BB Ranges [
# TRUNCATED-NEXT: {
-# TRUNCATED-NEXT: ID: 7
-# TRUNCATED-NEXT: Offset: 0x1F
-# TRUNCATED-NEXT: Size: 0xD
-# TRUNCATED-NEXT: HasReturn: No
-# TRUNCATED-NEXT: HasTailCall: Yes
-# TRUNCATED-NEXT: IsEHPad: Yes
-# TRUNCATED-NEXT: CanFallThrough: Yes
-# TRUNCATED-NEXT: HasIndirectBranch: No
+# TRUNCATED-NEXT: Base Address: 0x33333
+# TRUNCATED-NEXT: BB Entries [
+# TRUNCATED-NEXT: {
+# TRUNCATED-NEXT: ID: 6
+# TRUNCATED-NEXT: Offset: 0x9
+# TRUNCATED-NEXT: Size: 0xA
+# TRUNCATED-NEXT: HasReturn: Yes
+# TRUNCATED-NEXT: HasTailCall: Yes
+# TRUNCATED-NEXT: IsEHPad: No
+# TRUNCATED-NEXT: CanFallThrough: Yes
+# TRUNCATED-NEXT: HasIndirectBranch: Yes
+# TRUNCATED-NEXT: }
+# TRUNCATED-NEXT: {
+# TRUNCATED-NEXT: ID: 7
+# TRUNCATED-NEXT: Offset: 0x1F
+# TRUNCATED-NEXT: Size: 0xD
+# TRUNCATED-NEXT: HasReturn: No
+# TRUNCATED-NEXT: HasTailCall: Yes
+# TRUNCATED-NEXT: IsEHPad: Yes
+# TRUNCATED-NEXT: CanFallThrough: Yes
+# TRUNCATED-NEXT: HasIndirectBranch: No
+# TRUNCATED-NEXT: }
+# TRUNCATED-NEXT: ]
# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: ]
# TRUNCATED-NEXT: PGO analyses {
@@ -151,24 +166,26 @@ Sections:
Entries:
- Version: 2
Feature: 0x7
- Address: [[ADDR=0x11111]]
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
- - ID: 2
- AddressOffset: 0x3
- Size: 0x4
- Metadata: 0x15
+ BBRanges:
+ - BaseAddress: [[ADDR=0x11111]]
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
+ - ID: 2
+ AddressOffset: 0x3
+ Size: 0x4
+ Metadata: 0x15
- Version: 2
Feature: 0x3
- Address: 0x22222
- BBEntries:
- - ID: 4
- AddressOffset: 0x6
- Size: 0x7
- Metadata: 0x8
+ BBRanges:
+ - BaseAddress: 0x22222
+ BBEntries:
+ - ID: 4
+ AddressOffset: 0x6
+ Size: 0x7
+ Metadata: 0x8
PGOAnalyses:
- FuncEntryCount: 100
PGOBBEntries:
@@ -190,16 +207,17 @@ Sections:
Entries:
- Version: 2
Feature: [[FEATURE=0x1]]
- Address: 0x33333
- BBEntries:
- - ID: 6
- AddressOffset: 0x9
- Size: 0xa
- Metadata: 0x1b
- - ID: 7
- AddressOffset: 0xc
- Size: 0xd
- Metadata: 0xe
+ BBRanges:
+ - BaseAddress: 0x33333
+ BBEntries:
+ - ID: 6
+ AddressOffset: 0x9
+ Size: 0xa
+ Metadata: 0x1b
+ - ID: 7
+ AddressOffset: 0xc
+ Size: 0xd
+ Metadata: 0xe
PGOAnalyses:
- FuncEntryCount: 89
Symbols:
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
index e6b6cc3..e7f7849 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-relocatable.test
@@ -8,32 +8,42 @@
# CHECK-NEXT: Function {
# CHECK-NEXT: At: 0x0
# CHECK-NEXT: Name: <?>
-# CHECK-NEXT: BB entries [
+# CHECK-NEXT: BB Ranges [
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 0
-# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: Size: 0xF
-# CHECK-NEXT: HasReturn: Yes
-# CHECK-NEXT: HasTailCall: No
-# CHECK-NEXT: IsEHPad: No
-# CHECK-NEXT: CanFallThrough: No
-# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: Base Address: 0x0
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 0
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: Size: 0xF
+# CHECK-NEXT: HasReturn: Yes
+# CHECK-NEXT: HasTailCall: No
+# CHECK-NEXT: IsEHPad: No
+# CHECK-NEXT: CanFallThrough: No
+# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: Function {
# CHECK-NEXT: At: 0x10
# CHECK-NEXT: Name: <?>
-# CHECK-NEXT: BB entries [
+# CHECK-NEXT: BB Ranges [
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 0
-# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: Size: 0x11
-# CHECK-NEXT: HasReturn: No
-# CHECK-NEXT: HasTailCall: No
-# CHECK-NEXT: IsEHPad: No
-# CHECK-NEXT: CanFallThrough: Yes
-# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: Base Address: 0x10
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 0
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: Size: 0x11
+# CHECK-NEXT: HasReturn: No
+# CHECK-NEXT: HasTailCall: No
+# CHECK-NEXT: IsEHPad: No
+# CHECK-NEXT: CanFallThrough: Yes
+# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
@@ -54,17 +64,19 @@ Sections:
Link: .text
Entries:
- Version: 2
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0xF
- Metadata: 0x1
+ BBRanges:
+ - BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0xF
+ Metadata: 0x1
- Version: 2
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x11
- Metadata: 0x8
+ BBRanges:
+ - BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x11
+ Metadata: 0x8
- Name: .rela.llvm_bb_addr_map
Type: SHT_RELA
Flags: [ SHF_INFO_LINK ]
@@ -128,7 +140,8 @@ Sections:
Link: .text
Entries:
- Version: 2
- BBEntries:
+ BBRanges:
+ - BBEntries:
- ID: 0
AddressOffset: 0x0
Size: 0xF
@@ -181,12 +194,13 @@ Sections:
Flags: [ SHF_LINK_ORDER ]
Entries:
- Version: 2
- Address: 0xF
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0xF
- Metadata: 0x1
+ BBRanges:
+ - BaseAddress: 0xF
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0xF
+ Metadata: 0x1
# RUN: yaml2obj %s --docnum=5 -o %t5.o
# RUN: llvm-readobj %t5.o --bb-addr-map 2>&1 | FileCheck %s --check-prefix=ET-DYN-NO-WARNING -DFILE=%t5.o
@@ -195,16 +209,21 @@ Sections:
# ET-DYN-NO-WARNING: Function {
# ET-DYN-NO-WARNING: At: 0xF
# ET-DYN-NO-WARNING: Name: <?>
-# ET-DYN-NO-WARNING: BB entries [
+# ET-DYN-NO-WARNING: BB Ranges [
# ET-DYN-NO-WARNING: {
-# ET-DYN-NO-WARNING: ID: 0
-# ET-DYN-NO-WARNING: Offset: 0x0
-# ET-DYN-NO-WARNING: Size: 0xF
-# ET-DYN-NO-WARNING: HasReturn: Yes
-# ET-DYN-NO-WARNING: HasTailCall: No
-# ET-DYN-NO-WARNING: IsEHPad: No
-# ET-DYN-NO-WARNING: CanFallThrough: No
-# ET-DYN-NO-WARNING: HasIndirectBranch: No
+# ET-DYN-NO-WARNING: Base Address: 0xF
+# ET-DYN-NO-WARNING: BB Entries [
+# ET-DYN-NO-WARNING: {
+# ET-DYN-NO-WARNING: ID: 0
+# ET-DYN-NO-WARNING: Offset: 0x0
+# ET-DYN-NO-WARNING: Size: 0xF
+# ET-DYN-NO-WARNING: HasReturn: Yes
+# ET-DYN-NO-WARNING: HasTailCall: No
+# ET-DYN-NO-WARNING: IsEHPad: No
+# ET-DYN-NO-WARNING: CanFallThrough: No
+# ET-DYN-NO-WARNING: HasIndirectBranch: No
+# ET-DYN-NO-WARNING: }
+# ET-DYN-NO-WARNING: ]
# ET-DYN-NO-WARNING: }
# ET-DYN-NO-WARNING: ]
# ET-DYN-NO-WARNING: }
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
index 0593f04..c5d071c 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
@@ -15,8 +15,8 @@
# RUN: llvm-readelf %t1.x32.o --bb-addr-map | FileCheck %s --check-prefix=GNU
## Check that a malformed section can be handled.
-# RUN: yaml2obj --docnum=1 %s -DBITS=32 -DSIZE=6 -o %t2.o
-# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -DFILE=%t2.o --check-prefix=TRUNCATED
+# RUN: yaml2obj --docnum=1 %s -DBITS=32 -DSIZE=7 -o %t2.o
+# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000007 -DFILE=%t2.o --check-prefix=TRUNCATED
## Check that invalid metadata can be handled.
# RUN: yaml2obj --docnum=1 %s -DBITS=32 -DMETADATA=0xF000002 -o %t3.o
@@ -27,42 +27,57 @@
# CHECK-NEXT: At: [[ADDR]]
# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
# CHECK-NEXT: Name: <?>
-# CHECK-NEXT: BB entries [
+# CHECK-NEXT: BB Ranges [
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 0
-# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: Size: 0x1
-# CHECK-NEXT: HasReturn: No
-# CHECK-NEXT: HasTailCall: Yes
-# CHECK-NEXT: IsEHPad: No
-# CHECK-NEXT: CanFallThrough: No
-# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: Base Address: [[ADDR]]
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 0
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: Size: 0x1
+# CHECK-NEXT: HasReturn: No
+# CHECK-NEXT: HasTailCall: Yes
+# CHECK-NEXT: IsEHPad: No
+# CHECK-NEXT: CanFallThrough: No
+# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 2
-# CHECK-NEXT: Offset: 0x4
-# CHECK-NEXT: Size: 0x4
-# CHECK-NEXT: HasReturn: Yes
-# CHECK-NEXT: HasTailCall: No
-# CHECK-NEXT: IsEHPad: Yes
-# CHECK-NEXT: CanFallThrough: No
-# CHECK-NEXT: HasIndirectBranch: Yes
+# CHECK-NEXT: Base Address: 0x44444
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 2
+# CHECK-NEXT: Offset: 0x3
+# CHECK-NEXT: Size: 0x4
+# CHECK-NEXT: HasReturn: Yes
+# CHECK-NEXT: HasTailCall: No
+# CHECK-NEXT: IsEHPad: Yes
+# CHECK-NEXT: CanFallThrough: No
+# CHECK-NEXT: HasIndirectBranch: Yes
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: Function {
# CHECK-NEXT: At: 0x22222
# CHECK-NEXT: Name: foo
-# CHECK-NEXT: BB entries [
+# CHECK-NEXT: BB Ranges [
# CHECK-NEXT: {
-# CHECK-NEXT: ID: 4
-# CHECK-NEXT: Offset: 0x6
-# CHECK-NEXT: Size: 0x7
-# CHECK-NEXT: HasReturn: No
-# CHECK-NEXT: HasTailCall: No
-# CHECK-NEXT: IsEHPad: No
-# CHECK-NEXT: CanFallThrough: Yes
-# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: Base Address: 0x22222
+# CHECK-NEXT: BB Entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 4
+# CHECK-NEXT: Offset: 0x6
+# CHECK-NEXT: Size: 0x7
+# CHECK-NEXT: HasReturn: No
+# CHECK-NEXT: HasTailCall: No
+# CHECK-NEXT: IsEHPad: No
+# CHECK-NEXT: CanFallThrough: Yes
+# CHECK-NEXT: HasIndirectBranch: No
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
@@ -78,26 +93,31 @@
# TRUNCATED-NEXT: Function {
# TRUNCATED-NEXT: At: 0x33333
# TRUNCATED-NEXT: Name: bar
-# TRUNCATED-NEXT: BB entries [
+# TRUNCATED-NEXT: BB Ranges [
# TRUNCATED-NEXT: {
-# TRUNCATED-NEXT: ID: 6
-# TRUNCATED-NEXT: Offset: 0x9
-# TRUNCATED-NEXT: Size: 0xA
-# TRUNCATED-NEXT: HasReturn: Yes
-# TRUNCATED-NEXT: HasTailCall: Yes
-# TRUNCATED-NEXT: IsEHPad: No
-# TRUNCATED-NEXT: CanFallThrough: Yes
-# TRUNCATED-NEXT: HasIndirectBranch: Yes
-# TRUNCATED-NEXT: }
-# TRUNCATED-NEXT: {
-# TRUNCATED-NEXT: ID: 7
-# TRUNCATED-NEXT: Offset: 0x1F
-# TRUNCATED-NEXT: Size: 0xD
-# TRUNCATED-NEXT: HasReturn: No
-# TRUNCATED-NEXT: HasTailCall: Yes
-# TRUNCATED-NEXT: IsEHPad: Yes
-# TRUNCATED-NEXT: CanFallThrough: Yes
-# TRUNCATED-NEXT: HasIndirectBranch: No
+# TRUNCATED-NEXT: Base Address: 0x33333
+# TRUNCATED-NEXT: BB Entries [
+# TRUNCATED-NEXT: {
+# TRUNCATED-NEXT: ID: 6
+# TRUNCATED-NEXT: Offset: 0x9
+# TRUNCATED-NEXT: Size: 0xA
+# TRUNCATED-NEXT: HasReturn: Yes
+# TRUNCATED-NEXT: HasTailCall: Yes
+# TRUNCATED-NEXT: IsEHPad: No
+# TRUNCATED-NEXT: CanFallThrough: Yes
+# TRUNCATED-NEXT: HasIndirectBranch: Yes
+# TRUNCATED-NEXT: }
+# TRUNCATED-NEXT: {
+# TRUNCATED-NEXT: ID: 7
+# TRUNCATED-NEXT: Offset: 0x1F
+# TRUNCATED-NEXT: Size: 0xD
+# TRUNCATED-NEXT: HasReturn: No
+# TRUNCATED-NEXT: HasTailCall: Yes
+# TRUNCATED-NEXT: IsEHPad: Yes
+# TRUNCATED-NEXT: CanFallThrough: Yes
+# TRUNCATED-NEXT: HasIndirectBranch: No
+# TRUNCATED-NEXT: }
+# TRUNCATED-NEXT: ]
# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: ]
# TRUNCATED-NEXT: }
@@ -124,23 +144,28 @@ Sections:
Link: .text
Entries:
- Version: 2
- Address: [[ADDR=0x11111]]
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x1
- Metadata: [[METADATA=0x2]]
- - ID: 2
- AddressOffset: 0x3
- Size: 0x4
- Metadata: 0x15
+ Feature: 0x8
+ BBRanges:
+ - BaseAddress: [[ADDR=0x11111]]
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: [[METADATA=0x2]]
+ - BaseAddress: 0x44444
+ BBEntries:
+ - ID: 2
+ AddressOffset: 0x3
+ Size: 0x4
+ Metadata: 0x15
- Version: 2
- Address: 0x22222
- BBEntries:
- - ID: 4
- AddressOffset: 0x6
- Size: 0x7
- Metadata: 0x8
+ BBRanges:
+ - BaseAddress: 0x22222
+ BBEntries:
+ - ID: 4
+ AddressOffset: 0x6
+ Size: 0x7
+ Metadata: 0x8
- Name: dummy_section
Type: SHT_PROGBITS
Size: 16
@@ -149,16 +174,17 @@ Sections:
Link: .text.bar
Entries:
- Version: 2
- Address: 0x33333
- BBEntries:
- - ID: 6
- AddressOffset: 0x9
- Size: 0xa
- Metadata: 0x1b
- - ID: 7
- AddressOffset: 0xc
- Size: 0xd
- Metadata: 0xe
+ BBRanges:
+ - BaseAddress: 0x33333
+ BBEntries:
+ - ID: 6
+ AddressOffset: 0x9
+ Size: 0xa
+ Metadata: 0x1b
+ - ID: 7
+ AddressOffset: 0xc
+ Size: 0xd
+ Metadata: 0xe
Symbols:
- Name: foo
Section: .text
@@ -168,103 +194,3 @@ Symbols:
Section: .text.bar
Type: STT_FUNC
Value: 0x33333
-
-## Check that using the SHT_LLVM_BB_ADDR_MAP_V0 section type generates the same
-## result as using the SHT_LLVM_BB_ADDR_MAP section type with Version=0.
-## The Version field is required even for SHT_LLVM_BB_ADDR_MAP_V0 but it
-## should not impact the result. This unideal behavior will be gone once
-## SHT_LLVM_BB_ADDR_MAP_V0 is deprecated.
-
-# RUN: yaml2obj --docnum=2 %s -DVERSION=255 -DSECTION_TYPE=SHT_LLVM_BB_ADDR_MAP_V0 -o %t2.type0
-# RUN: llvm-readobj %t2.type0 --bb-addr-map 2>&1 | FileCheck %s --check-prefix=V0
-
-# RUN: yaml2obj --docnum=2 %s -DVERSION=0 -DSECTION_TYPE=SHT_LLVM_BB_ADDR_MAP -o %t2.version0
-# RUN: llvm-readobj %t2.version0 --bb-addr-map 2>&1 | FileCheck %s --check-prefix=V0
-
-# V0: BBAddrMap [
-# V0-NEXT: Function {
-# V0-NEXT: At: 0x11111
-# V0-NEXT: Name: foo
-# V0-NEXT: BB entries [
-# V0-NEXT: {
-# V0-NEXT: ID: 0
-# V0-NEXT: Offset: 0x1
-# V0-NEXT: Size: 0x2
-# V0-NEXT: HasReturn:
-# V0-NEXT: HasTailCall:
-# V0-NEXT: IsEHPad:
-# V0-NEXT: CanFallThrough:
-# V0-NEXT: HasIndirectBranch:
-# V0-NEXT: }
-# V0-NEXT: {
-# V0-NEXT: ID: 1
-# V0-NEXT: Offset: 0x4
-# V0-NEXT: Size: 0x5
-# V0-NEXT: HasReturn:
-# V0-NEXT: HasTailCall:
-# V0-NEXT: IsEHPad:
-# V0-NEXT: CanFallThrough:
-# V0-NEXT: HasIndirectBranch:
-# V0-NEXT: }
-# V0-NEXT: ]
-# V0-NEXT: }
-
-## Check version 1 (without BB IDs).
-# RUN: yaml2obj --docnum=2 %s -DVERSION=1 -DSECTION_TYPE=SHT_LLVM_BB_ADDR_MAP -o %t3
-# RUN: llvm-readobj %t3 --bb-addr-map 2>&1 | FileCheck %s --check-prefix=V1
-
-# V1: BBAddrMap [
-# V1-NEXT: Function {
-# V1-NEXT: At: 0x11111
-# V1-NEXT: Name: foo
-# V1-NEXT: BB entries [
-# V1-NEXT: {
-# V1-NEXT: ID: 0
-# V1-NEXT: Offset: 0x1
-# V1-NEXT: Size: 0x2
-# V1-NEXT: HasReturn:
-# V1-NEXT: HasTailCall:
-# V1-NEXT: IsEHPad:
-# V1-NEXT: CanFallThrough:
-# V1-NEXT: HasIndirectBranch:
-# V1-NEXT: }
-# V1-NEXT: {
-# V1-NEXT: ID: 1
-# V1-NEXT: Offset: 0x7
-# V1-NEXT: Size: 0x5
-# V1-NEXT: HasReturn:
-# V1-NEXT: HasTailCall:
-# V1-NEXT: IsEHPad:
-# V1-NEXT: CanFallThrough:
-# V1-NEXT: HasIndirectBranch:
-# V1-NEXT: }
-# V1-NEXT: ]
-# V1-NEXT: }
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .text.foo
- Type: SHT_PROGBITS
- Flags: [SHF_ALLOC]
- - Name: .llvm_bb_addr_map
- Type: [[SECTION_TYPE]]
- Link: .text.foo
- Entries:
- - Version: [[VERSION]]
- Address: 0x11111
- BBEntries:
- - AddressOffset: 0x1
- Size: 0x2
- Metadata: 0x3
- - AddressOffset: 0x4
- Size: 0x5
- Metadata: 0x6
-Symbols:
- - Name: foo
- Section: .text.foo
- Type: STT_FUNC
- Value: 0x11111
diff --git a/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml b/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
index 629c29e..8dbf97e 100644
--- a/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
@@ -14,30 +14,31 @@
# VALID-NEXT: - Name: .llvm_bb_addr_map
# VALID-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# VALID-NEXT: Entries:
-## The 'Address' field is omitted when it's zero.
# VALID-NEXT: - Version: 2
-# VALID-NEXT: Feature: 0xFF
-# VALID-NEXT: BBEntries:
-# VALID-NEXT: - ID: 0
-# VALID-NEXT: AddressOffset: 0x1
-# VALID-NEXT: Size: 0x2
-# VALID-NEXT: Metadata: 0x3
-# VALID-NEXT: - ID: 2
-# VALID-NEXT: AddressOffset: 0x4
-# VALID-NEXT: Size: 0x5
-# VALID-NEXT: Metadata: 0x6
-# VALID-NEXT: - ID: 4
-# VALID-NEXT: AddressOffset: 0xFFFFFFFFFFFFFFF7
-# VALID-NEXT: Size: 0xFFFFFFFFFFFFFFF8
-# VALID-NEXT: Metadata: 0xFFFFFFFFFFFFFFF9
+# VALID-NEXT: BBRanges:
+## The 'BaseAddress' field is omitted when it's zero.
+# VALID-NEXT: - BBEntries:
+# VALID-NEXT: - ID: 0
+# VALID-NEXT: AddressOffset: 0x1
+# VALID-NEXT: Size: 0x2
+# VALID-NEXT: Metadata: 0x3
+# VALID-NEXT: - ID: 2
+# VALID-NEXT: AddressOffset: 0x4
+# VALID-NEXT: Size: 0x5
+# VALID-NEXT: Metadata: 0x6
+# VALID-NEXT: - ID: 4
+# VALID-NEXT: AddressOffset: 0xFFFFFFFFFFFFFFF7
+# VALID-NEXT: Size: 0xFFFFFFFFFFFFFFF8
+# VALID-NEXT: Metadata: 0xFFFFFFFFFFFFFFF9
# VALID-NEXT: - Version: 2
-# VALID-NEXT: Feature: 0xEE
-# VALID-NEXT: Address: 0xFFFFFFFFFFFFFF20
-# VALID-NEXT: BBEntries:
-# VALID-NEXT: - ID: 6
-# VALID-NEXT: AddressOffset: 0xA
-# VALID-NEXT: Size: 0xB
-# VALID-NEXT: Metadata: 0xC
+# VALID-NEXT: Feature: 0x8
+# VALID-NEXT: BBRanges:
+# VALID-NEXT: - BaseAddress: 0xFFFFFFFFFFFFFF20
+# VALID-NEXT: BBEntries:
+# VALID-NEXT: - ID: 6
+# VALID-NEXT: AddressOffset: 0xA
+# VALID-NEXT: Size: 0xB
+# VALID-NEXT: Metadata: 0xC
--- !ELF
FileHeader:
@@ -50,30 +51,33 @@ Sections:
ShSize: [[SIZE=<none>]]
Entries:
- Version: 2
- Feature: 0xFF
- Address: 0x0
- BBEntries:
- - ID: 0
- AddressOffset: 0x1
- Size: 0x2
- Metadata: 0x3
- - ID: 2
- AddressOffset: 0x4
- Size: 0x5
- Metadata: 0x6
- - ID: 4
- AddressOffset: 0xFFFFFFFFFFFFFFF7
- Size: 0xFFFFFFFFFFFFFFF8
- Metadata: 0xFFFFFFFFFFFFFFF9
+ Feature: 0x0
+ BBRanges:
+ - BaseAddress: 0x0
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x1
+ Size: 0x2
+ Metadata: 0x3
+ - ID: 2
+ AddressOffset: 0x4
+ Size: 0x5
+ Metadata: 0x6
+ - ID: 4
+ AddressOffset: 0xFFFFFFFFFFFFFFF7
+ Size: 0xFFFFFFFFFFFFFFF8
+ Metadata: 0xFFFFFFFFFFFFFFF9
- Version: 2
- Feature: 0xEE
- Address: 0xFFFFFFFFFFFFFF20
- NumBlocks: [[NUMBLOCKS=<none>]]
- BBEntries:
- - ID: 6
- AddressOffset: 0xA
- Size: 0xB
- Metadata: 0xC
+ Feature: 0x8
+ NumBBRanges: [[NUMBBRANGES=<none>]]
+ BBRanges:
+ - BaseAddress: 0xFFFFFFFFFFFFFF20
+ NumBlocks: [[NUMBLOCKS=<none>]]
+ BBEntries:
+ - ID: 6
+ AddressOffset: 0xA
+ Size: 0xB
+ Metadata: 0xC
## Check obj2yaml can dump empty .llvm_bb_addr_map sections.
@@ -114,19 +118,21 @@ Sections:
# MULTI-NEXT: - Name: .llvm_bb_addr_map
# MULTI-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# MULTI-NEXT: Entries:
-## Fields 'Address' and 'Feature' are omitted when they are zero.
+## Fields 'BaseAddress' and 'Feature' are omitted when they are zero.
# MULTI-NEXT: - Version: 0
-# MULTI-NEXT: BBEntries:
-# MULTI-NEXT: - ID: 0
-# MULTI-NEXT: AddressOffset: 0x1
-# MULTI-NEXT: Size: 0x2
-# MULTI-NEXT: Metadata: 0x3
+# MULTI-NEXT: BBRanges:
+# MULTI-NEXT: - BBEntries:
+# MULTI-NEXT: - ID: 0
+# MULTI-NEXT: AddressOffset: 0x1
+# MULTI-NEXT: Size: 0x2
+# MULTI-NEXT: Metadata: 0x3
# MULTI-NEXT: - Name: '.llvm_bb_addr_map (1)'
# MULTI-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# MULTI-NEXT: Entries:
# MULTI-NEXT: - Version: 0
-# MULTI-NEXT: Address: 0x20
-# MULTI-NEXT: BBEntries: []
+# MULTI-NEXT: BBRanges:
+# MULTI-NEXT: - BaseAddress: 0x20
+# MULTI-NEXT: BBEntries: []
--- !ELF
FileHeader:
@@ -141,26 +147,31 @@ Sections:
## they are zero.
- Version: 0
Feature: 0x0
- Address: 0x0
- BBEntries:
- - AddressOffset: 0x1
- Size: 0x2
- Metadata: 0x3
+ BBRanges:
+ - BaseAddress: 0x0
+ BBEntries:
+ - AddressOffset: 0x1
+ Size: 0x2
+ Metadata: 0x3
- Name: '.llvm_bb_addr_map (1)'
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 0
- Address: 0x20
+ BBRanges:
+ - BaseAddress: 0x20
## 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' field is specified.
+## when an invalid 'NumBlocks' or 'NumBBRanges` field is specified.
# RUN: yaml2obj --docnum=1 -DSIZE=0x8 %s -o %t4
# RUN: obj2yaml %t4 | FileCheck %s --check-prefixes=TRUNCATED,INVALID
# RUN: yaml2obj --docnum=1 -DNUMBLOCKS=2 %s -o %t5
-# RUN: obj2yaml %t5 | FileCheck %s --check-prefixes=BADNUMBLOCKS,INVALID
+# RUN: obj2yaml %t5 | FileCheck %s --check-prefixes=BADNUM,INVALID
+
+# RUN: yaml2obj --docnum=1 -DNUMBBRANGES=2 %s -o %t6
+# RUN: obj2yaml %t6 | FileCheck %s --check-prefixes=BADNUM,INVALID
# INVALID: --- !ELF
# INVALID-NEXT: FileHeader:
@@ -170,86 +181,5 @@ Sections:
# INVALID-NEXT: Sections:
# INVALID-NEXT: - Name: .llvm_bb_addr_map
# INVALID-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
-# BADNUMBLOCKS-NEXT: Content: {{([[:xdigit:]]+)}}{{$}}
-# TRUNCATED-NEXT: Content: {{([[:xdigit:]]{16})}}{{$}}
-
-## Check obj2yaml for SHT_LLVM_BB_ADDR_MAP_V0.
-# RUN: yaml2obj --docnum=4 %s -o %t6
-# RUN: obj2yaml %t6 | FileCheck %s --check-prefix=V0
-
-# V0: --- !ELF
-# V0-NEXT: FileHeader:
-# V0-NEXT: Class: ELFCLASS64
-# V0-NEXT: Data: ELFDATA2LSB
-# V0-NEXT: Type: ET_EXEC
-# V0-NEXT: Sections:
-# V0-NEXT: - Name: .llvm_bb_addr_map
-# V0-NEXT: Type: SHT_LLVM_BB_ADDR_MAP_V0
-# V0-NEXT: Entries:
-# V0-NEXT: - Version: 0
-# V0-NEXT: Address: 0x1111
-# V0-NEXT: BBEntries:
-# V0-NEXT: - ID: 0
-# V0-NEXT: AddressOffset: 0x1
-# V0-NEXT: Size: 0x2
-# V0-NEXT: Metadata: 0x3
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .llvm_bb_addr_map
- Type: SHT_LLVM_BB_ADDR_MAP_V0
- Entries:
- - Version: 0
- Address: 0x1111
- BBEntries:
- - AddressOffset: 0x1
- Size: 0x2
- Metadata: 0x3
-
-## Check obj2yaml for version 1.
-# RUN: yaml2obj --docnum=5 %s -o %t7
-# RUN: obj2yaml %t7 | FileCheck %s --check-prefix=V1
-
-# V1: --- !ELF
-# V1-NEXT: FileHeader:
-# V1-NEXT: Class: ELFCLASS64
-# V1-NEXT: Data: ELFDATA2LSB
-# V1-NEXT: Type: ET_EXEC
-# V1-NEXT: Sections:
-# V1-NEXT: - Name: .llvm_bb_addr_map
-# V1-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
-# V1-NEXT: Entries:
-# V1-NEXT: - Version: 1
-# V1-NEXT: Address: 0x1111
-# V1-NEXT: BBEntries:
-# V1-NEXT: - ID: 0
-# V1-NEXT: AddressOffset: 0x1
-# V1-NEXT: Size: 0x2
-# V1-NEXT: Metadata: 0x3
-# V1-NEXT: - ID: 1
-# V1-NEXT: AddressOffset: 0x4
-# V1-NEXT: Size: 0x5
-# V1-NEXT: Metadata: 0x6
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .llvm_bb_addr_map
- Type: SHT_LLVM_BB_ADDR_MAP
- Entries:
- - Version: 1
- Address: 0x1111
- BBEntries:
- - AddressOffset: 0x1
- Size: 0x2
- Metadata: 0x3
- - AddressOffset: 0x4
- Size: 0x5
- Metadata: 0x6
+# BADNUM-NEXT: Content: {{([[:xdigit:]]+)}}{{$}}
+# TRUNCATED-NEXT: Content: '{{([[:xdigit:]]{16})}}'{{$}}
diff --git a/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml b/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
index 2086dc5..709938b 100644
--- a/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
@@ -53,6 +53,21 @@
# CHECK-NEXT: 0000: 02002000 00000000 0000020D 010203
# CHECK-NEXT: )
+# Case 7: Specify empty BBRanges.
+# CHECK: Name: .llvm_bb_addr_map (1)
+# CHECK: SectionData (
+# CHECK-NEXT: 0000: 020000
+# CHECK-NEXT: )
+
+# Case 8: Specify empty BBRanges with multi-bb-range.
+# CHECK: Name: .llvm_bb_addr_map (1)
+# CHECK: SectionData (
+# CHECK-NEXT: 0000: 020800
+# CHECK-NEXT: )
+
+
+
+
--- !ELF
FileHeader:
Class: ELFCLASS64
@@ -86,12 +101,13 @@ Sections:
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 2
- Address: 0x0000000000000020
- BBEntries:
- - ID: 11
- AddressOffset: 0x00000001
- Size: 0x00000002
- Metadata: 0x00000003
+ BBRanges:
+ - BaseAddress: 0x0000000000000020
+ BBEntries:
+ - ID: 11
+ AddressOffset: 0x00000001
+ Size: 0x00000002
+ Metadata: 0x00000003
## 5) When specifying the description with Entries, the 'Address' field will be
## zero when omitted.
@@ -99,11 +115,12 @@ Sections:
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 2
- BBEntries:
- - ID: 12
- AddressOffset: 0x00000001
- Size: 0x00000002
- Metadata: 0x00000003
+ BBRanges:
+ - BBEntries:
+ - ID: 12
+ AddressOffset: 0x00000001
+ Size: 0x00000002
+ Metadata: 0x00000003
## 6) We can override the NumBlocks field with a value different from the
## actual number of BB Entries.
@@ -111,13 +128,31 @@ Sections:
Type: SHT_LLVM_BB_ADDR_MAP
Entries:
- Version: 2
- Address: 0x0000000000000020
- NumBlocks: 2
- BBEntries:
- - ID: 13
- AddressOffset: 0x00000001
- Size: 0x00000002
- Metadata: 0x00000003
+ BBRanges:
+ - BaseAddress: 0x0000000000000020
+ NumBlocks: 2
+ BBEntries:
+ - ID: 13
+ AddressOffset: 0x00000001
+ Size: 0x00000002
+ Metadata: 0x00000003
+
+## 7) We can produce a SHT_LLVM_BB_ADDR_MAP section from a description
+## with one entry with empty BBRanges.
+ - Name: '.llvm_bb_addr_map (7)'
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Entries:
+ - Version: 2
+ BBRanges: []
+
+## 8) We can produce a SHT_LLVM_BB_ADDR_MAP section from a multi-bb-range
+## description with one entry with empty BBRanges.
+ - Name: '.llvm_bb_addr_map (8)'
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Entries:
+ - Version: 2
+ Feature: 0x8
+ BBRanges: []
## 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
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 7f57713..b4467ec 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -172,6 +172,110 @@ public:
"Mach-O object file displaying tool") {}
};
+struct BBAddrMapLabel {
+ std::string BlockLabel;
+ std::string PGOAnalysis;
+};
+
+// This class represents the BBAddrMap and PGOMap associated with a single
+// function.
+class BBAddrMapFunctionEntry {
+public:
+ BBAddrMapFunctionEntry(BBAddrMap AddrMap, PGOAnalysisMap PGOMap)
+ : AddrMap(std::move(AddrMap)), PGOMap(std::move(PGOMap)) {}
+
+ const BBAddrMap &getAddrMap() const { return AddrMap; }
+
+ // Returns the PGO string associated with the entry of index `PGOBBEntryIndex`
+ // in `PGOMap`.
+ std::string constructPGOLabelString(size_t PGOBBEntryIndex) const {
+ if (!PGOMap.FeatEnable.hasPGOAnalysis())
+ return "";
+ std::string PGOString;
+ raw_string_ostream PGOSS(PGOString);
+
+ PGOSS << " (";
+ if (PGOMap.FeatEnable.FuncEntryCount && PGOBBEntryIndex == 0) {
+ PGOSS << "Entry count: " << Twine(PGOMap.FuncEntryCount);
+ if (PGOMap.FeatEnable.hasPGOAnalysisBBData()) {
+ PGOSS << ", ";
+ }
+ }
+
+ if (PGOMap.FeatEnable.hasPGOAnalysisBBData()) {
+
+ assert(PGOBBEntryIndex < PGOMap.BBEntries.size() &&
+ "Expected PGOAnalysisMap and BBAddrMap to have the same entries");
+ const PGOAnalysisMap::PGOBBEntry &PGOBBEntry =
+ PGOMap.BBEntries[PGOBBEntryIndex];
+
+ if (PGOMap.FeatEnable.BBFreq) {
+ PGOSS << "Frequency: " << Twine(PGOBBEntry.BlockFreq.getFrequency());
+ if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
+ PGOSS << ", ";
+ }
+ }
+ if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
+ PGOSS << "Successors: ";
+ interleaveComma(
+ PGOBBEntry.Successors, PGOSS,
+ [&PGOSS](const PGOAnalysisMap::PGOBBEntry::SuccessorEntry &SE) {
+ PGOSS << "BB" << SE.ID << ":";
+ PGOSS.write_hex(SE.Prob.getNumerator());
+ });
+ }
+ }
+ PGOSS << ")";
+
+ return PGOString;
+ }
+
+private:
+ const BBAddrMap AddrMap;
+ const PGOAnalysisMap PGOMap;
+};
+
+// This class represents the BBAddrMap and PGOMap of potentially multiple
+// functions in a section.
+class BBAddrMapInfo {
+public:
+ void clear() {
+ FunctionAddrToMap.clear();
+ RangeBaseAddrToFunctionAddr.clear();
+ }
+
+ bool empty() const { return FunctionAddrToMap.empty(); }
+
+ void AddFunctionEntry(BBAddrMap AddrMap, PGOAnalysisMap PGOMap) {
+ uint64_t FunctionAddr = AddrMap.getFunctionAddress();
+ for (size_t I = 1; I < AddrMap.BBRanges.size(); ++I)
+ RangeBaseAddrToFunctionAddr.emplace(AddrMap.BBRanges[I].BaseAddress,
+ FunctionAddr);
+ [[maybe_unused]] auto R = FunctionAddrToMap.try_emplace(
+ FunctionAddr, std::move(AddrMap), std::move(PGOMap));
+ assert(R.second && "duplicate function address");
+ }
+
+ // Returns the BBAddrMap entry for the function associated with `BaseAddress`.
+ // `BaseAddress` could be the function address or the address of a range
+ // associated with that function. Returns `nullptr` if `BaseAddress` is not
+ // mapped to any entry.
+ const BBAddrMapFunctionEntry *getEntryForAddress(uint64_t BaseAddress) const {
+ uint64_t FunctionAddr = BaseAddress;
+ auto S = RangeBaseAddrToFunctionAddr.find(BaseAddress);
+ if (S != RangeBaseAddrToFunctionAddr.end())
+ FunctionAddr = S->second;
+ auto R = FunctionAddrToMap.find(FunctionAddr);
+ if (R == FunctionAddrToMap.end())
+ return nullptr;
+ return &R->second;
+ }
+
+private:
+ std::unordered_map<uint64_t, BBAddrMapFunctionEntry> FunctionAddrToMap;
+ std::unordered_map<uint64_t, uint64_t> RangeBaseAddrToFunctionAddr;
+};
+
} // namespace
#define DEBUG_TYPE "objdump"
@@ -1266,80 +1370,38 @@ static SymbolInfoTy createDummySymbolInfo(const ObjectFile &Obj,
return SymbolInfoTy(Addr, Name, Type);
}
-struct BBAddrMapLabel {
- std::string BlockLabel;
- std::string PGOAnalysis;
-};
-
-static std::string constructPGOLabelString(const PGOAnalysisMap &PGOMap,
- size_t BBEntryIndex) {
- std::string PGOString;
- raw_string_ostream PGOSS(PGOString);
-
- PGOSS << " (";
- if (PGOMap.FeatEnable.FuncEntryCount && BBEntryIndex == 0) {
- PGOSS << "Entry count: " << Twine(PGOMap.FuncEntryCount);
- if (PGOMap.FeatEnable.BBFreq || PGOMap.FeatEnable.BrProb) {
- PGOSS << ", ";
- }
- }
-
- if (PGOMap.FeatEnable.BBFreq || PGOMap.FeatEnable.BrProb) {
- assert(BBEntryIndex < PGOMap.BBEntries.size() &&
- "Expected PGOAnalysisMap and BBAddrMap to have the same entires");
- const PGOAnalysisMap::PGOBBEntry &PGOBBEntry =
- PGOMap.BBEntries[BBEntryIndex];
-
- if (PGOMap.FeatEnable.BBFreq) {
- PGOSS << "Frequency: " << Twine(PGOBBEntry.BlockFreq.getFrequency());
- if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
- PGOSS << ", ";
- }
- }
- if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
- PGOSS << "Successors: ";
- interleaveComma(
- PGOBBEntry.Successors, PGOSS,
- [&PGOSS](const PGOAnalysisMap::PGOBBEntry::SuccessorEntry &SE) {
- PGOSS << "BB" << SE.ID << ":";
- PGOSS.write_hex(SE.Prob.getNumerator());
- });
- }
- }
- PGOSS << ")";
-
- return PGOString;
-}
-
static void collectBBAddrMapLabels(
- const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
- const std::unordered_map<uint64_t, PGOAnalysisMap> &AddrToPGOAnalysisMap,
- uint64_t SectionAddr, uint64_t Start, uint64_t End,
- std::unordered_map<uint64_t, std::vector<BBAddrMapLabel>> &Labels,
- const StringRef FileName) {
- if (AddrToBBAddrMap.empty())
+ const BBAddrMapInfo &FullAddrMap, uint64_t SectionAddr, uint64_t Start,
+ uint64_t End,
+ std::unordered_map<uint64_t, std::vector<BBAddrMapLabel>> &Labels) {
+ if (FullAddrMap.empty())
return;
Labels.clear();
uint64_t StartAddress = SectionAddr + Start;
uint64_t EndAddress = SectionAddr + End;
- auto Iter = AddrToBBAddrMap.find(StartAddress);
- if (Iter == AddrToBBAddrMap.end())
+ const BBAddrMapFunctionEntry *FunctionMap =
+ FullAddrMap.getEntryForAddress(StartAddress);
+ if (!FunctionMap)
return;
- auto PGOIter = AddrToPGOAnalysisMap.find(StartAddress);
-
- for (size_t I = 0; I < Iter->second.getBBEntries().size(); ++I) {
- const BBAddrMap::BBEntry &BBEntry = Iter->second.getBBEntries()[I];
- uint64_t BBAddress = BBEntry.Offset + Iter->second.getFunctionAddress();
+ std::optional<size_t> BBRangeIndex =
+ FunctionMap->getAddrMap().getBBRangeIndexForBaseAddress(StartAddress);
+ if (!BBRangeIndex)
+ return;
+ size_t NumBBEntriesBeforeRange = 0;
+ for (size_t I = 0; I < *BBRangeIndex; ++I)
+ NumBBEntriesBeforeRange +=
+ FunctionMap->getAddrMap().BBRanges[I].BBEntries.size();
+ const auto &BBRange = FunctionMap->getAddrMap().BBRanges[*BBRangeIndex];
+ for (size_t I = 0; I < BBRange.BBEntries.size(); ++I) {
+ const BBAddrMap::BBEntry &BBEntry = BBRange.BBEntries[I];
+ uint64_t BBAddress = BBEntry.Offset + BBRange.BaseAddress;
if (BBAddress >= EndAddress)
continue;
std::string LabelString = ("BB" + Twine(BBEntry.ID)).str();
- std::string PGOString;
-
- if (PGOIter != AddrToPGOAnalysisMap.end())
- PGOString = constructPGOLabelString(PGOIter->second, I);
-
- Labels[BBAddress].push_back({LabelString, PGOString});
+ Labels[BBAddress].push_back(
+ {LabelString,
+ FunctionMap->constructPGOLabelString(NumBBEntriesBeforeRange + I)});
}
}
@@ -1696,11 +1758,10 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
LLVM_DEBUG(LVP.dump());
- std::unordered_map<uint64_t, BBAddrMap> AddrToBBAddrMap;
- std::unordered_map<uint64_t, PGOAnalysisMap> AddrToPGOAnalysisMap;
+ BBAddrMapInfo FullAddrMap;
auto ReadBBAddrMap = [&](std::optional<unsigned> SectionIndex =
std::nullopt) {
- AddrToBBAddrMap.clear();
+ FullAddrMap.clear();
if (const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj)) {
std::vector<PGOAnalysisMap> PGOAnalyses;
auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex, &PGOAnalyses);
@@ -1710,10 +1771,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
}
for (auto &&[FunctionBBAddrMap, FunctionPGOAnalysis] :
zip_equal(*std::move(BBAddrMapsOrErr), std::move(PGOAnalyses))) {
- uint64_t Addr = FunctionBBAddrMap.Addr;
- AddrToBBAddrMap.emplace(Addr, std::move(FunctionBBAddrMap));
- if (FunctionPGOAnalysis.FeatEnable.anyEnabled())
- AddrToPGOAnalysisMap.emplace(Addr, std::move(FunctionPGOAnalysis));
+ FullAddrMap.AddFunctionEntry(std::move(FunctionBBAddrMap),
+ std::move(FunctionPGOAnalysis));
}
}
};
@@ -2049,9 +2108,8 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
DT->DisAsm.get(), DT->InstPrinter.get(),
PrimaryTarget.SubtargetInfo.get(),
SectionAddr, Index, End, AllLabels);
- collectBBAddrMapLabels(AddrToBBAddrMap, AddrToPGOAnalysisMap,
- SectionAddr, Index, End, BBAddrMapLabels,
- FileName);
+ collectBBAddrMapLabels(FullAddrMap, SectionAddr, Index, End,
+ BBAddrMapLabels);
}
if (DT->InstrAnalysis)
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 4bf4640..ce33b15 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -7545,8 +7545,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
using Elf_Shdr = typename ELFT::Shdr;
auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
- return Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP ||
- Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP_V0;
+ return Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP;
};
Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecRelocMapOrErr =
this->Obj.getSectionAndRelocations(IsMatch);
@@ -7577,40 +7576,46 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
}
for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
DictScope D(W, "Function");
- W.printHex("At", AM.Addr);
+ W.printHex("At", AM.getFunctionAddress());
SmallVector<uint32_t> FuncSymIndex =
- this->getSymbolIndexesForFunctionAddress(AM.Addr, FunctionSec);
+ this->getSymbolIndexesForFunctionAddress(AM.getFunctionAddress(),
+ FunctionSec);
std::string FuncName = "<?>";
if (FuncSymIndex.empty())
this->reportUniqueWarning(
"could not identify function symbol for address (0x" +
- Twine::utohexstr(AM.Addr) + ") in " + this->describe(*Sec));
+ Twine::utohexstr(AM.getFunctionAddress()) + ") in " +
+ this->describe(*Sec));
else
FuncName = this->getStaticSymbolName(FuncSymIndex.front());
W.printString("Name", FuncName);
-
{
- ListScope L(W, "BB entries");
- for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
- DictScope L(W);
- W.printNumber("ID", BBE.ID);
- W.printHex("Offset", BBE.Offset);
- W.printHex("Size", BBE.Size);
- W.printBoolean("HasReturn", BBE.hasReturn());
- W.printBoolean("HasTailCall", BBE.hasTailCall());
- W.printBoolean("IsEHPad", BBE.isEHPad());
- W.printBoolean("CanFallThrough", BBE.canFallThrough());
- W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
+ ListScope BBRL(W, "BB Ranges");
+ for (const BBAddrMap::BBRangeEntry &BBR : AM.BBRanges) {
+ DictScope BBRD(W);
+ W.printHex("Base Address", BBR.BaseAddress);
+ ListScope BBEL(W, "BB Entries");
+ for (const BBAddrMap::BBEntry &BBE : BBR.BBEntries) {
+ DictScope BBED(W);
+ W.printNumber("ID", BBE.ID);
+ W.printHex("Offset", BBE.Offset);
+ W.printHex("Size", BBE.Size);
+ W.printBoolean("HasReturn", BBE.hasReturn());
+ W.printBoolean("HasTailCall", BBE.hasTailCall());
+ W.printBoolean("IsEHPad", BBE.isEHPad());
+ W.printBoolean("CanFallThrough", BBE.canFallThrough());
+ W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
+ }
}
}
- if (PAM.FeatEnable.anyEnabled()) {
+ if (PAM.FeatEnable.hasPGOAnalysis()) {
DictScope PD(W, "PGO analyses");
if (PAM.FeatEnable.FuncEntryCount)
W.printNumber("FuncEntryCount", PAM.FuncEntryCount);
- if (PAM.FeatEnable.BBFreq || PAM.FeatEnable.BrProb) {
+ if (PAM.FeatEnable.hasPGOAnalysisBBData()) {
ListScope L(W, "PGO BB entries");
for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {
DictScope L(W);
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 86bd138..38a69f7 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -626,7 +626,6 @@ ELFDumper<ELFT>::dumpSections() {
case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
return
[this](const Elf_Shdr *S) { return dumpCallGraphProfileSection(S); };
- case ELF::SHT_LLVM_BB_ADDR_MAP_V0:
case ELF::SHT_LLVM_BB_ADDR_MAP:
return [this](const Elf_Shdr *S) { return dumpBBAddrMapSection(S); };
case ELF::SHT_STRTAB:
@@ -893,6 +892,7 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
DataExtractor::Cursor Cur(0);
uint8_t Version = 0;
uint8_t Feature = 0;
+ uint64_t Address = 0;
while (Cur && Cur.tell() < Content.size()) {
if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
Version = Data.getU8(Cur);
@@ -903,19 +903,41 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
Twine(static_cast<int>(Version)));
Feature = Data.getU8(Cur);
}
- uint64_t Address = Data.getAddress(Cur);
- uint64_t NumBlocks = Data.getULEB128(Cur);
- std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;
- // Read the specified number of BB entries, or until decoding fails.
- for (uint64_t BlockIndex = 0; Cur && BlockIndex < NumBlocks; ++BlockIndex) {
- uint32_t ID = Version >= 2 ? Data.getULEB128(Cur) : BlockIndex;
- uint64_t Offset = Data.getULEB128(Cur);
- uint64_t Size = Data.getULEB128(Cur);
- uint64_t Metadata = Data.getULEB128(Cur);
- BBEntries.push_back({ID, Offset, Size, Metadata});
+ uint64_t NumBBRanges = 1;
+ uint64_t NumBlocks = 0;
+ auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(Feature);
+ if (!FeatureOrErr)
+ return FeatureOrErr.takeError();
+ if (FeatureOrErr->MultiBBRange) {
+ NumBBRanges = Data.getULEB128(Cur);
+ } else {
+ Address = Data.getAddress(Cur);
+ NumBlocks = Data.getULEB128(Cur);
+ }
+ std::vector<ELFYAML::BBAddrMapEntry::BBRangeEntry> BBRanges;
+ uint64_t BaseAddress = 0;
+ for (uint64_t BBRangeN = 0; Cur && BBRangeN != NumBBRanges; ++BBRangeN) {
+ if (FeatureOrErr->MultiBBRange) {
+ BaseAddress = Data.getAddress(Cur);
+ NumBlocks = Data.getULEB128(Cur);
+ } else {
+ BaseAddress = Address;
+ }
+
+ std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;
+ // Read the specified number of BB entries, or until decoding fails.
+ for (uint64_t BlockIndex = 0; Cur && BlockIndex < NumBlocks;
+ ++BlockIndex) {
+ uint32_t ID = Version >= 2 ? Data.getULEB128(Cur) : BlockIndex;
+ uint64_t Offset = Data.getULEB128(Cur);
+ uint64_t Size = Data.getULEB128(Cur);
+ uint64_t Metadata = Data.getULEB128(Cur);
+ BBEntries.push_back({ID, Offset, Size, Metadata});
+ }
+ BBRanges.push_back({BaseAddress, /*NumBlocks=*/{}, BBEntries});
}
Entries.push_back(
- {Version, Feature, Address, /*NumBlocks=*/{}, std::move(BBEntries)});
+ {Version, Feature, /*NumBBRanges=*/{}, std::move(BBRanges)});
}
if (!Cur) {
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index c539d79..c4d2b4a 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -511,7 +511,6 @@ Sections:
- Type: SHT_LLVM_BB_ADDR_MAP
Name: .llvm_bb_addr_map
Entries:
- - Address: 0x11111
)");
auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {
@@ -531,11 +530,13 @@ Sections:
// Check that we can detect unsupported versions.
SmallString<128> UnsupportedVersionYamlString(CommonYamlString);
UnsupportedVersionYamlString += R"(
- Version: 3
- BBEntries:
- - AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ - Version: 3
+ BBRanges:
+ - BaseAddress: 0x11111
+ BBEntries:
+ - AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
)";
{
@@ -544,14 +545,28 @@ Sections:
"unsupported SHT_LLVM_BB_ADDR_MAP version: 3");
}
+ SmallString<128> ZeroBBRangesYamlString(CommonYamlString);
+ ZeroBBRangesYamlString += R"(
+ - Version: 2
+ Feature: 0x8
+ BBRanges: []
+)";
+ {
+ SCOPED_TRACE("zero bb ranges");
+ DoCheck(ZeroBBRangesYamlString,
+ "invalid zero number of BB ranges at offset 3 in "
+ "SHT_LLVM_BB_ADDR_MAP section with index 1");
+ }
+
SmallString<128> CommonVersionedYamlString(CommonYamlString);
CommonVersionedYamlString += R"(
- Version: 2
- BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ - Version: 2
+ BBRanges:
+ - BaseAddress: 0x11111
+ BBEntries:
+ - AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
)";
// Check that we can detect the malformed encoding when the section is
@@ -572,24 +587,24 @@ Sections:
SmallVector<SmallString<128>, 3> OverInt32LimitYamlStrings(
3, CommonVersionedYamlString);
OverInt32LimitYamlStrings[0] += R"(
- - ID: 1
- AddressOffset: 0x100000000
- Size: 0xFFFFFFFF
- Metadata: 0xFFFFFFFF
+ - ID: 1
+ AddressOffset: 0x100000000
+ Size: 0xFFFFFFFF
+ Metadata: 0xFFFFFFFF
)";
OverInt32LimitYamlStrings[1] += R"(
- - ID: 2
- AddressOffset: 0xFFFFFFFF
- Size: 0x100000000
- Metadata: 0xFFFFFFFF
+ - ID: 2
+ AddressOffset: 0xFFFFFFFF
+ Size: 0x100000000
+ Metadata: 0xFFFFFFFF
)";
OverInt32LimitYamlStrings[2] += R"(
- - ID: 3
- AddressOffset: 0xFFFFFFFF
- Size: 0xFFFFFFFF
- Metadata: 0x100000000
+ - ID: 3
+ AddressOffset: 0xFFFFFFFF
+ Size: 0xFFFFFFFF
+ Metadata: 0x100000000
)";
{
@@ -635,7 +650,7 @@ Sections:
// with an out-of-range value.
SmallString<128> OverLimitNumBlocks(CommonVersionedYamlString);
OverLimitNumBlocks += R"(
- NumBlocks: 0x100000000
+ NumBlocks: 0x100000000
)";
{
@@ -643,6 +658,16 @@ Sections:
DoCheck(OverLimitNumBlocks,
"ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000)");
}
+
+ // Check for proper error handling when the 'NumBBRanges' field is overridden
+ // with an out-of-range value.
+ SmallString<128> OverLimitNumBBRanges(CommonVersionedYamlString);
+ OverLimitNumBBRanges += R"(
+ NumBBRanges: 0x100000000
+ Feature: 0x8
+)";
+ DoCheck(OverLimitNumBBRanges,
+ "ULEB128 value at offset 0x2 exceeds UINT32_MAX (0x100000000)");
}
// Test for the ELFObjectFile::readBBAddrMap API.
@@ -659,51 +684,67 @@ Sections:
Link: 1
Entries:
- Version: 2
- Address: 0x11111
- BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BaseAddress: 0x11111
+ BBEntries:
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
- Name: .llvm_bb_addr_map_2
Type: SHT_LLVM_BB_ADDR_MAP
Link: 1
Entries:
- Version: 2
- Address: 0x22222
- BBEntries:
- - ID: 2
- AddressOffset: 0x0
- Size: 0x2
- Metadata: 0x4
+ Feature: 0x8
+ BBRanges:
+ - BaseAddress: 0x22222
+ BBEntries:
+ - ID: 2
+ AddressOffset: 0x0
+ Size: 0x2
+ Metadata: 0x4
+ - BaseAddress: 0xFFFFF
+ BBEntries:
+ - ID: 15
+ AddressOffset: 0xF0
+ Size: 0xF1
+ Metadata: 0x1F
- Name: .llvm_bb_addr_map_3
Type: SHT_LLVM_BB_ADDR_MAP
Link: 2
Entries:
- Version: 1
- Address: 0x33333
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x3
- Metadata: 0x6
+ BBRanges:
+ - BaseAddress: 0x33333
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x3
+ Metadata: 0x6
- Name: .llvm_bb_addr_map_4
- Type: SHT_LLVM_BB_ADDR_MAP_V0
+ Type: SHT_LLVM_BB_ADDR_MAP
# Link: 0 (by default, can be overriden)
Entries:
- - Version: 0
- Address: 0x44444
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x4
- Metadata: 0x18
+ - Version: 2
+ BBRanges:
+ - BaseAddress: 0x44444
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x4
+ Metadata: 0x18
)");
- BBAddrMap E1(0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}});
- BBAddrMap E2(0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}});
- BBAddrMap E3(0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}}});
- BBAddrMap E4(0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}}});
+ BBAddrMap E1 = {
+ {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
+ BBAddrMap E2 = {
+ {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}},
+ {0xFFFFF, {{15, 0xF0, 0xF1, {true, true, true, true, true}}}}}};
+ BBAddrMap E3 = {
+ {{0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}}}}}};
+ BBAddrMap E4 = {
+ {{0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}}}}}};
std::vector<BBAddrMap> Section0BBAddrMaps = {E4};
std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
@@ -767,13 +808,13 @@ Sections:
// (not present) section.
SmallString<128> InvalidLinkedYamlString(CommonYamlString);
InvalidLinkedYamlString += R"(
- Link: 10
+ Link: 121
)";
DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/4,
"unable to get the linked-to section for "
- "SHT_LLVM_BB_ADDR_MAP_V0 section with index 4: invalid section "
- "index: 10");
+ "SHT_LLVM_BB_ADDR_MAP section with index 4: invalid section "
+ "index: 121");
{
SCOPED_TRACE("invalid linked section");
// Linked sections are not checked when we don't target a specific text
@@ -785,14 +826,14 @@ Sections:
// Check that we can detect when bb-address-map decoding fails.
SmallString<128> TruncatedYamlString(CommonYamlString);
TruncatedYamlString += R"(
- ShSize: 0x8
+ ShSize: 0xa
)";
{
SCOPED_TRACE("truncated section");
DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
- "unable to read SHT_LLVM_BB_ADDR_MAP_V0 section with index 4: "
- "unable to decode LEB128 at offset 0x00000008: malformed "
+ "unable to read SHT_LLVM_BB_ADDR_MAP section with index 4: "
+ "unable to decode LEB128 at offset 0x0000000a: malformed "
"uleb128, extends past end");
// Check that we can read the other section's bb-address-maps which are
@@ -815,7 +856,6 @@ Sections:
- Type: SHT_LLVM_BB_ADDR_MAP
Name: .llvm_bb_addr_map
Entries:
- - Address: 0x11111
)");
auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {
@@ -839,12 +879,13 @@ Sections:
// Check that we can detect unsupported versions that are too old.
SmallString<128> UnsupportedLowVersionYamlString(CommonYamlString);
UnsupportedLowVersionYamlString += R"(
- Version: 1
+ - Version: 1
Feature: 0x4
- BBEntries:
- - AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BBEntries:
+ - AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
)";
{
@@ -856,38 +897,39 @@ Sections:
SmallString<128> CommonVersionedYamlString(CommonYamlString);
CommonVersionedYamlString += R"(
- Version: 2
- BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ - Version: 2
+ BBRanges:
+ - BBEntries:
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
)";
// Check that we fail when function entry count is enabled but not provided.
SmallString<128> MissingFuncEntryCount(CommonYamlString);
MissingFuncEntryCount += R"(
- Version: 2
+ - Version: 2
Feature: 0x01
)";
{
SCOPED_TRACE("missing function entry count");
DoCheck(MissingFuncEntryCount,
- "unable to decode LEB128 at offset 0x0000000b: malformed uleb128, "
- "extends past end");
+ "unexpected end of data at offset 0x2 while reading [0x2, 0xa)");
}
// Check that we fail when basic block frequency is enabled but not provided.
SmallString<128> MissingBBFreq(CommonYamlString);
MissingBBFreq += R"(
- Version: 2
+ - Version: 2
Feature: 0x02
- BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BBEntries:
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
)";
{
@@ -899,21 +941,22 @@ Sections:
// Check that we fail when branch probability is enabled but not provided.
SmallString<128> MissingBrProb(CommonYamlString);
MissingBrProb += R"(
- Version: 2
+ - Version: 2
Feature: 0x04
- BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x6
- - ID: 2
- AddressOffset: 0x1
- Size: 0x1
- Metadata: 0x2
- - ID: 3
- AddressOffset: 0x2
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BBEntries:
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x6
+ - ID: 2
+ AddressOffset: 0x1
+ Size: 0x1
+ Metadata: 0x2
+ - ID: 3
+ AddressOffset: 0x2
+ Size: 0x1
+ Metadata: 0x2
PGOAnalyses:
- PGOBBEntries:
- Successors:
@@ -947,13 +990,14 @@ Sections:
Link: 1
Entries:
- Version: 2
- Address: 0x11111
Feature: 0x1
- BBEntries:
- - ID: 1
- AddressOffset: 0x0
- Size: 0x1
- Metadata: 0x2
+ BBRanges:
+ - BaseAddress: 0x11111
+ BBEntries:
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x2
PGOAnalyses:
- FuncEntryCount: 892
- Name: .llvm_bb_addr_map_2
@@ -961,13 +1005,14 @@ Sections:
Link: 1
Entries:
- Version: 2
- Address: 0x22222
Feature: 0x2
- BBEntries:
- - ID: 2
- AddressOffset: 0x0
- Size: 0x2
- Metadata: 0x4
+ BBRanges:
+ - BaseAddress: 0x22222
+ BBEntries:
+ - ID: 2
+ AddressOffset: 0x0
+ Size: 0x2
+ Metadata: 0x4
PGOAnalyses:
- PGOBBEntries:
- BBFreq: 343
@@ -976,21 +1021,22 @@ Sections:
Link: 2
Entries:
- Version: 2
- Address: 0x33333
Feature: 0x4
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x3
- Metadata: 0x6
- - ID: 1
- AddressOffset: 0x0
- Size: 0x3
- Metadata: 0x4
- - ID: 2
- AddressOffset: 0x0
- Size: 0x3
- Metadata: 0x0
+ BBRanges:
+ - BaseAddress: 0x33333
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x3
+ Metadata: 0x6
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x3
+ Metadata: 0x4
+ - ID: 2
+ AddressOffset: 0x0
+ Size: 0x3
+ Metadata: 0x0
PGOAnalyses:
- PGOBBEntries:
- Successors:
@@ -1007,25 +1053,26 @@ Sections:
# Link: 0 (by default, can be overriden)
Entries:
- Version: 2
- Address: 0x44444
Feature: 0x7
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x4
- Metadata: 0x18
- - ID: 1
- AddressOffset: 0x0
- Size: 0x4
- Metadata: 0x0
- - ID: 2
- AddressOffset: 0x0
- Size: 0x4
- Metadata: 0x0
- - ID: 3
- AddressOffset: 0x0
- Size: 0x4
- Metadata: 0x0
+ BBRanges:
+ - BaseAddress: 0x44444
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x4
+ Metadata: 0x18
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x4
+ Metadata: 0x0
+ - ID: 2
+ AddressOffset: 0x0
+ Size: 0x4
+ Metadata: 0x0
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x4
+ Metadata: 0x0
PGOAnalyses:
- FuncEntryCount: 1000
PGOBBEntries:
@@ -1054,34 +1101,74 @@ Sections:
# Link: 0 (by default, can be overriden)
Entries:
- Version: 2
- Address: 0x55555
Feature: 0x0
- BBEntries:
- - ID: 2
- AddressOffset: 0x0
- Size: 0x2
- Metadata: 0x4
+ BBRanges:
+ - BaseAddress: 0x55555
+ BBEntries:
+ - ID: 2
+ AddressOffset: 0x0
+ Size: 0x2
+ Metadata: 0x4
PGOAnalyses: [{}]
- )");
-
- BBAddrMap E1(0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}});
- PGOAnalysisMap P1 = {892, {}, {true, false, false}};
- BBAddrMap E2(0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}});
- PGOAnalysisMap P2 = {{}, {{BlockFrequency(343), {}}}, {false, true, false}};
- BBAddrMap E3(0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}},
- {1, 0x3, 0x3, {false, false, true, false, false}},
- {2, 0x6, 0x3, {false, false, false, false, false}}});
+ - Name: .llvm_bb_addr_map_6
+ Type: SHT_LLVM_BB_ADDR_MAP
+ # Link: 0 (by default, can be overriden)
+ Entries:
+ - Version: 2
+ Feature: 0xc
+ BBRanges:
+ - BaseAddress: 0x66666
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x6
+ - ID: 1
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x4
+ - BaseAddress: 0x666661
+ BBEntries:
+ - ID: 2
+ AddressOffset: 0x0
+ Size: 0x6
+ Metadata: 0x0
+ PGOAnalyses:
+ - PGOBBEntries:
+ - Successors:
+ - ID: 1
+ BrProb: 0x22222222
+ - ID: 2
+ BrProb: 0xcccccccc
+ - Successors:
+ - ID: 2
+ BrProb: 0x88888888
+ - Successors: []
+)");
+
+ BBAddrMap E1 = {
+ {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
+ PGOAnalysisMap P1 = {892, {}, {true, false, false, false}};
+ BBAddrMap E2 = {
+ {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
+ PGOAnalysisMap P2 = {
+ {}, {{BlockFrequency(343), {}}}, {false, true, false, false}};
+ BBAddrMap E3 = {{{0x33333,
+ {{0, 0x0, 0x3, {false, true, true, false, false}},
+ {1, 0x3, 0x3, {false, false, true, false, false}},
+ {2, 0x6, 0x3, {false, false, false, false, false}}}}}};
PGOAnalysisMap P3 = {{},
{{{},
{{1, BranchProbability::getRaw(0x1111'1111)},
{2, BranchProbability::getRaw(0xeeee'eeee)}}},
{{}, {{2, BranchProbability::getRaw(0xffff'ffff)}}},
{{}, {}}},
- {false, false, true}};
- BBAddrMap E4(0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}},
- {1, 0x4, 0x4, {false, false, false, false, false}},
- {2, 0x8, 0x4, {false, false, false, false, false}},
- {3, 0xc, 0x4, {false, false, false, false, false}}});
+ {false, false, true, false}};
+ BBAddrMap E4 = {{{0x44444,
+ {{0, 0x0, 0x4, {false, false, false, true, true}},
+ {1, 0x4, 0x4, {false, false, false, false, false}},
+ {2, 0x8, 0x4, {false, false, false, false, false}},
+ {3, 0xc, 0x4, {false, false, false, false, false}}}}}};
PGOAnalysisMap P4 = {
1000,
{{BlockFrequency(1000),
@@ -1093,19 +1180,32 @@ Sections:
{3, BranchProbability::getRaw(0xeeee'eeee)}}},
{BlockFrequency(18), {{3, BranchProbability::getRaw(0xffff'ffff)}}},
{BlockFrequency(1000), {}}},
- {true, true, true}};
- BBAddrMap E5(0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}}});
- PGOAnalysisMap P5 = {{}, {}, {false, false, false}};
+ {true, true, true, false}};
+ BBAddrMap E5 = {
+ {{0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
+ PGOAnalysisMap P5 = {{}, {}, {false, false, false, false}};
+ BBAddrMap E6 = {
+ {{0x66666,
+ {{0, 0x0, 0x6, {false, true, true, false, false}},
+ {1, 0x6, 0x6, {false, false, true, false, false}}}},
+ {0x666661, {{2, 0x0, 0x6, {false, false, false, false, false}}}}}};
+ PGOAnalysisMap P6 = {{},
+ {{{},
+ {{1, BranchProbability::getRaw(0x2222'2222)},
+ {2, BranchProbability::getRaw(0xcccc'cccc)}}},
+ {{}, {{2, BranchProbability::getRaw(0x8888'8888)}}},
+ {{}, {}}},
+ {false, false, true, true}};
- std::vector<BBAddrMap> Section0BBAddrMaps = {E4, E5};
+ std::vector<BBAddrMap> Section0BBAddrMaps = {E4, E5, E6};
std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};
- std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4, E5};
+ std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4, E5, E6};
- std::vector<PGOAnalysisMap> Section0PGOAnalysisMaps = {P4, P5};
+ std::vector<PGOAnalysisMap> Section0PGOAnalysisMaps = {P4, P5, P6};
std::vector<PGOAnalysisMap> Section1PGOAnalysisMaps = {P3};
std::vector<PGOAnalysisMap> Section2PGOAnalysisMaps = {P1, P2};
- std::vector<PGOAnalysisMap> AllPGOAnalysisMaps = {P1, P2, P3, P4, P5};
+ std::vector<PGOAnalysisMap> AllPGOAnalysisMaps = {P1, P2, P3, P4, P5, P6};
auto DoCheckSucceeds =
[&](StringRef YamlString, std::optional<unsigned> TextSectionIndex,
@@ -1131,10 +1231,21 @@ Sections:
EXPECT_EQ(*BBAddrMaps, ExpectedResult);
if (ExpectedPGO) {
EXPECT_EQ(BBAddrMaps->size(), PGOAnalyses.size());
+ for (const auto &PGO : PGOAnalyses) {
+ errs() << "FuncEntryCount: " << PGO.FuncEntryCount << "\n";
+ for (const auto &PGOBB : PGO.BBEntries)
+ errs() << "\tBB: " << PGOBB.BlockFreq.getFrequency() << "\n";
+ }
+ errs() << " To expected:\n";
+ for (const auto &PGO : *ExpectedPGO) {
+ errs() << "FuncEntryCount: " << PGO.FuncEntryCount << "\n";
+ for (const auto &PGOBB : PGO.BBEntries)
+ errs() << "\tBB: " << PGOBB.BlockFreq.getFrequency() << "\n";
+ }
EXPECT_EQ(PGOAnalyses, *ExpectedPGO);
for (auto &&[BB, PGO] : llvm::zip(*BBAddrMaps, PGOAnalyses)) {
if (PGO.FeatEnable.BBFreq || PGO.FeatEnable.BrProb)
- EXPECT_EQ(BB.getBBEntries().size(), PGO.BBEntries.size());
+ EXPECT_EQ(BB.getNumBBEntries(), PGO.BBEntries.size());
}
}
};
@@ -1190,15 +1301,15 @@ Sections:
// (not present) section.
SmallString<128> InvalidLinkedYamlString(CommonYamlString);
InvalidLinkedYamlString += R"(
- Link: 10
+ Link: 121
)";
{
SCOPED_TRACE("invalid linked section");
DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/5,
"unable to get the linked-to section for "
- "SHT_LLVM_BB_ADDR_MAP section with index 5: invalid section "
- "index: 10");
+ "SHT_LLVM_BB_ADDR_MAP section with index 6: invalid section "
+ "index: 121");
// Linked sections are not checked when we don't target a specific text
// section.
@@ -1216,10 +1327,10 @@ Sections:
{
SCOPED_TRACE("truncated section");
- DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
- "unable to read SHT_LLVM_BB_ADDR_MAP section with index 5: "
- "unable to decode LEB128 at offset 0x0000000a: malformed "
- "uleb128, extends past end");
+ DoCheckFails(
+ TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
+ "unable to read SHT_LLVM_BB_ADDR_MAP section with index 6: "
+ "unexpected end of data at offset 0xa while reading [0x3, 0xb)");
// Check that we can read the other section's bb-address-maps which are
// valid.
DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,
diff --git a/llvm/unittests/Object/ELFTypesTest.cpp b/llvm/unittests/Object/ELFTypesTest.cpp
index f09ab5e..f04d45c 100644
--- a/llvm/unittests/Object/ELFTypesTest.cpp
+++ b/llvm/unittests/Object/ELFTypesTest.cpp
@@ -100,34 +100,36 @@ static_assert(
decltype(BBAddrMap::BBEntry::ID)>,
"PGOAnalysisMap should use the same type for basic block ID as BBAddrMap");
-TEST(ELFTypesTest, PGOAnalysisMapFeaturesEncodingTest) {
- const std::array<PGOAnalysisMap::Features, 7> Decoded = {
- {{false, false, false},
- {true, false, false},
- {false, true, false},
- {false, false, true},
- {true, true, false},
- {false, true, true},
- {true, true, true}}};
- const std::array<uint8_t, 7> Encoded = {
- {0b000, 0b001, 0b010, 0b100, 0b011, 0b110, 0b111}};
+TEST(ELFTypesTest, BBAddrMapFeaturesEncodingTest) {
+ const std::array<BBAddrMap::Features, 9> Decoded = {
+ {{false, false, false, false},
+ {true, false, false, false},
+ {false, true, false, false},
+ {false, false, true, false},
+ {false, false, false, true},
+ {true, true, false, false},
+ {false, true, true, false},
+ {false, true, true, true},
+ {true, true, true, true}}};
+ const std::array<uint8_t, 9> Encoded = {
+ {0b0000, 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b0110, 0b1110, 0b1111}};
for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded))
EXPECT_EQ(Feat.encode(), EncodedVal);
for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded)) {
- Expected<PGOAnalysisMap::Features> FeatEnableOrError =
- PGOAnalysisMap::Features::decode(EncodedVal);
+ Expected<BBAddrMap::Features> FeatEnableOrError =
+ BBAddrMap::Features::decode(EncodedVal);
ASSERT_THAT_EXPECTED(FeatEnableOrError, Succeeded());
EXPECT_EQ(*FeatEnableOrError, Feat);
}
}
-TEST(ELFTypesTest, PGOAnalysisMapFeaturesInvalidEncodingTest) {
+TEST(ELFTypesTest, BBAddrMapFeaturesInvalidEncodingTest) {
const std::array<std::string, 2> Errors = {
- "invalid encoding for PGOAnalysisMap::Features: 0x8",
- "invalid encoding for PGOAnalysisMap::Features: 0xff"};
- const std::array<uint8_t, 2> Values = {{0b1000, 0b1111'1111}};
+ "invalid encoding for BBAddrMap::Features: 0x10",
+ "invalid encoding for BBAddrMap::Features: 0xff"};
+ const std::array<uint8_t, 2> Values = {{0b10000, 0b1111'1111}};
for (const auto &[Val, Error] : llvm::zip(Values, Errors)) {
- EXPECT_THAT_ERROR(PGOAnalysisMap::Features::decode(Val).takeError(),
+ EXPECT_THAT_ERROR(BBAddrMap::Features::decode(Val).takeError(),
FailedWithMessage(Error));
}
}