[llvm] [SHT_LLVM_BB_ADDR_MAP][llvm-readobj] Implements llvm-readobj handling for PGOAnalysisMap. (PR #79520)
Micah Weston via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 29 12:24:32 PST 2024
https://github.com/red1bluelost updated https://github.com/llvm/llvm-project/pull/79520
>From 4d78bde1910fea8061398f4011089ee71e4aa609 Mon Sep 17 00:00:00 2001
From: Micah Weston <micahsweston at gmail.com>
Date: Tue, 31 Oct 2023 21:42:27 -0400
Subject: [PATCH 1/3] Implements llvm-readobj handling without tests yet.
Adds tests for llvm-readobj PGOBBAddrMap.
Updates readobj for the redesign with PGOAnalysisMap
Updates tests after moving PGO analyses to after each function.
Updates readobj with bitfield features.
---
.../ELF/pgo-bb-addr-map-relocatable.test | 210 ++++++++++++++++++
.../llvm-readobj/ELF/pgo-bb-addr-map.test | 205 +++++++++++++++++
llvm/tools/llvm-readobj/ELFDumper.cpp | 45 +++-
llvm/tools/llvm-readobj/ObjDumper.h | 2 +-
llvm/tools/llvm-readobj/Opts.td | 1 +
llvm/tools/llvm-readobj/llvm-readobj.cpp | 6 +-
6 files changed, 458 insertions(+), 11 deletions(-)
create mode 100644 llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
create mode 100644 llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
new file mode 100644
index 000000000000000..7a8844b49d44394
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
@@ -0,0 +1,210 @@
+## This test checks how we handle the --pgo-analysis-map option on relocatable
+## object files.
+
+## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
+# UNSUPPORTED: system-windows
+
+# RUN: yaml2obj %s -o %t1.o
+# RUN: llvm-readobj %t1.o --pgo-analysis-map | FileCheck %s
+
+# CHECK: BBAddrMap [
+# CHECK-NEXT: Function {
+# CHECK-NEXT: At: 0x0
+# CHECK-NEXT: Name: <?>
+# CHECK-NEXT: EntryCount: 89
+# 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: Frequency: 90
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: Function {
+# CHECK-NEXT: At: 0x10
+# CHECK-NEXT: Name: <?>
+# 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: Frequency: 123
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ - Name: .llvm_bb_addr_map
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Link: .text
+ Entries:
+ - Version: 2
+ Feature: 0x3
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0xF
+ Metadata: 0x1
+ - Version: 2
+ Feature: 0x2
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x11
+ Metadata: 0x8
+ PGOAnalyses:
+ - FuncEntryCount: 89
+ PGOBBEntries:
+ - BBFreq: 90
+ - PGOBBEntries:
+ - BBFreq: 123
+ - Name: .rela.llvm_bb_addr_map
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ Info: .llvm_bb_addr_map
+ Relocations:
+ - Offset: 0x2
+ Symbol: .text
+ Type: R_X86_64_64
+ - Offset: 0x13
+ Symbol: .text
+ Type: R_X86_64_64
+ Addend: 16
+Symbols:
+ - Name: a
+ Section: .text
+ Value: 0x0
+ - Name: c
+ Section: .text
+ Value: 0x10
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+
+## Check that we get a warning if we expect a relocation and it is not present.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ - Name: .llvm_bb_addr_map
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Link: .text
+ Entries:
+ - Version: 2
+ Feature: 0x7
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0xF
+ Metadata: 0x1
+ PGOAnalyses:
+ - FuncEntryCount: 2
+ PGOBBEntries:
+ - BBFreq: 2
+ - Name: .rela.llvm_bb_addr_map
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Info: .llvm_bb_addr_map
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .rela.llvm_bb_addr_map
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Info: 0xFF
+
+# RUN: yaml2obj %s --docnum=3 -o %t4.o
+# RUN: llvm-readobj %t4.o --pgo-analysis-map 2>&1 | FileCheck %s --check-prefix=NO-RELOCATED-SECTION -DFILE=%t4.o
+
+# NO-RELOCATED-SECTION: warning: '[[FILE]]': failed to get SHT_LLVM_BB_ADDR_MAP section(s): SHT_RELA section with index 1: failed to get a relocated section: invalid section index: 255
+
+## Check that if we have an ET_DYN file with a .rela.dyn section, we don't get
+## a warning about a missing relocation section and can get the baddrmap data.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+Sections:
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ - Name: .llvm_bb_addr_map
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Flags: [ SHF_LINK_ORDER ]
+ Entries:
+ - Version: 2
+ Feature: 0x7
+ Address: 0xF
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0xF
+ Metadata: 0x1
+ PGOAnalyses:
+ - FuncEntryCount: 100
+ PGOBBEntries:
+ - BBFreq: 100
+ Successors: []
+
+# RUN: yaml2obj %s --docnum=4 -o %t5.o
+# RUN: llvm-readobj %t5.o --pgo-analysis-map | FileCheck %s --check-prefix=ET-DYN-NO-WARNING -DFILE=%t5.o
+
+# ET-DYN-NO-WARNING: BBAddrMap [
+# ET-DYN-NO-WARNING-NEXT: Function {
+# ET-DYN-NO-WARNING-NEXT: At: 0xF
+# ET-DYN-NO-WARNING-NEXT: Name: <?>
+# ET-DYN-NO-WARNING-NEXT: EntryCount: 100
+# ET-DYN-NO-WARNING-NEXT: BB entries [
+# ET-DYN-NO-WARNING-NEXT: {
+# ET-DYN-NO-WARNING-NEXT: ID: 0
+# ET-DYN-NO-WARNING-NEXT: Offset: 0x0
+# ET-DYN-NO-WARNING-NEXT: Size: 0xF
+# ET-DYN-NO-WARNING-NEXT: HasReturn: Yes
+# ET-DYN-NO-WARNING-NEXT: HasTailCall: No
+# ET-DYN-NO-WARNING-NEXT: IsEHPad: No
+# ET-DYN-NO-WARNING-NEXT: CanFallThrough: No
+# ET-DYN-NO-WARNING-NEXT: HasIndirectBranch: No
+# ET-DYN-NO-WARNING-NEXT: Frequency: 100
+# ET-DYN-NO-WARNING-NEXT: Successors [
+# ET-DYN-NO-WARNING-NEXT: ]
+# ET-DYN-NO-WARNING-NEXT: }
+# ET-DYN-NO-WARNING-NEXT: ]
+# ET-DYN-NO-WARNING-NEXT: }
+# ET-DYN-NO-WARNING-NEXT: ]
diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
new file mode 100644
index 000000000000000..05ae4730108159f
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
@@ -0,0 +1,205 @@
+## This test checks how we handle the --pgo-analysis-map option.
+
+## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
+# UNSUPPORTED: system-windows
+
+## Check 64-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
+# RUN: llvm-readobj %t1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x64.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+
+## Check 64-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.v1.x64.o
+# RUN: llvm-readobj %t1.v1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
+
+## Check 32-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
+# RUN: llvm-readobj %t1.x32.o --pgo-analysis-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x32.o --pgo-analysis-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 --pgo-analysis-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -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
+# RUN: llvm-readobj %t3.o --pgo-analysis-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
+
+# CHECK: BBAddrMap [
+# CHECK-NEXT: Function {
+# 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: EntryCount: 100
+# 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: Frequency: 100
+# CHECK-NEXT: Successors [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 2
+# CHECK-NEXT: Probability: 0xFFFFFFFF
+# 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: Frequency: 100
+# CHECK-NEXT: Successors [
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: Function {
+# CHECK-NEXT: At: 0x22222
+# CHECK-NEXT: Name: foo
+# CHECK-NEXT: EntryCount: 8888
+# 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: Frequency: 9000
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# GNU: GNUStyle::printBBAddrMaps not implemented
+
+# TRUNCATED: BBAddrMap [
+# TRUNCATED-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end
+# TRUNCATED-NEXT: ]
+## Check that the other valid section is properly dumped.
+# TRUNCATED-NEXT: BBAddrMap [
+# TRUNCATED-NEXT: Function {
+# TRUNCATED-NEXT: At: 0x33333
+# TRUNCATED-NEXT: Name: bar
+# TRUNCATED-NEXT: EntryCount: 89
+# 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: ]
+
+# INVALIDMD: BBAddrMap [
+# INVALIDMD-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: invalid encoding for BBEntry::Metadata: 0xf000002
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS[[BITS]]
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [SHF_ALLOC]
+ - Name: .text.bar
+ Type: SHT_PROGBITS
+ Flags: [SHF_ALLOC]
+ - Name: .llvm_bb_addr_map
+ Type: SHT_LLVM_BB_ADDR_MAP
+ ShSize: [[SIZE=<none>]]
+ Link: .text
+ Entries:
+ - Version: 2
+ Feature: 0x7
+ Address: [[ADDR=0x11111]]
+ BBEntries:
+ - ID: 0
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: [[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
+ PGOAnalyses:
+ - FuncEntryCount: 100
+ PGOBBEntries:
+ - BBFreq: 100
+ Successors:
+ - ID: 2
+ BrProb: 0xFFFFFFFF
+ - BBFreq: 100
+ Successors: []
+ - FuncEntryCount: 8888
+ PGOBBEntries:
+ - BBFreq: 9000
+ - Name: dummy_section
+ Type: SHT_PROGBITS
+ Size: 16
+ - Name: '.llvm_bb_addr_map (1)'
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Link: .text.bar
+ Entries:
+ - Version: 2
+ Feature: 0x1
+ Address: 0x33333
+ BBEntries:
+ - ID: 6
+ AddressOffset: 0x9
+ Size: 0xa
+ Metadata: 0x1b
+ - ID: 7
+ AddressOffset: 0xc
+ Size: 0xd
+ Metadata: 0xe
+ PGOAnalyses:
+ - FuncEntryCount: 89
+Symbols:
+ - Name: foo
+ Section: .text
+ Type: STT_FUNC
+ Value: 0x22222
+ - Name: bar
+ Section: .text.bar
+ Type: STT_FUNC
+ Value: 0x33333
+
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index f369a63add1149b..3b32d9805277759 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -593,7 +593,7 @@ template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
void printVersionDependencySection(const Elf_Shdr *Sec) override;
void printCGProfile() override;
- void printBBAddrMaps() override;
+ void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
void printAddrsig() override;
void printNotes() override;
void printELFLinkerOptions() override;
@@ -704,7 +704,7 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
void printVersionDependencySection(const Elf_Shdr *Sec) override;
void printCGProfile() override;
- void printBBAddrMaps() override;
+ void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
void printAddrsig() override;
void printNotes() override;
void printELFLinkerOptions() override;
@@ -739,6 +739,8 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
void printMipsABIFlags() override;
virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;
+ template<typename AddrMap> void printAddrMaps();
+
protected:
virtual std::string getGroupSectionHeaderName() const;
void printSymbolOtherField(const Elf_Sym &Symbol) const;
@@ -5070,7 +5072,8 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
OS << "GNUStyle::printCGProfile not implemented\n";
}
-template <class ELFT> void GNUELFDumper<ELFT>::printBBAddrMaps() {
+template <class ELFT>
+void GNUELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
OS << "GNUStyle::printBBAddrMaps not implemented\n";
}
@@ -7541,7 +7544,8 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
}
}
-template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
+template <class ELFT>
+void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
using Elf_Shdr = typename ELFT::Shdr;
auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
@@ -7567,14 +7571,16 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
this->describe(*Sec));
continue;
}
- Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
- this->Obj.decodeBBAddrMap(*Sec, RelocSec);
+ std::vector<PGOAnalysisMap> PGOAnalysis;
+ Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = this->Obj.decodeBBAddrMap(
+ *Sec, RelocSec, IncludePGOAnalysis ? &PGOAnalysis : nullptr);
if (!BBAddrMapOrErr) {
this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
": " + toString(BBAddrMapOrErr.takeError()));
continue;
}
- for (const BBAddrMap &AM : *BBAddrMapOrErr) {
+ for (const auto &[Idx, AM] : llvm::enumerate(*BBAddrMapOrErr)) {
+ const auto *PAM = IncludePGOAnalysis ? &PGOAnalysis[Idx] : nullptr;
DictScope D(W, "Function");
W.printHex("At", AM.Addr);
SmallVector<uint32_t> FuncSymIndex =
@@ -7587,9 +7593,14 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
else
FuncName = this->getStaticSymbolName(FuncSymIndex.front());
W.printString("Name", FuncName);
+ if (IncludePGOAnalysis && PAM->FeatEnable.FuncEntryCount)
+ W.printNumber("EntryCount", PAM->FuncEntryCount);
+ bool IncludePGOBBData =
+ IncludePGOAnalysis && PAM->BBEntries.size() == AM.BBEntries.size();
ListScope L(W, "BB entries");
- for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
+ for (const auto &[BIdx, BBE] : llvm::enumerate(AM.BBEntries)) {
+ const auto *PBBE = IncludePGOBBData ? &PAM->BBEntries[BIdx] : nullptr;
DictScope L(W);
W.printNumber("ID", BBE.ID);
W.printHex("Offset", BBE.Offset);
@@ -7599,6 +7610,24 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
W.printBoolean("IsEHPad", BBE.isEHPad());
W.printBoolean("CanFallThrough", BBE.canFallThrough());
W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
+
+ /// FIXME: currently we just emit the raw frequency, it may be better to
+ /// provide an option to scale it by the first entry frequence using
+ /// BlockFrequency::Scaled64 number
+ if (IncludePGOBBData && PAM->FeatEnable.BBFreq)
+ W.printNumber("Frequency", PBBE->BlockFreq.getFrequency());
+
+ if (IncludePGOBBData && PAM->FeatEnable.BrProb) {
+ ListScope L(W, "Successors");
+ for (const auto &Succ : PBBE->Successors) {
+ DictScope L(W);
+ W.printNumber("ID", Succ.ID);
+ /// FIXME: currently we just emit the raw numerator of the probably,
+ /// it may be better to provide an option to emit it as a percentage
+ /// or other prettied representation
+ W.printHex("Probability", Succ.Prob.getNumerator());
+ }
+ }
}
}
}
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 1d679453581bc84..082aba80841c6b6 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -129,7 +129,7 @@ class ObjDumper {
virtual void printGroupSections() {}
virtual void printHashHistograms() {}
virtual void printCGProfile() {}
- virtual void printBBAddrMaps() {}
+ virtual void printBBAddrMaps(bool IncludePGOAnalysis = false) {}
virtual void printAddrsig() {}
virtual void printNotes() {}
virtual void printELFLinkerOptions() {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index e2d93c6ec229e9f..a981fac2f2f3650 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -29,6 +29,7 @@ def extra_sym_info : FF<"extra-sym-info", "Display extra information when showin
def file_header : FF<"file-header", "Display file header">;
def headers : FF<"headers", "Equivalent to setting: --file-header, --program-headers, --section-headers">;
defm hex_dump : Eq<"hex-dump", "Display the specified section(s) as hexadecimal bytes">, MetaVarName<"<name or index>">;
+def pgo_analysis_map : FF<"pgo-analysis-map", "Display the BB address map section with PGO data included">;
def pretty_print : FF<"pretty-print", "Pretty print JSON output">;
def relocs : FF<"relocs", "Display the relocation entries in the file">;
def section_data : FF<"section-data", "Display section data for each section shown. This option has no effect for GNU style output">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index f9d605d35244bf3..4dcab4ce5c9f74d 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -95,6 +95,7 @@ static bool Addrsig;
static bool All;
static bool ArchSpecificInfo;
static bool BBAddrMap;
+static bool PGOAnalysisMap;
bool ExpandRelocs;
static bool CGProfile;
bool Demangle;
@@ -211,6 +212,7 @@ static void parseOptions(const opt::InputArgList &Args) {
opts::All = Args.hasArg(OPT_all);
opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);
opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);
+ opts::PGOAnalysisMap = Args.hasArg(OPT_pgo_analysis_map);
opts::CGProfile = Args.hasArg(OPT_cg_profile);
opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);
@@ -463,8 +465,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printHashHistograms();
if (opts::CGProfile)
Dumper->printCGProfile();
- if (opts::BBAddrMap)
- Dumper->printBBAddrMaps();
+ if (opts::BBAddrMap || opts::PGOAnalysisMap)
+ Dumper->printBBAddrMaps(opts::PGOAnalysisMap);
if (opts::Addrsig)
Dumper->printAddrsig();
if (opts::Notes)
>From c036ea8331dce425d05515ed06073b520ba7e3ce Mon Sep 17 00:00:00 2001
From: Micah Weston <micahsweston at gmail.com>
Date: Thu, 25 Jan 2024 18:20:38 -0500
Subject: [PATCH 2/3] Updates to pgo-analysis-map and always prints.
---
...test => bb-addr-map-pgo-analysis-map.test} | 60 +++--
.../ELF/pgo-bb-addr-map-relocatable.test | 210 ------------------
llvm/tools/llvm-readobj/ELFDumper.cpp | 96 ++++----
llvm/tools/llvm-readobj/ObjDumper.h | 2 +-
llvm/tools/llvm-readobj/Opts.td | 1 -
llvm/tools/llvm-readobj/llvm-readobj.cpp | 6 +-
6 files changed, 92 insertions(+), 283 deletions(-)
rename llvm/test/tools/llvm-readobj/ELF/{pgo-bb-addr-map.test => bb-addr-map-pgo-analysis-map.test} (75%)
delete mode 100644 llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
similarity index 75%
rename from llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
rename to llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
index 05ae4730108159f..fad2cca1990a49b 100644
--- a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
@@ -1,36 +1,35 @@
-## This test checks how we handle the --pgo-analysis-map option.
+## This test checks how we handle PGO Analysis Map in --bb-addr-map.
## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
# UNSUPPORTED: system-windows
## Check 64-bit:
# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
-# RUN: llvm-readobj %t1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
-# RUN: llvm-readelf %t1.x64.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
+# RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU
## Check 64-bit:
# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.v1.x64.o
-# RUN: llvm-readobj %t1.v1.x64.o --pgo-analysis-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
+# RUN: llvm-readobj %t1.v1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
## Check 32-bit:
# RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
-# RUN: llvm-readobj %t1.x32.o --pgo-analysis-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
-# RUN: llvm-readelf %t1.x32.o --pgo-analysis-map | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
+# 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 --pgo-analysis-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -DFILE=%t2.o --check-prefix=TRUNCATED
+# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000006 -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
-# RUN: llvm-readobj %t3.o --pgo-analysis-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
+# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
# CHECK: BBAddrMap [
# CHECK-NEXT: Function {
# 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: EntryCount: 100
# CHECK-NEXT: BB entries [
# CHECK-NEXT: {
# CHECK-NEXT: ID: 0
@@ -41,13 +40,6 @@
# CHECK-NEXT: IsEHPad: No
# CHECK-NEXT: CanFallThrough: No
# CHECK-NEXT: HasIndirectBranch: No
-# CHECK-NEXT: Frequency: 100
-# CHECK-NEXT: Successors [
-# CHECK-NEXT: {
-# CHECK-NEXT: ID: 2
-# CHECK-NEXT: Probability: 0xFFFFFFFF
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: {
# CHECK-NEXT: ID: 2
@@ -58,16 +50,31 @@
# CHECK-NEXT: IsEHPad: Yes
# CHECK-NEXT: CanFallThrough: No
# CHECK-NEXT: HasIndirectBranch: Yes
-# CHECK-NEXT: Frequency: 100
-# CHECK-NEXT: Successors [
-# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: ]
+# CHECK-NEXT: PGO analyses {
+# CHECK-NEXT: FuncEntryCount: 100
+# CHECK-NEXT: PGO BB entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: Frequency: 100
+# CHECK-NEXT: Successors [
+# CHECK-NEXT: {
+# CHECK-NEXT: ID: 2
+# CHECK-NEXT: Probability: 0xFFFFFFFF
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: {
+# CHECK-NEXT: Frequency: 100
+# CHECK-NEXT: Successors [
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
# CHECK-NEXT: }
# CHECK-NEXT: Function {
# CHECK-NEXT: At: 0x22222
# CHECK-NEXT: Name: foo
-# CHECK-NEXT: EntryCount: 8888
# CHECK-NEXT: BB entries [
# CHECK-NEXT: {
# CHECK-NEXT: ID: 4
@@ -78,9 +85,16 @@
# CHECK-NEXT: IsEHPad: No
# CHECK-NEXT: CanFallThrough: Yes
# CHECK-NEXT: HasIndirectBranch: No
-# CHECK-NEXT: Frequency: 9000
# CHECK-NEXT: }
# CHECK-NEXT: ]
+# CHECK-NEXT: PGO analyses {
+# CHECK-NEXT: FuncEntryCount: 8888
+# CHECK-NEXT: PGO BB entries [
+# CHECK-NEXT: {
+# CHECK-NEXT: Frequency: 9000
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
# CHECK-NEXT: }
# CHECK-NEXT: ]
@@ -94,7 +108,6 @@
# TRUNCATED-NEXT: Function {
# TRUNCATED-NEXT: At: 0x33333
# TRUNCATED-NEXT: Name: bar
-# TRUNCATED-NEXT: EntryCount: 89
# TRUNCATED-NEXT: BB entries [
# TRUNCATED-NEXT: {
# TRUNCATED-NEXT: ID: 6
@@ -117,6 +130,9 @@
# TRUNCATED-NEXT: HasIndirectBranch: No
# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: ]
+# TRUNCATED-NEXT: PGO analyses {
+# TRUNCATED-NEXT: FuncEntryCount: 89
+# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: ]
diff --git a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
deleted file mode 100644
index 7a8844b49d44394..000000000000000
--- a/llvm/test/tools/llvm-readobj/ELF/pgo-bb-addr-map-relocatable.test
+++ /dev/null
@@ -1,210 +0,0 @@
-## This test checks how we handle the --pgo-analysis-map option on relocatable
-## object files.
-
-## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
-# UNSUPPORTED: system-windows
-
-# RUN: yaml2obj %s -o %t1.o
-# RUN: llvm-readobj %t1.o --pgo-analysis-map | FileCheck %s
-
-# CHECK: BBAddrMap [
-# CHECK-NEXT: Function {
-# CHECK-NEXT: At: 0x0
-# CHECK-NEXT: Name: <?>
-# CHECK-NEXT: EntryCount: 89
-# 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: Frequency: 90
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
-# CHECK-NEXT: }
-# CHECK-NEXT: Function {
-# CHECK-NEXT: At: 0x10
-# CHECK-NEXT: Name: <?>
-# 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: Frequency: 123
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
-# CHECK-NEXT: }
-# CHECK-NEXT: ]
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- - Name: .llvm_bb_addr_map
- Type: SHT_LLVM_BB_ADDR_MAP
- Link: .text
- Entries:
- - Version: 2
- Feature: 0x3
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0xF
- Metadata: 0x1
- - Version: 2
- Feature: 0x2
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0x11
- Metadata: 0x8
- PGOAnalyses:
- - FuncEntryCount: 89
- PGOBBEntries:
- - BBFreq: 90
- - PGOBBEntries:
- - BBFreq: 123
- - Name: .rela.llvm_bb_addr_map
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Link: .symtab
- Info: .llvm_bb_addr_map
- Relocations:
- - Offset: 0x2
- Symbol: .text
- Type: R_X86_64_64
- - Offset: 0x13
- Symbol: .text
- Type: R_X86_64_64
- Addend: 16
-Symbols:
- - Name: a
- Section: .text
- Value: 0x0
- - Name: c
- Section: .text
- Value: 0x10
- - Name: .text
- Type: STT_SECTION
- Section: .text
-
-## Check that we get a warning if we expect a relocation and it is not present.
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- - Name: .llvm_bb_addr_map
- Type: SHT_LLVM_BB_ADDR_MAP
- Link: .text
- Entries:
- - Version: 2
- Feature: 0x7
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0xF
- Metadata: 0x1
- PGOAnalyses:
- - FuncEntryCount: 2
- PGOBBEntries:
- - BBFreq: 2
- - Name: .rela.llvm_bb_addr_map
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Info: .llvm_bb_addr_map
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .rela.llvm_bb_addr_map
- Type: SHT_RELA
- Flags: [ SHF_INFO_LINK ]
- Info: 0xFF
-
-# RUN: yaml2obj %s --docnum=3 -o %t4.o
-# RUN: llvm-readobj %t4.o --pgo-analysis-map 2>&1 | FileCheck %s --check-prefix=NO-RELOCATED-SECTION -DFILE=%t4.o
-
-# NO-RELOCATED-SECTION: warning: '[[FILE]]': failed to get SHT_LLVM_BB_ADDR_MAP section(s): SHT_RELA section with index 1: failed to get a relocated section: invalid section index: 255
-
-## Check that if we have an ET_DYN file with a .rela.dyn section, we don't get
-## a warning about a missing relocation section and can get the baddrmap data.
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
- Machine: EM_X86_64
-Sections:
- - Name: .rela.dyn
- Type: SHT_RELA
- Flags: [ SHF_ALLOC ]
- - Name: .llvm_bb_addr_map
- Type: SHT_LLVM_BB_ADDR_MAP
- Flags: [ SHF_LINK_ORDER ]
- Entries:
- - Version: 2
- Feature: 0x7
- Address: 0xF
- BBEntries:
- - ID: 0
- AddressOffset: 0x0
- Size: 0xF
- Metadata: 0x1
- PGOAnalyses:
- - FuncEntryCount: 100
- PGOBBEntries:
- - BBFreq: 100
- Successors: []
-
-# RUN: yaml2obj %s --docnum=4 -o %t5.o
-# RUN: llvm-readobj %t5.o --pgo-analysis-map | FileCheck %s --check-prefix=ET-DYN-NO-WARNING -DFILE=%t5.o
-
-# ET-DYN-NO-WARNING: BBAddrMap [
-# ET-DYN-NO-WARNING-NEXT: Function {
-# ET-DYN-NO-WARNING-NEXT: At: 0xF
-# ET-DYN-NO-WARNING-NEXT: Name: <?>
-# ET-DYN-NO-WARNING-NEXT: EntryCount: 100
-# ET-DYN-NO-WARNING-NEXT: BB entries [
-# ET-DYN-NO-WARNING-NEXT: {
-# ET-DYN-NO-WARNING-NEXT: ID: 0
-# ET-DYN-NO-WARNING-NEXT: Offset: 0x0
-# ET-DYN-NO-WARNING-NEXT: Size: 0xF
-# ET-DYN-NO-WARNING-NEXT: HasReturn: Yes
-# ET-DYN-NO-WARNING-NEXT: HasTailCall: No
-# ET-DYN-NO-WARNING-NEXT: IsEHPad: No
-# ET-DYN-NO-WARNING-NEXT: CanFallThrough: No
-# ET-DYN-NO-WARNING-NEXT: HasIndirectBranch: No
-# ET-DYN-NO-WARNING-NEXT: Frequency: 100
-# ET-DYN-NO-WARNING-NEXT: Successors [
-# ET-DYN-NO-WARNING-NEXT: ]
-# ET-DYN-NO-WARNING-NEXT: }
-# ET-DYN-NO-WARNING-NEXT: ]
-# ET-DYN-NO-WARNING-NEXT: }
-# ET-DYN-NO-WARNING-NEXT: ]
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 3b32d9805277759..4bf4640f1a4ca39 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -593,7 +593,7 @@ template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
void printVersionDependencySection(const Elf_Shdr *Sec) override;
void printCGProfile() override;
- void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
+ void printBBAddrMaps() override;
void printAddrsig() override;
void printNotes() override;
void printELFLinkerOptions() override;
@@ -704,7 +704,7 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
void printVersionDependencySection(const Elf_Shdr *Sec) override;
void printCGProfile() override;
- void printBBAddrMaps(bool IncludePGOAnalysis = false) override;
+ void printBBAddrMaps() override;
void printAddrsig() override;
void printNotes() override;
void printELFLinkerOptions() override;
@@ -739,8 +739,6 @@ template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
void printMipsABIFlags() override;
virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;
- template<typename AddrMap> void printAddrMaps();
-
protected:
virtual std::string getGroupSectionHeaderName() const;
void printSymbolOtherField(const Elf_Sym &Symbol) const;
@@ -5072,8 +5070,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
OS << "GNUStyle::printCGProfile not implemented\n";
}
-template <class ELFT>
-void GNUELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
+template <class ELFT> void GNUELFDumper<ELFT>::printBBAddrMaps() {
OS << "GNUStyle::printBBAddrMaps not implemented\n";
}
@@ -7544,8 +7541,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
}
}
-template <class ELFT>
-void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
+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 {
@@ -7571,16 +7567,15 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
this->describe(*Sec));
continue;
}
- std::vector<PGOAnalysisMap> PGOAnalysis;
- Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = this->Obj.decodeBBAddrMap(
- *Sec, RelocSec, IncludePGOAnalysis ? &PGOAnalysis : nullptr);
+ std::vector<PGOAnalysisMap> PGOAnalyses;
+ Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
+ this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);
if (!BBAddrMapOrErr) {
this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
": " + toString(BBAddrMapOrErr.takeError()));
continue;
}
- for (const auto &[Idx, AM] : llvm::enumerate(*BBAddrMapOrErr)) {
- const auto *PAM = IncludePGOAnalysis ? &PGOAnalysis[Idx] : nullptr;
+ for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
DictScope D(W, "Function");
W.printHex("At", AM.Addr);
SmallVector<uint32_t> FuncSymIndex =
@@ -7593,39 +7588,50 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool IncludePGOAnalysis) {
else
FuncName = this->getStaticSymbolName(FuncSymIndex.front());
W.printString("Name", FuncName);
- if (IncludePGOAnalysis && PAM->FeatEnable.FuncEntryCount)
- W.printNumber("EntryCount", PAM->FuncEntryCount);
-
- bool IncludePGOBBData =
- IncludePGOAnalysis && PAM->BBEntries.size() == AM.BBEntries.size();
- ListScope L(W, "BB entries");
- for (const auto &[BIdx, BBE] : llvm::enumerate(AM.BBEntries)) {
- const auto *PBBE = IncludePGOBBData ? &PAM->BBEntries[BIdx] : nullptr;
- 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());
-
- /// FIXME: currently we just emit the raw frequency, it may be better to
- /// provide an option to scale it by the first entry frequence using
- /// BlockFrequency::Scaled64 number
- if (IncludePGOBBData && PAM->FeatEnable.BBFreq)
- W.printNumber("Frequency", PBBE->BlockFreq.getFrequency());
-
- if (IncludePGOBBData && PAM->FeatEnable.BrProb) {
- ListScope L(W, "Successors");
- for (const auto &Succ : PBBE->Successors) {
+
+ {
+ 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());
+ }
+ }
+
+ if (PAM.FeatEnable.anyEnabled()) {
+ DictScope PD(W, "PGO analyses");
+
+ if (PAM.FeatEnable.FuncEntryCount)
+ W.printNumber("FuncEntryCount", PAM.FuncEntryCount);
+
+ if (PAM.FeatEnable.BBFreq || PAM.FeatEnable.BrProb) {
+ ListScope L(W, "PGO BB entries");
+ for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {
DictScope L(W);
- W.printNumber("ID", Succ.ID);
- /// FIXME: currently we just emit the raw numerator of the probably,
- /// it may be better to provide an option to emit it as a percentage
- /// or other prettied representation
- W.printHex("Probability", Succ.Prob.getNumerator());
+
+ /// FIXME: currently we just emit the raw frequency, it may be
+ /// better to provide an option to scale it by the first entry
+ /// frequence using BlockFrequency::Scaled64 number
+ if (PAM.FeatEnable.BBFreq)
+ W.printNumber("Frequency", PBBE.BlockFreq.getFrequency());
+
+ if (PAM.FeatEnable.BrProb) {
+ ListScope L(W, "Successors");
+ for (const auto &Succ : PBBE.Successors) {
+ DictScope L(W);
+ W.printNumber("ID", Succ.ID);
+ /// FIXME: currently we just emit the raw numerator of the
+ /// probably, it may be better to provide an option to emit it
+ /// as a percentage or other prettied representation
+ W.printHex("Probability", Succ.Prob.getNumerator());
+ }
+ }
}
}
}
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 082aba80841c6b6..1d679453581bc84 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -129,7 +129,7 @@ class ObjDumper {
virtual void printGroupSections() {}
virtual void printHashHistograms() {}
virtual void printCGProfile() {}
- virtual void printBBAddrMaps(bool IncludePGOAnalysis = false) {}
+ virtual void printBBAddrMaps() {}
virtual void printAddrsig() {}
virtual void printNotes() {}
virtual void printELFLinkerOptions() {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index a981fac2f2f3650..e2d93c6ec229e9f 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -29,7 +29,6 @@ def extra_sym_info : FF<"extra-sym-info", "Display extra information when showin
def file_header : FF<"file-header", "Display file header">;
def headers : FF<"headers", "Equivalent to setting: --file-header, --program-headers, --section-headers">;
defm hex_dump : Eq<"hex-dump", "Display the specified section(s) as hexadecimal bytes">, MetaVarName<"<name or index>">;
-def pgo_analysis_map : FF<"pgo-analysis-map", "Display the BB address map section with PGO data included">;
def pretty_print : FF<"pretty-print", "Pretty print JSON output">;
def relocs : FF<"relocs", "Display the relocation entries in the file">;
def section_data : FF<"section-data", "Display section data for each section shown. This option has no effect for GNU style output">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 4dcab4ce5c9f74d..f9d605d35244bf3 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -95,7 +95,6 @@ static bool Addrsig;
static bool All;
static bool ArchSpecificInfo;
static bool BBAddrMap;
-static bool PGOAnalysisMap;
bool ExpandRelocs;
static bool CGProfile;
bool Demangle;
@@ -212,7 +211,6 @@ static void parseOptions(const opt::InputArgList &Args) {
opts::All = Args.hasArg(OPT_all);
opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);
opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);
- opts::PGOAnalysisMap = Args.hasArg(OPT_pgo_analysis_map);
opts::CGProfile = Args.hasArg(OPT_cg_profile);
opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);
@@ -465,8 +463,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printHashHistograms();
if (opts::CGProfile)
Dumper->printCGProfile();
- if (opts::BBAddrMap || opts::PGOAnalysisMap)
- Dumper->printBBAddrMaps(opts::PGOAnalysisMap);
+ if (opts::BBAddrMap)
+ Dumper->printBBAddrMaps();
if (opts::Addrsig)
Dumper->printAddrsig();
if (opts::Notes)
>From 71a258ccd0000d070bf1c18d554963b733dbd0ba Mon Sep 17 00:00:00 2001
From: Micah Weston <micahsweston at gmail.com>
Date: Mon, 29 Jan 2024 15:24:18 -0500
Subject: [PATCH 3/3] Updates test based on feedback.
---
.../ELF/bb-addr-map-pgo-analysis-map.test | 31 +++++++------------
1 file changed, 12 insertions(+), 19 deletions(-)
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 fad2cca1990a49b..91b3d7e3902e324 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
@@ -1,29 +1,23 @@
-## This test checks how we handle PGO Analysis Map in --bb-addr-map.
-
-## Fails on windows (https://github.com/llvm/llvm-project/issues/60013).
-# UNSUPPORTED: system-windows
+## This test checks how llvm-readobj prints the PGO Analysis Map with the
+## --bb-addr-map option.
## Check 64-bit:
-# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
+# RUN: yaml2obj %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
# RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
# RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU
-## Check 64-bit:
-# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.v1.x64.o
-# RUN: llvm-readobj %t1.v1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
-
## Check 32-bit:
-# RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
+# RUN: yaml2obj %s -DBITS=32 -o %t1.x32.o
# RUN: llvm-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
# 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 %s -DBITS=32 -DSIZE=24 -o %t2.o
+# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000018 -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
-# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDMD
+## Check that missing features can be handled.
+# RUN: yaml2obj %s -DBITS=32 -DFEATURE=0x2 -o %t3.o
+# RUN: llvm-readobj %t3.o --bb-addr-map 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALIDFT
# CHECK: BBAddrMap [
# CHECK-NEXT: Function {
@@ -136,8 +130,7 @@
# TRUNCATED-NEXT: }
# TRUNCATED-NEXT: ]
-# INVALIDMD: BBAddrMap [
-# INVALIDMD-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: invalid encoding for BBEntry::Metadata: 0xf000002
+# INVALIDFT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 5: unable to decode LEB128 at offset 0x00000010: malformed uleb128, extends past end
--- !ELF
FileHeader:
@@ -163,7 +156,7 @@ Sections:
- ID: 0
AddressOffset: 0x0
Size: 0x1
- Metadata: [[METADATA=0x2]]
+ Metadata: 0x2
- ID: 2
AddressOffset: 0x3
Size: 0x4
@@ -196,7 +189,7 @@ Sections:
Link: .text.bar
Entries:
- Version: 2
- Feature: 0x1
+ Feature: [[FEATURE=0x1]]
Address: 0x33333
BBEntries:
- ID: 6
More information about the llvm-commits
mailing list