Skip to content

Commit

Permalink
[SHT_LLVM_BB_ADDR_MAP] Adds pretty printing of BFI and BPI for PGO An…
Browse files Browse the repository at this point in the history
…alysis Map in tools. (llvm#82292)

Primary change is to add a flag `--pretty-pgo-analysis-map` to
llvm-readobj and llvm-objdump that prints block frequencies and branch
probabilities in the same manner as BFI and BPI respectively. This can
be helpful if you are manually inspecting the outputs from the tools.

In order to print, I moved the `printBlockFreqImpl` function from
Analysis to Support and renamed it to `printRelativeBlockFreq`.
  • Loading branch information
red1bluelost authored Feb 27, 2024
1 parent 19181f2 commit 9ca8db3
Show file tree
Hide file tree
Showing 16 changed files with 164 additions and 71 deletions.
16 changes: 15 additions & 1 deletion llvm/docs/CommandGuide/llvm-objdump.rst
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,12 @@ OPTIONS

When printing a PC-relative global symbol reference, print it as an offset from the leading symbol.

When a bb-address-map section is present (i.e., the object file is built with ``-fbasic-block-sections=labels``), labels are retrieved from that section instead.
When a bb-address-map section is present (i.e., the object file is built with
``-fbasic-block-sections=labels``), labels are retrieved from that section
instead. If a pgo-analysis-map is present alongside the bb-address-map, any
available analyses are printed after the relevant block label. By default,
any analysis with a special representation (i.e. BlockFrequency,
BranchProbability, etc) are printed as raw hex values.

Only works with PowerPC objects or X86 linked images.

Expand All @@ -291,6 +296,15 @@ OPTIONS
cmp eax, dword ptr <g>
jge <L0>
.. option:: --pretty-pgo-analysis-map

When using :option:`--symbolize-operands` with bb-address-map and
pgo-analysis-map, print analyses using the same format as their analysis
passes would. An example of pretty format would be printing block frequencies
relative to the entry block, the same as BFI.

Only works when :option:`--symbolize-operands` is enabled.

.. option:: --triple=<string>

Target triple to disassemble for, see ``--version`` for available targets.
Expand Down
11 changes: 11 additions & 0 deletions llvm/docs/CommandGuide/llvm-readobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ The following options are implemented only for the ELF file format.
Display the contents of the basic block address map section(s), which contain the
address of each function, along with the relative offset of each basic block.

When pgo analysis maps are present, all analyses are printed as their raw
value.

.. option:: --pretty-pgo-analysis-map

When pgo analysis maps are present in the basic block address map section(s),
analyses with special formats (i.e. BlockFrequency, BranchProbability, etc)
are printed using the same format as their respective analysis pass.

Requires :option:`--bb-addr-map` to have an effect.

.. option:: --demangle, -C

Display demangled symbol names in the output.
Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,6 @@ class BlockFrequencyInfoImplBase {
}
};

void printBlockFreqImpl(raw_ostream &OS, BlockFrequency EntryFreq,
BlockFrequency Freq);

namespace bfi_detail {

template <class BlockT> struct TypeMap {};
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Support/BlockFrequency.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace llvm {

class raw_ostream;
class BranchProbability;

// This class represents Block Frequency as a 64-bit value.
Expand Down Expand Up @@ -119,6 +120,9 @@ class BlockFrequency {
}
};

void printRelativeBlockFreq(raw_ostream &OS, BlockFrequency EntryFreq,
BlockFrequency Freq);

} // namespace llvm

