[llvm] [SHT_LLVM_BB_ADDR_MAP] Add a new PGOAnalysisMap feature to emit dynamic instruction count (PR #119303)
Lei Wang via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 9 17:08:49 PST 2024
https://github.com/wlei-llvm created https://github.com/llvm/llvm-project/pull/119303
Add a new `PGOAnalysisMap` feature(`-pgo-analysis-map=dyn-inst-count`) to emit estimated dynamic instruction count. The dynamic instruction count is calculated as the sum of all instruction's sample count(extracted from PGO MBFI) within the function, extending as a new feature option is to save binary size instead of paring from BBFreq/BBProb. This feature would serve as a performance proxy for PGO optimized binary, that can be leveraged for code analysis tool, such as detect unexpectedly high instruction counts, pinpoint functions with unusually high dynamic instruction, compare instruction counts across different compilation pipelines, etc.
>From 803a00d00b5a8efef797b31d7561e25c1e4c1035 Mon Sep 17 00:00:00 2001
From: wlei <wlei at fb.com>
Date: Mon, 9 Dec 2024 11:19:01 -0800
Subject: [PATCH] [SHT_LLVM_BB_ADDR_MAP] Extend PGOAnalysisMap to emit dynamic
instruction count
---
llvm/include/llvm/Object/ELFTypes.h | 21 +++++---
llvm/include/llvm/ObjectYAML/ELFYAML.h | 1 +
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 26 ++++++++--
llvm/lib/Object/ELF.cpp | 10 +++-
llvm/lib/ObjectYAML/ELFEmitter.cpp | 3 ++
llvm/lib/ObjectYAML/ELFYAML.cpp | 1 +
.../basic-block-address-map-pgo-features.ll | 10 ++--
.../llvm-objdump/X86/elf-pgoanalysismap.yaml | 51 +++++++++++++++++--
.../ELF/bb-addr-map-pgo-analysis-map.test | 11 ++--
.../ELF/bb-addr-map-pgo-analysis-map.yaml | 7 +--
llvm/tools/llvm-objdump/llvm-objdump.cpp | 12 +++--
llvm/tools/llvm-readobj/ELFDumper.cpp | 3 ++
llvm/tools/obj2yaml/elf2yaml.cpp | 3 ++
llvm/unittests/Object/ELFObjectFileTest.cpp | 19 ++++---
llvm/unittests/Object/ELFTypesTest.cpp | 30 ++++++-----
15 files changed, 155 insertions(+), 53 deletions(-)
diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h
index 87e4dbe4480910..5a80a05431d823 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -831,8 +831,11 @@ struct BBAddrMap {
bool BrProb : 1;
bool MultiBBRange : 1;
bool OmitBBEntries : 1;
+ bool DynamicInstCount : 1;
- bool hasPGOAnalysis() const { return FuncEntryCount || BBFreq || BrProb; }
+ bool hasPGOAnalysis() const {
+ return FuncEntryCount || BBFreq || BrProb || DynamicInstCount;
+ }
bool hasPGOAnalysisBBData() const { return BBFreq || BrProb; }
@@ -842,7 +845,8 @@ struct BBAddrMap {
(static_cast<uint8_t>(BBFreq) << 1) |
(static_cast<uint8_t>(BrProb) << 2) |
(static_cast<uint8_t>(MultiBBRange) << 3) |
- (static_cast<uint8_t>(OmitBBEntries) << 4);
+ (static_cast<uint8_t>(OmitBBEntries) << 4) |
+ (static_cast<uint8_t>(DynamicInstCount) << 5);
}
// Decodes from minimum bit width representation and validates no
@@ -851,7 +855,7 @@ struct BBAddrMap {
Features Feat{
static_cast<bool>(Val & (1 << 0)), static_cast<bool>(Val & (1 << 1)),
static_cast<bool>(Val & (1 << 2)), static_cast<bool>(Val & (1 << 3)),
- static_cast<bool>(Val & (1 << 4))};
+ static_cast<bool>(Val & (1 << 4)), static_cast<bool>(Val & (1 << 5))};
if (Feat.encode() != Val)
return createStringError(
std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
@@ -861,9 +865,10 @@ struct BBAddrMap {
bool operator==(const Features &Other) const {
return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange,
- OmitBBEntries) ==
+ OmitBBEntries, DynamicInstCount) ==
std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
- Other.MultiBBRange, Other.OmitBBEntries);
+ Other.MultiBBRange, Other.OmitBBEntries,
+ Other.DynamicInstCount);
}
};
@@ -1016,14 +1021,16 @@ struct PGOAnalysisMap {
};
uint64_t FuncEntryCount; // Prof count from IR function
+ uint64_t DynamicInstCount; // Dynamic instruction count
std::vector<PGOBBEntry> BBEntries; // Extended basic block entries
// Flags to indicate if each PGO related info was enabled in this function
BBAddrMap::Features FeatEnable;
bool operator==(const PGOAnalysisMap &Other) const {
- return std::tie(FuncEntryCount, BBEntries, FeatEnable) ==
- std::tie(Other.FuncEntryCount, Other.BBEntries, Other.FeatEnable);
+ return std::tie(FuncEntryCount, DynamicInstCount, BBEntries, FeatEnable) ==
+ std::tie(Other.FuncEntryCount, Other.DynamicInstCount,
+ Other.BBEntries, Other.FeatEnable);
}
};
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index dfdfa055d65fa6..17e9e56f8542eb 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -192,6 +192,7 @@ struct PGOAnalysisMapEntry {
std::optional<std::vector<SuccessorEntry>> Successors;
};
std::optional<uint64_t> FuncEntryCount;
+ std::optional<uint64_t> DynamicInstCount;
std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
};
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 3072edc5088e2a..a3f46d3edd5099 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -143,6 +143,7 @@ using namespace llvm;
enum class PGOMapFeaturesEnum {
None,
FuncEntryCount,
+ DynInstCount,
BBFreq,
BrProb,
All,
@@ -153,6 +154,8 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
clEnumValN(PGOMapFeaturesEnum::None, "none", "Disable all options"),
clEnumValN(PGOMapFeaturesEnum::FuncEntryCount, "func-entry-count",
"Function Entry Count"),
+ clEnumValN(PGOMapFeaturesEnum::DynInstCount, "dyn-inst-count",
+ "Dynamic instruction count"),
clEnumValN(PGOMapFeaturesEnum::BBFreq, "bb-freq",
"Basic Block Frequency"),
clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob", "Branch Probability"),
@@ -1412,6 +1415,9 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) {
bool FuncEntryCountEnabled =
AllFeatures || (!NoFeatures && PgoAnalysisMapFeatures.isSet(
PGOMapFeaturesEnum::FuncEntryCount));
+ bool DynInstCountEnabled =
+ AllFeatures || (!NoFeatures && PgoAnalysisMapFeatures.isSet(
+ PGOMapFeaturesEnum::DynInstCount));
bool BBFreqEnabled =
AllFeatures ||
(!NoFeatures && PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BBFreq));
@@ -1424,9 +1430,12 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) {
"BB entries info is required for BBFreq and BrProb "
"features");
}
- return {FuncEntryCountEnabled, BBFreqEnabled, BrProbEnabled,
+ return {FuncEntryCountEnabled,
+ BBFreqEnabled,
+ BrProbEnabled,
MF.hasBBSections() && NumMBBSectionRanges > 1,
- static_cast<bool>(BBAddrMapSkipEmitBBEntries)};
+ static_cast<bool>(BBAddrMapSkipEmitBBEntries),
+ DynInstCountEnabled};
}
void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
@@ -1519,7 +1528,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
MaybeEntryCount ? MaybeEntryCount->getCount() : 0);
}
const MachineBlockFrequencyInfo *MBFI =
- Features.BBFreq
+ Features.BBFreq || Features.DynamicInstCount
? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
: nullptr;
const MachineBranchProbabilityInfo *MBPI =
@@ -1527,8 +1536,13 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()
: nullptr;
- if (Features.BBFreq || Features.BrProb) {
+ if (Features.BBFreq || Features.BrProb || Features.DynamicInstCount) {
+ uint64_t DynInstCount = 0;
for (const MachineBasicBlock &MBB : MF) {
+ if (Features.DynamicInstCount) {
+ DynInstCount +=
+ MBFI->getBlockProfileCount(&MBB).value_or(0) * MBB.size();
+ }
if (Features.BBFreq) {
OutStreamer->AddComment("basic block frequency");
OutStreamer->emitULEB128IntValue(
@@ -1547,6 +1561,10 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
}
}
}
+ if (Features.DynamicInstCount) {
+ OutStreamer->AddComment("Dynamic instruction count");
+ OutStreamer->emitULEB128IntValue(DynInstCount);
+ }
}
}
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index b6d0699ee4fe08..549d1de2a83f7c 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -887,6 +887,12 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
: 0;
+ // Dynamic instruction count
+ uint64_t DynInstCount =
+ FeatEnable.DynamicInstCount
+ ? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
+ : 0;
+
std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;
for (uint32_t BlockIndex = 0;
FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&
@@ -915,8 +921,8 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
}
if (PGOAnalyses)
- PGOAnalyses->push_back(
- {FuncEntryCount, std::move(PGOBBEntries), FeatEnable});
+ PGOAnalyses->push_back({FuncEntryCount, DynInstCount,
+ std::move(PGOBBEntries), FeatEnable});
}
}
// Either Cur is in the error state, or we have an error in ULEBSizeErr or
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 5daf6c32ec936a..5f8675c0e6b107 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1515,6 +1515,9 @@ void ELFState<ELFT>::writeSectionContent(
if (PGOEntry.FuncEntryCount)
SHeader.sh_size += CBA.writeULEB128(*PGOEntry.FuncEntryCount);
+ if (PGOEntry.DynamicInstCount)
+ SHeader.sh_size += CBA.writeULEB128(*PGOEntry.DynamicInstCount);
+
if (!PGOEntry.PGOBBEntries)
continue;
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index ca0ea03452d3be..424cbd45f0e01e 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1872,6 +1872,7 @@ void MappingTraits<ELFYAML::PGOAnalysisMapEntry>::mapping(
IO &IO, ELFYAML::PGOAnalysisMapEntry &E) {
assert(IO.getContext() && "The IO context is not initialized");
IO.mapOptional("FuncEntryCount", E.FuncEntryCount);
+ IO.mapOptional("DynamicInstCount", E.DynamicInstCount);
IO.mapOptional("PGOBBEntries", E.PGOBBEntries);
}
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
index 63779727ec72c6..0e49427ec3efe8 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
@@ -3,13 +3,14 @@
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=none | FileCheck %s --check-prefixes=CHECK,BASIC,PGO-NONE
;; Also verify this holds for all PGO features enabled
-; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=func-entry-count,bb-freq,br-prob | FileCheck %s --check-prefixes=CHECK,PGO-ALL,PGO-FEC,PGO-BBF,PGO-BRP
-; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=all | FileCheck %s --check-prefixes=CHECK,PGO-ALL,PGO-FEC,PGO-BBF,PGO-BRP
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=func-entry-count,bb-freq,br-prob,dyn-inst-count | FileCheck %s --check-prefixes=CHECK,PGO-ALL,PGO-FEC,PGO-BBF,PGO-BRP
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=all | FileCheck %s --check-prefixes=CHECK,PGO-ALL,PGO-FEC,PGO-BBF,PGO-BRP,PGO-DINST
;; Also verify that pgo extension only includes the enabled feature
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=func-entry-count | FileCheck %s --check-prefixes=CHECK,PGO-FEC,FEC-ONLY
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=bb-freq | FileCheck %s --check-prefixes=CHECK,PGO-BBF,BBF-ONLY
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=br-prob | FileCheck %s --check-prefixes=CHECK,PGO-BRP,BRP-ONLY
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=dyn-inst-count | FileCheck %s --check-prefixes=CHECK,PGO-DINST,DINST-ONLY
; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=func-entry-count -basic-block-address-map-skip-bb-entries | FileCheck %s --check-prefixes=SKIP-BB-ENTRIES
; RUN: not llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true -basic-block-address-map -pgo-analysis-map=bb-freq -basic-block-address-map-skip-bb-entries 2>&1 | FileCheck %s --check-prefixes=SKIP-BB-ENTRIES-ERROR
@@ -71,8 +72,9 @@ declare i32 @__gxx_personality_v0(...)
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3bazb{{$}}
; CHECK-NEXT: .byte 2 # version
; BASIC-NEXT: .byte 0 # feature
-; PGO-ALL-NEXT: .byte 7 # feature
+; PGO-ALL-NEXT: .byte 39 # feature
; FEC-ONLY-NEXT:.byte 1 # feature
+; DINST-ONLY-NEXT:.byte 32 # feature
; BBF-ONLY-NEXT:.byte 2 # feature
; BRP-ONLY-NEXT:.byte 4 # feature
; CHECK-NEXT: .quad .Lfunc_begin0 # function address
@@ -138,6 +140,8 @@ declare i32 @__gxx_personality_v0(...)
; PGO-BRP-NEXT: .byte 5 # successor BB ID
; PGO-BRP-NEXT: .ascii "\200\200\200\200\b" # successor branch probability
+; PGO-DINST: .ascii "\341\f" # Dynamic instruction count
+
; SKIP-BB-ENTRIES: .byte 17 # feature
; SKIP-BB-ENTRIES-NEXT: .quad .Lfunc_begin0 # function address
; SKIP-BB-ENTRIES-NEXT: .byte 6 # number of basic blocks
diff --git a/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml b/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
index 4d1e5408d86d4d..26466c8ff48ffa 100644
--- a/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
+++ b/llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
@@ -43,9 +43,49 @@ Symbols:
# ENTRYCOUNT: <foo>:
# ENTRYCOUNT: <BB3> (Entry count: 1000):
+## Check the case where we only have dynamic instruction count.
+# RUN: yaml2obj --docnum=2 %s -o %t1
+# RUN: llvm-objdump %t1 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
+# RUN: FileCheck %s --check-prefix=DYNICNT
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .text.foo
+ Type: SHT_PROGBITS
+ Address: 0x0
+ Flags: [SHF_ALLOC, SHF_EXECINSTR]
+ Content: '50'
+ - Name: .llvm_bb_addr_map.foo
+ Type: SHT_LLVM_BB_ADDR_MAP
+ Link: .text.foo
+ Entries:
+ - Version: 2
+ Feature: 0x20
+ BBRanges:
+ - BaseAddress: 0x0
+ BBEntries:
+ - ID: 3
+ AddressOffset: 0x0
+ Size: 0x1
+ Metadata: 0x1
+ PGOAnalyses:
+ - DynamicInstCount: 1000
+Symbols:
+ - Name: foo
+ Section: .text.foo
+ Value: 0x0
+
+# DYNICNT: <foo>:
+# DYNICNT: <BB3> (Dynamic instruction count: 1000):
+
## Check the case where we have entry points and block frequency information
-# RUN: yaml2obj %s --docnum=2 -o %t2
+# RUN: yaml2obj %s --docnum=3 -o %t2
# RUN: llvm-objdump %t2 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
# RUN: FileCheck --match-full-lines --strict-whitespace %s --check-prefix=ENTRYCOUNT-BLOCKFREQ
# RUN: llvm-objdump %t2 -d --symbolize-operands --pretty-pgo-analysis-map --no-show-raw-insn --no-leading-addr | \
@@ -68,7 +108,7 @@ Sections:
Link: .text.foo
Entries:
- Version: 2
- Feature: 0x3
+ Feature: 0x23
BBRanges:
- BaseAddress: 0x0
BBEntries:
@@ -90,6 +130,7 @@ Sections:
Metadata: 0x2
PGOAnalyses:
- FuncEntryCount: 1000
+ DynamicInstCount: 2000
PGOBBEntries:
- BBFreq: 1000
- BBFreq: 133
@@ -101,13 +142,13 @@ Symbols:
Value: 0x0
# ENTRYCOUNT-BLOCKFREQ:<foo>:
-# ENTRYCOUNT-BLOCKFREQ:<BB3> (Entry count: 1000, Frequency: 1000):
+# ENTRYCOUNT-BLOCKFREQ:<BB3> (Entry count: 1000, Dynamic instruction count: 2000, Frequency: 1000):
# ENTRYCOUNT-BLOCKFREQ:<BB1> (Frequency: 133):
# ENTRYCOUNT-BLOCKFREQ:<BB2> (Frequency: 18):
# ENTRYCOUNT-BLOCKFREQ:<BB5> (Frequency: 1000):
# ENTRYCOUNT-BLOCKFREQ-PRETTY:<foo>:
-# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB3> (Entry count: 1000, Frequency: 1.0):
+# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB3> (Entry count: 1000, Dynamic instruction count: 2000, Frequency: 1.0):
# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB1> (Frequency: 0.133):
# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB2> (Frequency: 0.018):
# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB5> (Frequency: 1.0):
@@ -115,7 +156,7 @@ Symbols:
## Check the case where we have entry points, block frequency, and branch
## proabability information.
-# RUN: yaml2obj %s --docnum=3 -o %t3
+# RUN: yaml2obj %s --docnum=4 -o %t3
# RUN: llvm-objdump %t3 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
# RUN: FileCheck --match-full-lines --strict-whitespace %s --check-prefix=ENTRY-FREQ-PROB
# RUN: llvm-objdump %t3 -d --symbolize-operands --pretty-pgo-analysis-map --no-show-raw-insn --no-leading-addr | \
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 5faafd4d83b2f2..748e0fb3dbeb50 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
@@ -15,7 +15,7 @@
## Check that a malformed section can be handled.
# RUN: yaml2obj %s -DBITS=32 -DSIZE=24 -o %t2.o
-# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck --match-full-lines %s -DOFFSET=0x00000018 -DFILE=%t2.o --check-prefix=TRUNCATED
+# RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck --match-full-lines %s -DOFFSET=0x00000014 -DFILE=%t2.o --check-prefix=TRUNCATED
## Check that missing features can be handled.
# RUN: yaml2obj %s -DBITS=32 -DFEATURE=0x2 -o %t3.o
@@ -55,6 +55,7 @@
# CHECK-NEXT: ]
# CHECK-NEXT: PGO analyses {
# CHECK-NEXT: FuncEntryCount: 100
+# CHECK-NEXT: DynamicInstCount: 100
# CHECK-NEXT: PGO BB entries [
# CHECK-NEXT: {
# RAW-NEXT: Frequency: 100
@@ -98,6 +99,7 @@
# CHECK-NEXT: ]
# CHECK-NEXT: PGO analyses {
# CHECK-NEXT: FuncEntryCount: 8888
+# CHECK-NEXT: DynamicInstCount: 8888
# CHECK-NEXT: PGO BB entries [
# CHECK-NEXT: {
# RAW-NEXT: Frequency: 9000
@@ -173,7 +175,7 @@ Sections:
Link: .text
Entries:
- Version: 2
- Feature: 0x7
+ Feature: 0x27
BBRanges:
- BaseAddress: [[ADDR=0x11111]]
BBEntries:
@@ -186,7 +188,7 @@ Sections:
Size: 0x4
Metadata: 0x15
- Version: 2
- Feature: 0x3
+ Feature: 0x23
BBRanges:
- BaseAddress: 0x22222
BBEntries:
@@ -196,6 +198,7 @@ Sections:
Metadata: 0x8
PGOAnalyses:
- FuncEntryCount: 100
+ DynamicInstCount: 100
PGOBBEntries:
- BBFreq: 100
Successors:
@@ -204,6 +207,7 @@ Sections:
- BBFreq: 100
Successors: []
- FuncEntryCount: 8888
+ DynamicInstCount: 8888
PGOBBEntries:
- BBFreq: 9000
- Name: dummy_section
@@ -237,4 +241,3 @@ Symbols:
Section: .text.bar
Type: STT_FUNC
Value: 0x33333
-
diff --git a/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml b/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml
index 299bf463cf4bc9..37edd968893b3a 100644
--- a/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/bb-addr-map-pgo-analysis-map.yaml
@@ -15,7 +15,7 @@
# VALID-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# VALID-NEXT: Entries:
# VALID-NEXT: - Version: 2
-# VALID-NEXT: Feature: 0x7
+# VALID-NEXT: Feature: 0x27
## The 'BaseAddress' field is omitted when it's zero.
# VALID-NEXT: BBRanges:
# VALID-NEXT: - BBEntries:
@@ -42,6 +42,7 @@
# VALID-NEXT: Metadata: 0xC
# VALID-NEXT: PGOAnalyses:
# VALID-NEXT: - FuncEntryCount: 100
+# VALID-NEXT: DynamicInstCount: 200
# VALID-NEXT: PGOBBEntries:
# VALID-NEXT: - BBFreq: 100
# VALID-NEXT: Successors:
@@ -69,7 +70,7 @@ Sections:
ShSize: [[SIZE=<none>]]
Entries:
- Version: 2
- Feature: 0x7
+ Feature: 0x27
BBRanges:
- BaseAddress: 0x0
BBEntries:
@@ -96,6 +97,7 @@ Sections:
Metadata: 0xC
PGOAnalyses:
- FuncEntryCount: 100
+ DynamicInstCount: 200
PGOBBEntries:
- BBFreq: 100
Successors:
@@ -229,4 +231,3 @@ Sections:
# MISSING-FEC-NEXT: - Name: .llvm_bb_addr_map
# MISSING-FEC-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
# MISSING-FEC-NEXT: Content: '{{([[:xdigit:]]+)}}'{{$}}
-
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 246d5cfa05818a..95e3da2590ff15 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -198,15 +198,19 @@ class BBAddrMapFunctionEntry {
raw_string_ostream PGOSS(PGOString);
PGOSS << " (";
- if (PGOMap.FeatEnable.FuncEntryCount && PGOBBEntryIndex == 0) {
+ if (PGOMap.FeatEnable.FuncEntryCount && PGOBBEntryIndex == 0)
PGOSS << "Entry count: " << Twine(PGOMap.FuncEntryCount);
- if (PGOMap.FeatEnable.hasPGOAnalysisBBData()) {
+
+ if (PGOMap.FeatEnable.DynamicInstCount && PGOBBEntryIndex == 0) {
+ if (PGOMap.FeatEnable.FuncEntryCount)
PGOSS << ", ";
- }
+ PGOSS << "Dynamic instruction count: " << Twine(PGOMap.DynamicInstCount);
}
if (PGOMap.FeatEnable.hasPGOAnalysisBBData()) {
-
+ if (PGOBBEntryIndex == 0 && (PGOMap.FeatEnable.FuncEntryCount ||
+ PGOMap.FeatEnable.DynamicInstCount))
+ PGOSS << ", ";
assert(PGOBBEntryIndex < PGOMap.BBEntries.size() &&
"Expected PGOAnalysisMap and BBAddrMap to have the same entries");
const PGOAnalysisMap::PGOBBEntry &PGOBBEntry =
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index bb8ec41d87454c..7aaaec9978e8d5 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -7858,6 +7858,9 @@ void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {
if (PAM.FeatEnable.FuncEntryCount)
W.printNumber("FuncEntryCount", PAM.FuncEntryCount);
+ if (PAM.FeatEnable.DynamicInstCount)
+ W.printNumber("DynamicInstCount", PAM.DynamicInstCount);
+
if (PAM.FeatEnable.hasPGOAnalysisBBData()) {
ListScope L(W, "PGO BB entries");
for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index b1c8032ea21929..b572bc0c2e448f 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -951,6 +951,9 @@ ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
if (FeatureOrErr->FuncEntryCount)
PGOAnalysis.FuncEntryCount = Data.getULEB128(Cur);
+ if (FeatureOrErr->DynamicInstCount)
+ PGOAnalysis.DynamicInstCount = Data.getULEB128(Cur);
+
if (FeatureOrErr->hasPGOAnalysisBBData()) {
auto &PGOBBEntries = PGOAnalysis.PGOBBEntries.emplace();
for (uint64_t BlockIndex = 0; Cur && BlockIndex < TotalNumBlocks;
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index 2a0921690914b4..0cfe8ba632e60a 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -1148,22 +1148,25 @@ TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
BBAddrMap E1 = {
{{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
- PGOAnalysisMap P1 = {892, {}, {true, false, false, false, false}};
+ PGOAnalysisMap P1 = {892, {}, {}, {true, false, false, false, false, false}};
BBAddrMap E2 = {
{{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
- PGOAnalysisMap P2 = {
- {}, {{BlockFrequency(343), {}}}, {false, true, false, false, false}};
+ PGOAnalysisMap P2 = {{},
+ {},
+ {{BlockFrequency(343), {}}},
+ {false, true, false, false, 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, false, false}};
+ {false, false, true, false, false, false}};
BBAddrMap E4 = {{{0x44444,
{{0, 0x0, 0x4, {false, false, false, true, true}},
{1, 0x4, 0x4, {false, false, false, false, false}},
@@ -1171,6 +1174,7 @@ TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
{3, 0xc, 0x4, {false, false, false, false, false}}}}}};
PGOAnalysisMap P4 = {
1000,
+ {},
{{BlockFrequency(1000),
{{1, BranchProbability::getRaw(0x2222'2222)},
{2, BranchProbability::getRaw(0x3333'3333)},
@@ -1180,22 +1184,23 @@ TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
{3, BranchProbability::getRaw(0xeeee'eeee)}}},
{BlockFrequency(18), {{3, BranchProbability::getRaw(0xffff'ffff)}}},
{BlockFrequency(1000), {}}},
- {true, true, true, false, false}};
+ {true, true, true, false, false, false}};
BBAddrMap E5 = {
{{0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
- PGOAnalysisMap P5 = {{}, {}, {false, false, false, false, false}};
+ PGOAnalysisMap P5 = {{}, {}, {}, {false, false, 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, false}};
+ {false, false, true, true, false, false}};
std::vector<BBAddrMap> Section0BBAddrMaps = {E4, E5, E6};
std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
diff --git a/llvm/unittests/Object/ELFTypesTest.cpp b/llvm/unittests/Object/ELFTypesTest.cpp
index 13130dde80ef10..d8ba57a076817f 100644
--- a/llvm/unittests/Object/ELFTypesTest.cpp
+++ b/llvm/unittests/Object/ELFTypesTest.cpp
@@ -101,18 +101,20 @@ static_assert(
"PGOAnalysisMap should use the same type for basic block ID as BBAddrMap");
TEST(ELFTypesTest, BBAddrMapFeaturesEncodingTest) {
- const std::array<BBAddrMap::Features, 9> Decoded = {
- {{false, false, false, false, false},
- {true, false, false, false, false},
- {false, true, false, false, false},
- {false, false, true, false, false},
- {false, false, false, true, false},
- {true, true, false, false, false},
- {false, true, true, false, false},
- {false, true, true, true, false},
- {true, true, true, true, false}}};
- const std::array<uint8_t, 9> Encoded = {
- {0b0000, 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b0110, 0b1110, 0b1111}};
+ const std::array<BBAddrMap::Features, 10> Decoded = {
+ {{false, false, false, false, false, false},
+ {true, false, false, false, false, false},
+ {false, true, false, false, false, false},
+ {false, false, true, false, false, false},
+ {false, false, false, true, false, false},
+ {true, true, false, false, false, false},
+ {false, true, true, false, false, false},
+ {false, true, true, true, false, false},
+ {true, true, true, true, false, false},
+ {true, true, true, true, true, true}}};
+ const std::array<uint8_t, 10> Encoded = {{0b0000, 0b0001, 0b0010, 0b0100,
+ 0b1000, 0b0011, 0b0110, 0b1110,
+ 0b1111, 0b11'1111}};
for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded))
EXPECT_EQ(Feat.encode(), EncodedVal);
for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded)) {
@@ -125,9 +127,9 @@ TEST(ELFTypesTest, BBAddrMapFeaturesEncodingTest) {
TEST(ELFTypesTest, BBAddrMapFeaturesInvalidEncodingTest) {
const std::array<std::string, 2> Errors = {
- "invalid encoding for BBAddrMap::Features: 0x20",
+ "invalid encoding for BBAddrMap::Features: 0x40",
"invalid encoding for BBAddrMap::Features: 0xf0"};
- const std::array<uint8_t, 2> Values = {{0b10'0000, 0b1111'0000}};
+ const std::array<uint8_t, 2> Values = {{0b100'0000, 0b1111'0000}};
for (const auto &[Val, Error] : llvm::zip(Values, Errors)) {
EXPECT_THAT_ERROR(BBAddrMap::Features::decode(Val).takeError(),
FailedWithMessage(Error));
More information about the llvm-commits
mailing list