Skip to content

[BPI] Reuse the AsmWriter's BB naming scheme in BranchProbabilityPrinterPass #73593

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 4 commits into from
Dec 2, 2023

Conversation

mtrofin
Copy link
Member

@mtrofin mtrofin commented Nov 28, 2023

When using BranchProbabilityPrinterPass, if a BB has no name, we get pretty unusable information like edge -> has probability... (i.e. we have no idea what the vertices of that edge are).

This patch uses printAsOperand, which uses the same naming scheme as Function::dump, so for example during debugging sessions, the IR obtained from a function and the names used by BranchProbabilityPrinterPass will match.

A shortcoming is that printAsOperand will result in the numbering algorithm re-running for every edge and every vertex (when BranchProbabilityPrinterPass is run on a function). If, for the given scenario, this is a problem, we can revisit this subsequently.

Another nuance is that the entry basic block will be numbered, which may be slightly confusing when it's anonymous, but it's easily identifiable - the first edge would have it as source (and the number should be easily recognizable)

When using `BranchProbabilityPrinterPass`, if a BB has no name, we get
pretty unusable information like `edge -> has probability...` (i.e. no
idea what the vertices of that edge are).

This patch reuses the same naming sheme `Function::dump`. Especially
during debugging sessions, the IR obtained from a function and the names
used by BPPP will match.
@llvmbot llvmbot added llvm:ir llvm:analysis Includes value tracking, cost tables and constant folding labels Nov 28, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2023

@llvm/pr-subscribers-pgo
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-ir

Author: Mircea Trofin (mtrofin)

Changes

When using BranchProbabilityPrinterPass, if a BB has no name, we get
pretty unusable information like edge -> has probability... (i.e. no
idea what the vertices of that edge are).

This patch reuses the same naming sheme Function::dump. Especially
during debugging sessions, the IR obtained from a function and the names
used by BPPP will match.


Full diff: https://github.com/llvm/llvm-project/pull/73593.diff

5 Files Affected:

  • (modified) llvm/include/llvm/IR/BasicBlock.h (+2-2)
  • (modified) llvm/lib/Analysis/BranchProbabilityInfo.cpp (+7-2)
  • (modified) llvm/lib/IR/AsmWriter.cpp (+16-11)
  • (added) llvm/test/Analysis/BranchProbabilityInfo/anonymous-bb.ll (+25)
  • (modified) llvm/test/Analysis/BranchProbabilityInfo/pointer_heuristics.ll (+12-12)
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index ec916acc25151c8..98ff865dba96974 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -420,8 +420,8 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
   /// Print the basic block to an output stream with an optional
   /// AssemblyAnnotationWriter.
   void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW = nullptr,
-             bool ShouldPreserveUseListOrder = false,
-             bool IsForDebug = false) const;
+             bool ShouldPreserveUseListOrder = false, bool IsForDebug = false,
+             bool NameOnly = false) const;
 
   //===--------------------------------------------------------------------===//
   /// Instruction iterator methods
