Skip to content

[AsmPrint] Correctly factor function entry count when dumping MBB frequencies #67826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ class MachineBlockFrequencyInfo : public MachineFunctionPass {

/// Compute the frequency of the block, relative to the entry block.
/// This API assumes getEntryFreq() is non-zero.
float getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const {
double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const {
assert(getEntryFreq() != 0 && "getEntryFreq() should not return 0 here!");
return getBlockFreq(MBB).getFrequency() * (1.0f / getEntryFreq());
return static_cast<double>(getBlockFreq(MBB).getFrequency()) /
static_cast<double>(getEntryFreq());
}

std::optional<uint64_t>
Expand Down
20 changes: 17 additions & 3 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1929,18 +1929,32 @@ void AsmPrinter::emitFunctionBody() {

// Output MBB ids, function names, and frequencies if the flag to dump
// MBB profile information has been set
if (MBBProfileDumpFileOutput) {
if (MBBProfileDumpFileOutput && !MF->empty() &&
MF->getFunction().getEntryCount()) {
if (!MF->hasBBLabels())
MF->getContext().reportError(
SMLoc(),
"Unable to find BB labels for MBB profile dump. -mbb-profile-dump "
"must be called with -basic-block-sections=labels");
MachineBlockFrequencyInfo &MBFI =
getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI();
// The entry count and the entry basic block frequency aren't the same. We
// want to capture "absolute" frequencies, i.e. the frequency with which a
// MBB is executed when the program is executed. From there, we can derive
// Function-relative frequencies (divide by the value for the first MBB).
// We also have the information about frequency with which functions
// were called. This helps, for example, in a type of integration tests
// where we want to cross-validate the compiler's profile with a real
// profile.
// Using double precision because uint64 values used to encode mbb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to mention that parsing double is harder than uint64 and now all values have that burden. It depends on how you are consuming them; up to you to reconsider.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Harder how? And what would be the alternative?

BTW, was a float until #66818

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double representations are slower to parse, particularly with standard library functions such as strtod, see https://github.com/fastfloat/fast_float.

BTW, was a float until #66818

If you haven't had any concerns before then it probably doesn't matter now.

// "frequencies" may be quite large.
const double EntryCount =
static_cast<double>(MF->getFunction().getEntryCount()->getCount());
for (const auto &MBB : *MF) {
const double MBBRelFreq = MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
const double AbsMBBFreq = MBBRelFreq * EntryCount;
*MBBProfileDumpFileOutput.get()
<< MF->getName() << "," << MBB.getBBID() << ","
<< MBFI.getBlockFreq(&MBB).getFrequency() << "\n";
<< MF->getName() << "," << MBB.getBBID() << "," << AbsMBBFreq << "\n";
}
}
}
Expand Down
36 changes: 29 additions & 7 deletions llvm/test/CodeGen/Generic/bb-profile-dump.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,48 @@

; Check that given a simple case, we can return the default MBFI

define i64 @f2(i64 %a, i64 %b) {
define i64 @f2(i64 %a, i64 %b) !prof !1{
%sum = add i64 %a, %b
ret i64 %sum
}

; CHECK: f2,0,8
; CHECK: f2,0,1.000000e+03

define i64 @f1() {
define i64 @f1() !prof !2{
%sum = call i64 @f2(i64 2, i64 2)
%isEqual = icmp eq i64 %sum, 4
br i1 %isEqual, label %ifEqual, label %ifNotEqual
br i1 %isEqual, label %ifEqual, label %ifNotEqual, !prof !3
ifEqual:
ret i64 0
ifNotEqual:
ret i64 %sum
}

; CHECK-NEXT: f1,0,16
; CHECK-NEXT: f1,1,8
; CHECK-NEXT: f1,2,16
; CHECK-NEXT: f1,0,1.000000e+01
; CHECK-NEXT: f1,2,6.000000e+00
; CHECK-NEXT: f1,1,4.000000e+00

define void @f3(i32 %iter) !prof !4 {
entry:
br label %loop
loop:
%i = phi i32 [0, %entry], [%i_next, %loop]
%i_next = add i32 %i, 1
%exit_cond = icmp slt i32 %i_next, %iter
br i1 %exit_cond, label %loop, label %exit, !prof !5
exit:
ret void
}

; CHECK-NEXT: f3,0,2.000000e+00
; CHECK-NEXT: f3,1,2.002000e+03
; CHECK-NEXT: f3,2,2.000000e+00

!1 = !{!"function_entry_count", i64 1000}
!2 = !{!"function_entry_count", i64 10}
!3 = !{!"branch_weights", i32 2, i32 3}
!4 = !{!"function_entry_count", i64 2}
!5 = !{!"branch_weights", i32 1000, i32 1}

; Check that if we pass -mbb-profile-dump but don't set -basic-block-sections,
; we get an appropriate error message
Expand Down