#endif
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/BlockFrequencyInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ void BlockFrequencyInfo::verifyMatch(BlockFrequencyInfo &Other) const {
Printable llvm::printBlockFreq(const BlockFrequencyInfo &BFI,
BlockFrequency Freq) {
return Printable([&BFI, Freq](raw_ostream &OS) {
printBlockFreqImpl(OS, BFI.getEntryFreq(), Freq);
printRelativeBlockFreq(OS, BFI.getEntryFreq(), Freq);
});
}

Expand Down
15 changes: 0 additions & 15 deletions llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,21 +634,6 @@ BlockFrequencyInfoImplBase::getLoopName(const LoopData &Loop) const {
return getBlockName(Loop.getHeader()) + (Loop.isIrreducible() ? "**" : "*");
}

void llvm::printBlockFreqImpl(raw_ostream &OS, BlockFrequency EntryFreq,
BlockFrequency Freq) {
if (Freq == BlockFrequency(0)) {
OS << "0";
return;
}
if (EntryFreq == BlockFrequency(0)) {
OS << "<invalid BFI>";
return;
}
Scaled64 Block(Freq.getFrequency(), 0);
Scaled64 Entry(EntryFreq.getFrequency(), 0);
OS << Block / Entry;
}

void IrreducibleGraph::addNodesInLoop(const BFIBase::LoopData &OuterLoop) {
Start = OuterLoop.getHeader();
Nodes.reserve(OuterLoop.Nodes.size());
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ BlockFrequency MachineBlockFrequencyInfo::getEntryFreq() const {
Printable llvm::printBlockFreq(const MachineBlockFrequencyInfo &MBFI,
BlockFrequency Freq) {
return Printable([&MBFI, Freq](raw_ostream &OS) {
printBlockFreqImpl(OS, MBFI.getEntryFreq(), Freq);
printRelativeBlockFreq(OS, MBFI.getEntryFreq(), Freq);
});
}

Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Support/BlockFrequency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ScaledNumber.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

Expand Down Expand Up @@ -45,3 +47,18 @@ std::optional<BlockFrequency> BlockFrequency::mul(uint64_t Factor) const {
return {};
return BlockFrequency(ResultFrequency);
}

void llvm::printRelativeBlockFreq(raw_ostream &OS, BlockFrequency EntryFreq,
BlockFrequency Freq) {
if (Freq == BlockFrequency(0)) {
OS << "0";
return;
}
if (EntryFreq == BlockFrequency(0)) {
OS << "<invalid BFI>";
return;
}
ScaledNumber<uint64_t> Block(Freq.getFrequency(), 0);
ScaledNumber<uint64_t> Entry(EntryFreq.getFrequency(), 0);
OS << Block / Entry;
}
56 changes: 38 additions & 18 deletions llvm/test/tools/llvm-objdump/X86/elf-pgoanalysismap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ Symbols:

# RUN: yaml2obj %s --docnum=2 -o %t2
# RUN: llvm-objdump %t2 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
# RUN: FileCheck %s --check-prefix=ENTRYCOUNT-BLOCKFREQ
# 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 | \
# RUN: FileCheck --match-full-lines --strict-whitespace %s --check-prefix=ENTRYCOUNT-BLOCKFREQ-PRETTY

--- !ELF
FileHeader:
Expand Down Expand Up @@ -98,18 +100,28 @@ Symbols:
Section: .text.foo
Value: 0x0

# ENTRYCOUNT-BLOCKFREQ: <foo>:
# ENTRYCOUNT-BLOCKFREQ: <BB3> (Entry count: 1000, Frequency: 1000):
# ENTRYCOUNT-BLOCKFREQ: <BB1> (Frequency: 133):
# ENTRYCOUNT-BLOCKFREQ: <BB2> (Frequency: 18):
# ENTRYCOUNT-BLOCKFREQ: <BB5> (Frequency: 1000):
# ENTRYCOUNT-BLOCKFREQ:<foo>:
# ENTRYCOUNT-BLOCKFREQ:<BB3> (Entry count: 1000, 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:<BB1> (Frequency: 0.133):
# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB2> (Frequency: 0.018):
# ENTRYCOUNT-BLOCKFREQ-PRETTY:<BB5> (Frequency: 1.0):

## Check the case where we have entry points, block frequency, and branch
## proabability information.

# RUN: yaml2obj %s --docnum=3 -o %t3
# RUN: llvm-objdump %t3 -d --symbolize-operands --no-show-raw-insn --no-leading-addr | \
# RUN: FileCheck %s --check-prefix=ENTRY-FREQ-PROB
# 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 | \
# RUN: FileCheck --match-full-lines --strict-whitespace %s --check-prefix=ENTRY-FREQ-PROB-PRETTY
# RUN: llvm-objdump %t3 -d --pretty-pgo-analysis-map --no-show-raw-insn --no-leading-addr 2>&1 | \
# RUN: FileCheck %s --check-prefix=MISSING-SYMBOLIZE-OPERANDS

--- !ELF
FileHeader:
Expand Down Expand Up @@ -154,30 +166,38 @@ Sections:
- BBFreq: 1000
Successors:
- ID: 1
BrProb: 0x22222222
BrProb: 0x10000000
- ID: 2
BrProb: 0x33333333
BrProb: 0x15000000
- ID: 3
BrProb: 0xaaaaaaaa
BrProb: 0x50000000
- BBFreq: 133
Successors:
- ID: 2
BrProb: 0x11111111
BrProb: 0x10000000
- ID: 3
BrProb: 0xeeeeeeee
BrProb: 0x70000000
- BBFreq: 18
Successors:
- ID: 3
BrProb: 0xffffffff
BrProb: 0x80000000
- BBFreq: 1000
Successors: []
Symbols:
- Name: foo
Section: .text.foo
Value: 0x0

# ENTRY-FREQ-PROB: <foo>:
# ENTRY-FREQ-PROB: <BB3> (Entry count: 1000, Frequency: 1000, Successors: BB1:22222222, BB2:33333333, BB3:aaaaaaaa):
# ENTRY-FREQ-PROB: <BB1> (Frequency: 133, Successors: BB2:11111111, BB3:eeeeeeee):
# ENTRY-FREQ-PROB: <BB2> (Frequency: 18, Successors: BB3:ffffffff):
# ENTRY-FREQ-PROB: <BB5> (Frequency: 1000):
# ENTRY-FREQ-PROB:<foo>:
# ENTRY-FREQ-PROB:<BB3> (Entry count: 1000, Frequency: 1000, Successors: BB1:10000000, BB2:15000000, BB3:50000000):
# ENTRY-FREQ-PROB:<BB1> (Frequency: 133, Successors: BB2:10000000, BB3:70000000):
# ENTRY-FREQ-PROB:<BB2> (Frequency: 18, Successors: BB3:80000000):
# ENTRY-FREQ-PROB:<BB5> (Frequency: 1000):

# ENTRY-FREQ-PROB-PRETTY:<foo>:
# ENTRY-FREQ-PROB-PRETTY:<BB3> (Entry count: 1000, Frequency: 1.0, Successors: BB1:[0x10000000 / 0x80000000 = 12.50%], BB2:[0x15000000 / 0x80000000 = 16.41%], BB3:[0x50000000 / 0x80000000 = 62.50%]):
# ENTRY-FREQ-PROB-PRETTY:<BB1> (Frequency: 0.133, Successors: BB2:[0x10000000 / 0x80000000 = 12.50%], BB3:[0x70000000 / 0x80000000 = 87.50%]):
# ENTRY-FREQ-PROB-PRETTY:<BB2> (Frequency: 0.018, Successors: BB3:[0x80000000 / 0x80000000 = 100.00%]):
# ENTRY-FREQ-PROB-PRETTY:<BB5> (Frequency: 1.0):

# MISSING-SYMBOLIZE-OPERANDS: warning: --symbolize-operands must be enabled for --pretty-pgo-analysis-map to have an effect
28 changes: 18 additions & 10 deletions llvm/test/tools/llvm-readobj/ELF/bb-addr-map-pgo-analysis-map.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@

## Check 64-bit:
# 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-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck --match-full-lines %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefixes=CHECK,RAW
# RUN: llvm-readobj %t1.x64.o --bb-addr-map --pretty-pgo-analysis-map 2>&1 | FileCheck --match-full-lines %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefixes=CHECK,PRETTY
# RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU
# RUN: llvm-readobj %t1.x64.o --pretty-pgo-analysis-map 2>&1 | FileCheck %s --check-prefix=PRETTY-NO-BAM

## Check 32-bit:
# 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-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck --match-full-lines -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefixes=CHECK,RAW
# RUN: llvm-readelf %t1.x32.o --bb-addr-map | FileCheck %s --check-prefix=GNU

## 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 %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=0x00000018 -DFILE=%t2.o --check-prefix=TRUNCATED

## Check that missing features can be handled.
# RUN: yaml2obj %s -DBITS=32 -DFEATURE=0x2 -o %t3.o
Expand All @@ -22,7 +24,7 @@
# 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: {{.*}}: 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 Ranges [
# CHECK-NEXT: {
Expand Down Expand Up @@ -55,16 +57,19 @@
# CHECK-NEXT: FuncEntryCount: 100
# CHECK-NEXT: PGO BB entries [
# CHECK-NEXT: {
# CHECK-NEXT: Frequency: 100
# RAW-NEXT: Frequency: 100
# PRETTY-NEXT: Frequency: 1.0
# CHECK-NEXT: Successors [
# CHECK-NEXT: {
# CHECK-NEXT: ID: 2
# CHECK-NEXT: Probability: 0xFFFFFFFF
# RAW-NEXT: Probability: 0x80000000
# PRETTY-NEXT: Probability: 0x80000000 / 0x80000000 = 100.00%
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
# CHECK-NEXT: {
# CHECK-NEXT: Frequency: 100
# RAW-NEXT: Frequency: 100
# PRETTY-NEXT: Frequency: 1.0
# CHECK-NEXT: Successors [
# CHECK-NEXT: ]
# CHECK-NEXT: }
Expand Down Expand Up @@ -95,7 +100,8 @@
# CHECK-NEXT: FuncEntryCount: 8888
# CHECK-NEXT: PGO BB entries [
# CHECK-NEXT: {
# CHECK-NEXT: Frequency: 9000
# RAW-NEXT: Frequency: 9000
# PRETTY-NEXT: Frequency: 1.0
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
Expand All @@ -104,8 +110,10 @@

# GNU: GNUStyle::printBBAddrMaps not implemented

# PRETTY-NO-BAM: warning: --bb-addr-map must be enabled for --pretty-pgo-analysis-map to have an effect

# 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: {{.*}}: 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 [
Expand Down Expand Up @@ -192,7 +200,7 @@ Sections:
- BBFreq: 100
Successors:
- ID: 2
BrProb: 0xFFFFFFFF
BrProb: 0x80000000
- BBFreq: 100
Successors: []
- FuncEntryCount: 8888
Expand Down
4 changes: 4 additions & 0 deletions llvm/tools/llvm-objdump/ObjdumpOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ def : Flag<["-"], "t">, Alias<syms>, HelpText<"Alias for --syms">;
def symbolize_operands : Flag<["--"], "symbolize-operands">,
HelpText<"Symbolize instruction operands when disassembling">;

def pretty_pgo_analysis_map : Flag<["--"], "pretty-pgo-analysis-map">,
HelpText<"Display PGO analysis values with "
"formatting rather than raw numbers">;

def dynamic_syms : Flag<["--"], "dynamic-syms">,
HelpText<"Display the contents of the dynamic symbol table">;
def : Flag<["-"], "T">, Alias<dynamic_syms>,
Expand Down
Loading

0 comments on commit 9ca8db3

Please sign in to comment.