diff --git a/llvm/lib/Analysis/BranchProbabilityInfo.cpp b/llvm/lib/Analysis/BranchProbabilityInfo.cpp
index 9789a3e5364c3c6..04de2d2cebe4f3c 100644
--- a/llvm/lib/Analysis/BranchProbabilityInfo.cpp
+++ b/llvm/lib/Analysis/BranchProbabilityInfo.cpp
@@ -1188,8 +1188,13 @@ BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS,
                                             const BasicBlock *Src,
                                             const BasicBlock *Dst) const {
   const BranchProbability Prob = getEdgeProbability(Src, Dst);
-  OS << "edge " << Src->getName() << " -> " << Dst->getName()
-     << " probability is " << Prob
+  OS << "edge ";
+  Src->print(OS, /*AAW=*/nullptr, /*ShouldPreserveUseListOrder=*/false,
+             /*IsForDebug=*/false, /*NameOnly=*/true);
+  OS << " -> ";
+  Dst->print(OS, /*AAW=*/nullptr, /*ShouldPreserveUseListOrder=*/false,
+             /*IsForDebug=*/false, /*NameOnly=*/true);
+  OS << " probability is " << Prob
      << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
 
   return OS;
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 601b636f306adeb..9b14ad974139783 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2624,7 +2624,7 @@ class AssemblyWriter {
   void printComdat(const Comdat *C);
   void printFunction(const Function *F);
   void printArgument(const Argument *FA, AttributeSet Attrs);
-  void printBasicBlock(const BasicBlock *BB);
+  void printBasicBlock(const BasicBlock *BB, bool NameOnly = false);
   void printInstructionLine(const Instruction &I);
   void printInstruction(const Instruction &I);
   void printDPMarker(const DPMarker &DPI);
@@ -3960,21 +3960,26 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
 }
 
 /// printBasicBlock - This member is called for each basic block in a method.
-void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
-  bool IsEntryBlock = BB->getParent() && BB->isEntryBlock();
-  if (BB->hasName()) {              // Print out the label if it exists...
+void AssemblyWriter::printBasicBlock(const BasicBlock *BB, bool NameOnly) {
+  const bool IsEntryBlock = BB->getParent() && BB->isEntryBlock();
+  const bool UnnamedEntry = !BB->hasName() && IsEntryBlock;
+  if (!NameOnly && !UnnamedEntry)
     Out << "\n";
+  if (BB->hasName()) { // Print out the label if it exists...
     PrintLLVMName(Out, BB->getName(), LabelPrefix);
-    Out << ':';
   } else if (!IsEntryBlock) {
-    Out << "\n";
     int Slot = Machine.getLocalSlot(BB);
     if (Slot != -1)
-      Out << Slot << ":";
+      Out << Slot;
     else
-      Out << "<badref>:";
+      Out << "<badref>";
   }
 
+  if (NameOnly)
+    return;
+  if (!UnnamedEntry)
+    Out << ":";
+
   if (!IsEntryBlock) {
     // Output predecessors for the block.
     Out.PadToColumn(50);
@@ -4658,14 +4663,14 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
 }
 
 void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
-                     bool ShouldPreserveUseListOrder,
-                     bool IsForDebug) const {
+                       bool ShouldPreserveUseListOrder, bool IsForDebug,
+                       bool NameOnly) const {
   SlotTracker SlotTable(this->getParent());
   formatted_raw_ostream OS(ROS);
   AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
                    IsForDebug,
                    ShouldPreserveUseListOrder);
-  W.printBasicBlock(this);
+  W.printBasicBlock(this, NameOnly);
 }
 
 void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
diff --git a/llvm/test/Analysis/BranchProbabilityInfo/anonymous-bb.ll b/llvm/test/Analysis/BranchProbabilityInfo/anonymous-bb.ll
new file mode 100644
index 000000000000000..7ca97699dfba2b1
--- /dev/null
+++ b/llvm/test/Analysis/BranchProbabilityInfo/anonymous-bb.ll
@@ -0,0 +1,25 @@
+; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
+
+define void @fct() {
+; CHECK: fct
+entry:
+  br label %0
+0:
+  br label %1
+1:
+  ret void
+}
+
+; CHECK: edge entry -> 0
+; CHECK: edge 0 -> 1
+
+define void @fct2() {
+; CHECK: fct2
+  br label %1
+1:
+  br label %2
+2:
+  ret void
+}
+; CHECK: edge  -> 1
+; CHECK: edge 1 -> 2
\ No newline at end of file
diff --git a/llvm/test/Analysis/BranchProbabilityInfo/pointer_heuristics.ll b/llvm/test/Analysis/BranchProbabilityInfo/pointer_heuristics.ll
index 3c6798d31f9ba71..76a57de9ef82cdd 100644
--- a/llvm/test/Analysis/BranchProbabilityInfo/pointer_heuristics.ll
+++ b/llvm/test/Analysis/BranchProbabilityInfo/pointer_heuristics.ll
@@ -4,18 +4,18 @@ define i32 @cmp1(ptr readnone %0, ptr readnone %1) {
 ; CHECK-LABEL: 'cmp1'
   %3 = icmp eq ptr %0, %1
   br i1 %3, label %4, label %6
-; CHECK:   edge  ->  probability is 0x30000000 / 0x80000000 = 37.50%
-; CHECK:   edge  ->  probability is 0x50000000 / 0x80000000 = 62.50%
+; CHECK:   edge  -> 4 probability is 0x30000000 / 0x80000000 = 37.50%
+; CHECK:   edge  -> 6 probability is 0x50000000 / 0x80000000 = 62.50%
 
 4:                                                ; preds = %2
   %5 = tail call i32 @f() #2
   br label %8
-; CHECK:   edge  ->  probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
+; CHECK:   edge 4 -> 8 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
 
 6:                                                ; preds = %2
   %7 = tail call i32 @g() #2
   br label %8
-; CHECK:   edge  ->  probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
+; CHECK:   edge 6 -> 8 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
 
 8:                                                ; preds = %6, %4
   %9 = phi i32 [ %5, %4 ], [ %7, %6 ]
@@ -26,18 +26,18 @@ define i32 @cmp2(ptr readnone %0, ptr readnone %1) {
 ; CHECK-LABEL: 'cmp2'
   %3 = icmp eq ptr %0, %1
   br i1 %3, label %6, label %4
-; CHECK:   edge  ->  probability is 0x30000000 / 0x80000000 = 37.50%
-; CHECK:   edge  ->  probability is 0x50000000 / 0x80000000 = 62.50%
+; CHECK:   edge  -> 6 probability is 0x30000000 / 0x80000000 = 37.50%
+; CHECK:   edge  -> 4 probability is 0x50000000 / 0x80000000 = 62.50%
 
 4:                                                ; preds = %2
   %5 = tail call i32 @f() #2
   br label %8
-; CHECK:   edge  ->  probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
+; CHECK:   edge 4 -> 8 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
 
 6:                                                ; preds = %2
   %7 = tail call i32 @g() #2
   br label %8
-; CHECK:   edge  ->  probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
+; CHECK:   edge 6 -> 8 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
 
 8:                                                ; preds = %6, %4
   %9 = phi i32 [ %5, %4 ], [ %7, %6 ]
@@ -48,18 +48,18 @@ define i32 @cmp3(ptr readnone %0) {
 ; CHECK-LABEL: 'cmp3'
   %2 = icmp eq ptr %0, null
   br i1 %2, label %3, label %5
-; CHECK:   edge  ->  probability is 0x30000000 / 0x80000000 = 37.50%
-; CHECK:   edge  ->  probability is 0x50000000 / 0x80000000 = 62.50%
+; CHECK:   edge  -> 3 probability is 0x30000000 / 0x80000000 = 37.50%
+; CHECK:   edge  -> 5 probability is 0x50000000 / 0x80000000 = 62.50%
 
 3:                                                ; preds = %1
   %4 = tail call i32 @f() #2
   br label %7
-; CHECK:   edge  ->  probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
+; CHECK:   edge 3 -> 7 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
 
 5:                                                ; preds = %1
   %6 = tail call i32 @g() #2
   br label %7
-; CHECK:   edge  ->  probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
+; CHECK:   edge 5 -> 7 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
 
 7:                                                ; preds = %5, %3
   %8 = phi i32 [ %6, %5 ], [ %4, %3 ]

Copy link
Member

@jmorse jmorse left a comment

Choose a reason for hiding this comment

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

I'm not an expert on branch-probability facilities, but the test changes look highly valuable,

It seems awkward to add an extra flag to the block-printer, as it introduces a number of conditionals -- would it be possible to refactor as a dedicated printBlockName method rather than an extra option for block printing?

Copy link
Contributor

@MatzeB MatzeB left a comment

Choose a reason for hiding this comment

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

Can you use Value::printAsOperand ?

@mtrofin
Copy link
Member Author

mtrofin commented Dec 1, 2023

Can you use Value::printAsOperand ?

Ah, nice! Yes. Only thing is that this will re-initialize a SlotTracker for every edge vertex, but probably this inefficiency doesn't matter for the scenario. If it does, we can address it later.

@mtrofin
Copy link
Member Author

mtrofin commented Dec 1, 2023

I'm not an expert on branch-probability facilities, but the test changes look highly valuable,

It seems awkward to add an extra flag to the block-printer, as it introduces a number of conditionals -- would it be possible to refactor as a dedicated printBlockName method rather than an extra option for block printing?

I think @MatzeB's suggestion tackles this, ptal.

Copy link
Contributor

@MatzeB MatzeB left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@MatzeB MatzeB left a comment

Choose a reason for hiding this comment

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

Consider using utils/update_analyze_test_checks.py to create the check lines...

@llvmbot llvmbot added PGO Profile Guided Optimizations llvm:transforms labels Dec 1, 2023
@mtrofin
Copy link
Member Author

mtrofin commented Dec 1, 2023

Consider using utils/update_analyze_test_checks.py to create the check lines...

Ack - I did for the new test, and updated the remaining tests - since now all the BB names have a preceding %.

@mtrofin mtrofin changed the title [bpi] Reuse the AsmWriter's BB naming scheme [BPI] Reuse the AsmWriter's BB naming scheme in BranchProbabilityPrinterPass Dec 1, 2023
@mtrofin mtrofin merged commit bb6497f into llvm:main Dec 2, 2023
@mtrofin mtrofin deleted the slot branch December 2, 2023 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding llvm:ir llvm:transforms PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants