[llvm] Use the Propeller CFG profile in the PGO analysis map if it is available. (PR #163252)

Rahman Lavaee via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 20 22:21:25 PDT 2025


https://github.com/rlavaee updated https://github.com/llvm/llvm-project/pull/163252

>From 0903d669c62d9c168c5a3ac85bbbe59a2d943622 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 17:29:55 +0000
Subject: [PATCH 01/10] Emit the PGO analysis map based on the Propeller
 profile.

---
 .../CodeGen/BasicBlockSectionsProfileReader.h | 49 ++++++++---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    | 87 ++++++++++++++-----
 .../BasicBlockSectionsProfileReader.cpp       | 25 +-----
 .../X86/basic-block-sections-pgo-features.ll  | 64 ++++++++++++++
 4 files changed, 167 insertions(+), 58 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll

diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 82dd5feb31dba..3c0e26bad7a5b 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -42,18 +42,40 @@ struct BBClusterInfo {
   unsigned PositionInCluster;
 };
 
+// This represents the CFG profile data for a function.
+struct CFGProfile {
+  // Node counts for each basic block.
+  DenseMap<UniqueBBID, uint64_t> NodeCounts;
+  // Edge counts for each edge, stored as a nested map.
+  DenseMap<UniqueBBID, DenseMap<UniqueBBID, uint64_t>> EdgeCounts;
+
+  // Returns the profile count for the given basic block or zero if it does not
+  // exist.
+  uint64_t getNodeCount(const UniqueBBID &BBID) const {
+    return NodeCounts.lookup(BBID);
+  }
+
+  // Returns the profile count for the edge from `SrcBBID` to `SinkBBID` or
+  // zero if it does not exist.
+  uint64_t getEdgeCount(const UniqueBBID &SrcBBID,
+                        const UniqueBBID &SinkBBID) const {
+    auto It = EdgeCounts.find(SrcBBID);
+    if (It == EdgeCounts.end())
+      return 0;
+    return It->second.lookup(SinkBBID);
+  }
+};
+
 // This represents the raw input profile for one function.
-struct FunctionPathAndClusterInfo {
+struct FunctionProfile {
   // BB Cluster information specified by `UniqueBBID`s.
   SmallVector<BBClusterInfo> ClusterInfo;
   // Paths to clone. A path a -> b -> c -> d implies cloning b, c, and d along
   // the edge a -> b (a is not cloned). The index of the path in this vector
   // determines the `UniqueBBID::CloneID` of the cloned blocks in that path.
   SmallVector<SmallVector<unsigned>> ClonePaths;
-  // Node counts for each basic block.
-  DenseMap<UniqueBBID, uint64_t> NodeCounts;
-  // Edge counts for each edge, stored as a nested map.
-  DenseMap<UniqueBBID, DenseMap<UniqueBBID, uint64_t>> EdgeCounts;
+  // CFG profile data.
+  CFGProfile CFG;
 };
 
 class BasicBlockSectionsProfileReader {
@@ -81,10 +103,14 @@ class BasicBlockSectionsProfileReader {
   SmallVector<SmallVector<unsigned>>
   getClonePathsForFunction(StringRef FuncName) const;
 
-  // Returns the profile count for the edge from `SrcBBID` to `SinkBBID` in
-  // function `FuncName` or zero if it does not exist.
-  uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID,
-                        const UniqueBBID &SinkBBID) const;
+  // Returns a pointer to the CFGProfile for the given function.
+  // Returns nullptr if no profile data is available for the function.
+  const CFGProfile *getFunctionCFGProfile(StringRef FuncName) const {
+    auto It = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
+    if (It == ProgramPathAndClusterInfo.end())
+      return nullptr;
+    return &It->second.CFG;
+  }
 
 private:
   StringRef getAliasName(StringRef FuncName) const {
@@ -132,7 +158,7 @@ class BasicBlockSectionsProfileReader {
   // for (all or some of) its basic blocks. The cluster information for every
   // basic block includes its cluster ID along with the position of the basic
   // block in that cluster.
-  StringMap<FunctionPathAndClusterInfo> ProgramPathAndClusterInfo;
+  StringMap<FunctionProfile> ProgramPathAndClusterInfo;
 
   // Some functions have alias names. We use this map to find the main alias
   // name which appears in ProgramPathAndClusterInfo as a key.
@@ -192,9 +218,6 @@ class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
   SmallVector<SmallVector<unsigned>>
   getClonePathsForFunction(StringRef FuncName) const;
 
-  uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID,
-                        const UniqueBBID &DestBBID) const;
-
   // Initializes the FunctionNameToDIFilename map for the current module and
   // then reads the profile for the matching functions.
   bool doInitialization(Module &M) override;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 219bbc9d5cdd4..3544033ead5f5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -37,6 +37,7 @@
 #include "llvm/BinaryFormat/COFF.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
 #include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/GCMetadataPrinter.h"
 #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
@@ -1531,38 +1532,80 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
     assert(BBAddrMapVersion >= 2 &&
            "PGOAnalysisMap only supports version 2 or later");
 
+    const BasicBlockSectionsProfileReader *BBSPR = nullptr;
+    if (auto *BBSPRPass =
+            getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>())
+      BBSPR = &BBSPRPass->getBBSPR();
+
+    const CFGProfile *FuncCFGProfile = nullptr;
+    if (BBSPR)
+      FuncCFGProfile = BBSPR->getFunctionCFGProfile(MF.getFunction().getName());
+
     if (Features.FuncEntryCount) {
       OutStreamer->AddComment("function entry count");
-      auto MaybeEntryCount = MF.getFunction().getEntryCount();
-      OutStreamer->emitULEB128IntValue(
-          MaybeEntryCount ? MaybeEntryCount->getCount() : 0);
+      uint64_t EntryCount = 0;
+      if (FuncCFGProfile) {
+        EntryCount = FuncCFGProfile->getNodeCount(*MF.front().getBBID());
+      } else {
+        auto MaybeEntryCount = MF.getFunction().getEntryCount();
+        EntryCount = MaybeEntryCount ? MaybeEntryCount->getCount() : 0;
+      }
+      OutStreamer->emitULEB128IntValue(EntryCount);
     }
-    const MachineBlockFrequencyInfo *MBFI =
-        Features.BBFreq
-            ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
-            : nullptr;
-    const MachineBranchProbabilityInfo *MBPI =
-        Features.BrProb
-            ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()
-            : nullptr;
-
-    if (Features.BBFreq || Features.BrProb) {
-      for (const MachineBasicBlock &MBB : MF) {
-        if (Features.BBFreq) {
-          OutStreamer->AddComment("basic block frequency");
+
+    if (FuncCFGProfile) {
+      if (Features.BBFreq) {
+        // Basic Block Frequencies from BBSPR NodeCounts.
+        for (const MachineBasicBlock &MBB : MF) {
+          OutStreamer->AddComment("basic block frequency (from BBSPR)");
           OutStreamer->emitULEB128IntValue(
-              MBFI->getBlockFreq(&MBB).getFrequency());
+              FuncCFGProfile->getNodeCount(*MBB.getBBID()));
         }
-        if (Features.BrProb) {
-          unsigned SuccCount = MBB.succ_size();
+      }
+      if (Features.BrProb) {
+        // Branch Probabilities from BBSPR EdgeCounts.
+        for (const MachineBasicBlock &MBB : MF) {
           OutStreamer->AddComment("basic block successor count");
-          OutStreamer->emitULEB128IntValue(SuccCount);
+          OutStreamer->emitULEB128IntValue(MBB.succ_size());
           for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
             OutStreamer->AddComment("successor BB ID");
             OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
-            OutStreamer->AddComment("successor branch probability");
+            // Emit the numerator of the probability.
+            OutStreamer->AddComment("successor branch probability (from BBSPR)");
             OutStreamer->emitULEB128IntValue(
-                MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());
+                FuncCFGProfile->getEdgeCount(*MBB.getBBID(), *SuccMBB->getBBID()));
+          }
+        }
+      }
+    } else {
+      // Fallback to MBFI and MBPI if BBSPR data is not available.
+      const MachineBlockFrequencyInfo *MBFI =
+          Features.BBFreq
+              ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
+              : nullptr;
+      const MachineBranchProbabilityInfo *MBPI =
+          Features.BrProb ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
+                                 .getMBPI()
+                          : nullptr;
+
+      if (Features.BBFreq || Features.BrProb) {
+        for (const MachineBasicBlock &MBB : MF) {
+          if (Features.BBFreq) {
+            OutStreamer->AddComment("basic block frequency");
+            OutStreamer->emitULEB128IntValue(
+                MBFI->getBlockFreq(&MBB).getFrequency());
+          }
+          if (Features.BrProb) {
+            unsigned SuccCount = MBB.succ_size();
+            OutStreamer->AddComment("basic block successor count");
+            OutStreamer->emitULEB128IntValue(SuccCount);
+            for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
+              OutStreamer->AddComment("successor BB ID");
+              OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
+              OutStreamer->AddComment("successor branch probability");
+              OutStreamer->emitULEB128IntValue(
+                  MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());
+            }
           }
         }
       }
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index fbcd614b85d18..71a12e79fdd85 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -76,21 +76,6 @@ BasicBlockSectionsProfileReader::getClonePathsForFunction(
   return ProgramPathAndClusterInfo.lookup(getAliasName(FuncName)).ClonePaths;
 }
 
-uint64_t BasicBlockSectionsProfileReader::getEdgeCount(
-    StringRef FuncName, const UniqueBBID &SrcBBID,
-    const UniqueBBID &SinkBBID) const {
-  auto It = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
-  if (It == ProgramPathAndClusterInfo.end())
-    return 0;
-  auto NodeIt = It->second.EdgeCounts.find(SrcBBID);
-  if (NodeIt == It->second.EdgeCounts.end())
-    return 0;
-  auto EdgeIt = NodeIt->second.find(SinkBBID);
-  if (EdgeIt == NodeIt->second.end())
-    return 0;
-  return EdgeIt->second;
-}
-
 // Reads the version 1 basic block sections profile. Profile for each function
 // is encoded as follows:
 //   m <module_name>
@@ -279,10 +264,10 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
                 Twine("unsigned integer expected: '") + CountStr + "'");
           if (i == 0) {
             // The first element represents the source and its total count.
-            FI->second.NodeCounts[SrcBBID = *BBID] = Count;
+            FI->second.CFG.NodeCounts[SrcBBID = *BBID] = Count;
             continue;
           }
-          FI->second.EdgeCounts[SrcBBID][*BBID] = Count;
+          FI->second.CFG.EdgeCounts[SrcBBID][*BBID] = Count;
         }
       }
       continue;
@@ -487,12 +472,6 @@ BasicBlockSectionsProfileReaderWrapperPass::getClonePathsForFunction(
   return BBSPR.getClonePathsForFunction(FuncName);
 }
 
-uint64_t BasicBlockSectionsProfileReaderWrapperPass::getEdgeCount(
-    StringRef FuncName, const UniqueBBID &SrcBBID,
-    const UniqueBBID &SinkBBID) const {
-  return BBSPR.getEdgeCount(FuncName, SrcBBID, SinkBBID);
-}
-
 BasicBlockSectionsProfileReader &
 BasicBlockSectionsProfileReaderWrapperPass::getBBSPR() {
   return BBSPR;
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
new file mode 100644
index 0000000000000..e46dba51c716b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -0,0 +1,64 @@
+; Verify PGO analysis map features with basic block sections profile.
+;
+; RUN: echo 'v1' > %t
+; RUN: echo 'f foo' >> %t
+; RUN: echo 'g 0:1000,1:800,2:200 1:800,3:800 2:200,3:200 3:1000' >> %t
+; RUN: echo 'c 0 1 2' >> %t
+;
+; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -basic-block-address-map -pgo-analysis-map=all | FileCheck %s
+
+define void @foo() nounwind !prof !0 {
+entry:
+  br label %bb1
+
+bb1:
+  br i1 undef, label %bb2, label %bb3, !prof !1
+
+bb2:
+  br label %bb3
+
+bb3:
+  ret void
+}
+
+!0 = !{!"function_entry_count", i64 1500}
+!1 = !{!"branch_weights", i32 1200, i32 300}
+
+; CHECK: .section .text.foo,"ax", at progbits
+; CHECK-LABEL: foo:
+; CHECK: .LBB_END0_0:
+; CHECK-LABEL: .LBB0_1:
+; CHECK: .LBB_END0_1:
+; CHECK-LABEL: .LBB0_2:
+; CHECK: .LBB_END0_2:
+; CHECK-LABEL: foo.cold:
+; CHECK: .LBB_END0_3:
+
+; CHECK: 	.section	.llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.foo
+; CHECK-NEXT:	.byte	3		# version
+; CHECK-NEXT:	.byte	15		# feature
+; CHECK:	.quad	.Lfunc_begin0	# base address
+; CHECK:	.byte	0		# BB id
+; CHECK:	.byte	1		# BB id
+; CHECK:	.byte	2		# BB id
+; CHECK:	.byte	3		# BB id
+
+; PGO Analysis Map
+; CHECK:	.ascii	"\350\007"	# function entry count
+; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency (from BBSPR)
+; CHECK-NEXT:	.ascii	"\240\006"	# basic block frequency (from BBSPR)
+; CHECK-NEXT:	.ascii	"\310\001"	# basic block frequency (from BBSPR)
+; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency (from BBSPR)
+; CHECK-NEXT:	.byte	1		# basic block successor count
+; CHECK-NEXT:	.byte	1		# successor BB ID
+; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.byte	2		# basic block successor count
+; CHECK-NEXT:	.byte	2		# successor BB ID
+; CHECK-NEXT:	.byte	0		# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.byte	3		# successor BB ID
+; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.byte	1		# basic block successor count
+; CHECK-NEXT:	.byte	3		# successor BB ID
+; CHECK-NEXT:	.ascii	"\310\001"	# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.byte	0		# basic block successor count
+

>From c22ac4dc0c47c916f3138bdfec2022e6a742644f Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 17:30:07 +0000
Subject: [PATCH 02/10] clang-format.

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 3544033ead5f5..f84f15b84f2ba 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1533,8 +1533,8 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
            "PGOAnalysisMap only supports version 2 or later");
 
     const BasicBlockSectionsProfileReader *BBSPR = nullptr;
-    if (auto *BBSPRPass =
-            getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>())
+    if (auto *BBSPRPass = getAnalysisIfAvailable<
+            BasicBlockSectionsProfileReaderWrapperPass>())
       BBSPR = &BBSPRPass->getBBSPR();
 
     const CFGProfile *FuncCFGProfile = nullptr;
@@ -1571,9 +1571,10 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
             OutStreamer->AddComment("successor BB ID");
             OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
             // Emit the numerator of the probability.
-            OutStreamer->AddComment("successor branch probability (from BBSPR)");
-            OutStreamer->emitULEB128IntValue(
-                FuncCFGProfile->getEdgeCount(*MBB.getBBID(), *SuccMBB->getBBID()));
+            OutStreamer->AddComment(
+                "successor branch probability (from BBSPR)");
+            OutStreamer->emitULEB128IntValue(FuncCFGProfile->getEdgeCount(
+                *MBB.getBBID(), *SuccMBB->getBBID()));
           }
         }
       }
@@ -1584,9 +1585,10 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
               ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
               : nullptr;
       const MachineBranchProbabilityInfo *MBPI =
-          Features.BrProb ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
-                                 .getMBPI()
-                          : nullptr;
+          Features.BrProb
+              ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
+                     .getMBPI()
+              : nullptr;
 
       if (Features.BBFreq || Features.BrProb) {
         for (const MachineBasicBlock &MBB : MF) {

>From d10f3404ebed5887a9f1f80ed861bb0fb31e42bc Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 18:36:27 +0000
Subject: [PATCH 03/10] Refine and extend the test.

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    | 73 +++++++------------
 .../X86/basic-block-sections-pgo-features.ll  | 64 +++++++++++-----
 2 files changed, 72 insertions(+), 65 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index f84f15b84f2ba..1a770013ec199 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1532,15 +1532,28 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
     assert(BBAddrMapVersion >= 2 &&
            "PGOAnalysisMap only supports version 2 or later");
 
+    // We will emit the BBSPR profile data if availale. Otherwise, we fall back
+    // to MBFI and MBPI.
     const BasicBlockSectionsProfileReader *BBSPR = nullptr;
     if (auto *BBSPRPass = getAnalysisIfAvailable<
             BasicBlockSectionsProfileReaderWrapperPass>())
       BBSPR = &BBSPRPass->getBBSPR();
 
+
     const CFGProfile *FuncCFGProfile = nullptr;
     if (BBSPR)
       FuncCFGProfile = BBSPR->getFunctionCFGProfile(MF.getFunction().getName());
 
+    const MachineBlockFrequencyInfo *MBFI =
+          Features.BBFreq
+              ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
+              : nullptr;
+      const MachineBranchProbabilityInfo *MBPI =
+          Features.BrProb
+              ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
+                     .getMBPI()
+              : nullptr;
+
     if (Features.FuncEntryCount) {
       OutStreamer->AddComment("function entry count");
       uint64_t EntryCount = 0;
@@ -1553,65 +1566,31 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
       OutStreamer->emitULEB128IntValue(EntryCount);
     }
 
-    if (FuncCFGProfile) {
-      if (Features.BBFreq) {
-        // Basic Block Frequencies from BBSPR NodeCounts.
+        if (Features.BBFreq || Features.BrProb) {
         for (const MachineBasicBlock &MBB : MF) {
-          OutStreamer->AddComment("basic block frequency (from BBSPR)");
-          OutStreamer->emitULEB128IntValue(
-              FuncCFGProfile->getNodeCount(*MBB.getBBID()));
+
+      if (Features.BBFreq) {
+          OutStreamer->AddComment("basic block frequency");
+          uint64_t BlockFrequency = FuncCFGProfile ? FuncCFGProfile->getNodeCount(*MBB.getBBID()) :  MBFI->getBlockFreq(&MBB).getFrequency();
+          OutStreamer->emitULEB128IntValue(BlockFrequency);
         }
-      }
       if (Features.BrProb) {
-        // Branch Probabilities from BBSPR EdgeCounts.
-        for (const MachineBasicBlock &MBB : MF) {
           OutStreamer->AddComment("basic block successor count");
           OutStreamer->emitULEB128IntValue(MBB.succ_size());
           for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
             OutStreamer->AddComment("successor BB ID");
             OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
-            // Emit the numerator of the probability.
             OutStreamer->AddComment(
-                "successor branch probability (from BBSPR)");
-            OutStreamer->emitULEB128IntValue(FuncCFGProfile->getEdgeCount(
-                *MBB.getBBID(), *SuccMBB->getBBID()));
+                "successor branch probability");
+            // For MPBI, we emit the numerator of the probability. For BBSPR, we
+            // emit the raw edge count.
+            uint64_t EdgeFrequency = FuncCFGProfile ? FuncCFGProfile->getEdgeCount(
+                *MBB.getBBID(), *SuccMBB->getBBID()) : MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator();
+            OutStreamer->emitULEB128IntValue(EdgeFrequency);
           }
-        }
       }
-    } else {
-      // Fallback to MBFI and MBPI if BBSPR data is not available.
-      const MachineBlockFrequencyInfo *MBFI =
-          Features.BBFreq
-              ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
-              : nullptr;
-      const MachineBranchProbabilityInfo *MBPI =
-          Features.BrProb
-              ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
-                     .getMBPI()
-              : nullptr;
-
-      if (Features.BBFreq || Features.BrProb) {
-        for (const MachineBasicBlock &MBB : MF) {
-          if (Features.BBFreq) {
-            OutStreamer->AddComment("basic block frequency");
-            OutStreamer->emitULEB128IntValue(
-                MBFI->getBlockFreq(&MBB).getFrequency());
-          }
-          if (Features.BrProb) {
-            unsigned SuccCount = MBB.succ_size();
-            OutStreamer->AddComment("basic block successor count");
-            OutStreamer->emitULEB128IntValue(SuccCount);
-            for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
-              OutStreamer->AddComment("successor BB ID");
-              OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
-              OutStreamer->AddComment("successor branch probability");
-              OutStreamer->emitULEB128IntValue(
-                  MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());
-            }
-          }
-        }
       }
-    }
+        }
   }
 
   OutStreamer->popSection();
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
index e46dba51c716b..ff97066659f4d 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -24,15 +24,7 @@ bb3:
 !0 = !{!"function_entry_count", i64 1500}
 !1 = !{!"branch_weights", i32 1200, i32 300}
 
-; CHECK: .section .text.foo,"ax", at progbits
-; CHECK-LABEL: foo:
-; CHECK: .LBB_END0_0:
-; CHECK-LABEL: .LBB0_1:
-; CHECK: .LBB_END0_1:
-; CHECK-LABEL: .LBB0_2:
-; CHECK: .LBB_END0_2:
-; CHECK-LABEL: foo.cold:
-; CHECK: .LBB_END0_3:
+;; Verify that foo gets its PGO map from its Propeller CFG profile.
 
 ; CHECK: 	.section	.llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.foo
 ; CHECK-NEXT:	.byte	3		# version
@@ -43,22 +35,58 @@ bb3:
 ; CHECK:	.byte	2		# BB id
 ; CHECK:	.byte	3		# BB id
 
-; PGO Analysis Map
+; PGO Analysis Map for foo
 ; CHECK:	.ascii	"\350\007"	# function entry count
-; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency (from BBSPR)
-; CHECK-NEXT:	.ascii	"\240\006"	# basic block frequency (from BBSPR)
-; CHECK-NEXT:	.ascii	"\310\001"	# basic block frequency (from BBSPR)
-; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency (from BBSPR)
+; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency
 ; CHECK-NEXT:	.byte	1		# basic block successor count
 ; CHECK-NEXT:	.byte	1		# successor BB ID
-; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability
+; CHECK-NEXT:	.ascii	"\240\006"	# basic block frequency
 ; CHECK-NEXT:	.byte	2		# basic block successor count
 ; CHECK-NEXT:	.byte	2		# successor BB ID
-; CHECK-NEXT:	.byte	0		# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.byte	0		# successor branch probability
 ; CHECK-NEXT:	.byte	3		# successor BB ID
-; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability
+; CHECK-NEXT:	.ascii	"\310\001"	# basic block frequency
 ; CHECK-NEXT:	.byte	1		# basic block successor count
 ; CHECK-NEXT:	.byte	3		# successor BB ID
-; CHECK-NEXT:	.ascii	"\310\001"	# successor branch probability (from BBSPR)
+; CHECK-NEXT:	.ascii	"\310\001"	# successor branch probability
+; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency
 ; CHECK-NEXT:	.byte	0		# basic block successor count
 
+define void @bar() nounwind !prof !2 {
+entry:
+  br i1 undef, label %bb1, label %bb2, !prof !3
+
+bb1:
+  ret void
+
+bb2:
+  ret void
+}
+
+!2 = !{!"function_entry_count", i64 80}
+!3 = !{!"branch_weights", i32 2, i32 78}
+
+;; Verify that we emit the PGO map for bar although it doesn't have Propeller profile.
+
+; CHECK: 	.section	.llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.bar
+; CHECK-NEXT:	.byte	3		# version
+; CHECK-NEXT:	.byte	7		# feature
+; CHECK:	.quad	.Lfunc_begin1	# function address
+; CHECK:	.byte	0		# BB id
+; CHECK:	.byte	1		# BB id
+; CHECK:	.byte	2		# BB id
+
+; CHECK:	.byte	80                              # function entry count
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200 " # basic block frequency
+; CHECK-NEXT:	.byte	2                               # basic block successor count
+; CHECK-NEXT:	.byte	1                               # successor BB ID
+; CHECK-NEXT:	.ascii	"\200\200\200\200\004"          # successor branch probability
+; CHECK-NEXT:	.byte	2                               # successor BB ID
+; CHECK-NEXT:	.ascii	"\200\200\200\200\004"          # successor branch probability
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200\020" # basic block frequency
+; CHECK-NEXT:	.byte	0                               # basic block successor count
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200\020" # basic block frequency
+; CHECK-NEXT:	.byte	0                               # basic block successor count
+

>From 16814a40874fc25563307ec1ae9a5bfcbd043fd7 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 18:36:43 +0000
Subject: [PATCH 04/10] clang-format.

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 42 +++++++++++-----------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1a770013ec199..9adc65ee0c1b1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1539,20 +1539,18 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
             BasicBlockSectionsProfileReaderWrapperPass>())
       BBSPR = &BBSPRPass->getBBSPR();
 
-
     const CFGProfile *FuncCFGProfile = nullptr;
     if (BBSPR)
       FuncCFGProfile = BBSPR->getFunctionCFGProfile(MF.getFunction().getName());
 
     const MachineBlockFrequencyInfo *MBFI =
-          Features.BBFreq
-              ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
-              : nullptr;
-      const MachineBranchProbabilityInfo *MBPI =
-          Features.BrProb
-              ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
-                     .getMBPI()
-              : nullptr;
+        Features.BBFreq
+            ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
+            : nullptr;
+    const MachineBranchProbabilityInfo *MBPI =
+        Features.BrProb
+            ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()
+            : nullptr;
 
     if (Features.FuncEntryCount) {
       OutStreamer->AddComment("function entry count");
@@ -1566,31 +1564,35 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
       OutStreamer->emitULEB128IntValue(EntryCount);
     }
 
-        if (Features.BBFreq || Features.BrProb) {
-        for (const MachineBasicBlock &MBB : MF) {
+    if (Features.BBFreq || Features.BrProb) {
+      for (const MachineBasicBlock &MBB : MF) {
 
-      if (Features.BBFreq) {
+        if (Features.BBFreq) {
           OutStreamer->AddComment("basic block frequency");
-          uint64_t BlockFrequency = FuncCFGProfile ? FuncCFGProfile->getNodeCount(*MBB.getBBID()) :  MBFI->getBlockFreq(&MBB).getFrequency();
+          uint64_t BlockFrequency =
+              FuncCFGProfile ? FuncCFGProfile->getNodeCount(*MBB.getBBID())
+                             : MBFI->getBlockFreq(&MBB).getFrequency();
           OutStreamer->emitULEB128IntValue(BlockFrequency);
         }
-      if (Features.BrProb) {
+        if (Features.BrProb) {
           OutStreamer->AddComment("basic block successor count");
           OutStreamer->emitULEB128IntValue(MBB.succ_size());
           for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
             OutStreamer->AddComment("successor BB ID");
             OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
-            OutStreamer->AddComment(
-                "successor branch probability");
+            OutStreamer->AddComment("successor branch probability");
             // For MPBI, we emit the numerator of the probability. For BBSPR, we
             // emit the raw edge count.
-            uint64_t EdgeFrequency = FuncCFGProfile ? FuncCFGProfile->getEdgeCount(
-                *MBB.getBBID(), *SuccMBB->getBBID()) : MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator();
+            uint64_t EdgeFrequency =
+                FuncCFGProfile
+                    ? FuncCFGProfile->getEdgeCount(*MBB.getBBID(),
+                                                   *SuccMBB->getBBID())
+                    : MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator();
             OutStreamer->emitULEB128IntValue(EdgeFrequency);
           }
-      }
-      }
         }
+      }
+    }
   }
 
   OutStreamer->popSection();

>From b02b87aea00564c7e32f4115004c62cd56addea9 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 19:38:48 +0000
Subject: [PATCH 05/10] Fix a test comment.

---
 llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
index ff97066659f4d..f535b9f6bd9d2 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -68,7 +68,7 @@ bb2:
 !2 = !{!"function_entry_count", i64 80}
 !3 = !{!"branch_weights", i32 2, i32 78}
 
-;; Verify that we emit the PGO map for bar although it doesn't have Propeller profile.
+;; Verify that we emit the PGO map for bar which doesn't have Propeller profile.
 
 ; CHECK: 	.section	.llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.bar
 ; CHECK-NEXT:	.byte	3		# version

>From 3362e028bac8aac63c3e0bab3de6f04d996c91f1 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 22:36:44 +0000
Subject: [PATCH 06/10] Add flag to enable using the Propeller profile in PGO
 analysis map.

---
 .../CodeGen/BasicBlockSectionsProfileReader.h | 12 ++++++-----
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    | 20 ++++++++++---------
 .../BasicBlockSectionsProfileReader.cpp       |  5 +++++
 .../X86/basic-block-sections-pgo-features.ll  |  2 +-
 4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 3c0e26bad7a5b..4967365f1bfe5 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -43,7 +43,7 @@ struct BBClusterInfo {
 };
 
 // This represents the CFG profile data for a function.
-struct CFGProfile {
+struct CfgProfile {
   // Node counts for each basic block.
   DenseMap<UniqueBBID, uint64_t> NodeCounts;
   // Edge counts for each edge, stored as a nested map.
@@ -74,8 +74,8 @@ struct FunctionProfile {
   // the edge a -> b (a is not cloned). The index of the path in this vector
   // determines the `UniqueBBID::CloneID` of the cloned blocks in that path.
   SmallVector<SmallVector<unsigned>> ClonePaths;
-  // CFG profile data.
-  CFGProfile CFG;
+  // Cfg profile data (block and edge frequencies).
+  CfgProfile CFG;
 };
 
 class BasicBlockSectionsProfileReader {
@@ -103,9 +103,9 @@ class BasicBlockSectionsProfileReader {
   SmallVector<SmallVector<unsigned>>
   getClonePathsForFunction(StringRef FuncName) const;
 
-  // Returns a pointer to the CFGProfile for the given function.
+  // Returns a pointer to the CfgProfile for the given function.
   // Returns nullptr if no profile data is available for the function.
-  const CFGProfile *getFunctionCFGProfile(StringRef FuncName) const {
+  const CfgProfile *getFunctionCfgProfile(StringRef FuncName) const {
     auto It = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
     if (It == ProgramPathAndClusterInfo.end())
       return nullptr;
@@ -218,6 +218,8 @@ class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
   SmallVector<SmallVector<unsigned>>
   getClonePathsForFunction(StringRef FuncName) const;
 
+  const CfgProfile *getFunctionCfgProfile(StringRef FuncName) const;
+
   // Initializes the FunctionNameToDIFilename map for the current module and
   // then reads the profile for the matching functions.
   bool doInitialization(Module &M) override;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 9adc65ee0c1b1..06f57019da40a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -165,6 +165,10 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
         "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "
         "extracted from PGO related analysis."));
 
+static cl::opt<bool> PgoAnalysisMapUsePropellerCfg("pgo-analysis-map-use-propeller-cfg",
+cl::desc("If available, use the Propeller cfg profile in the PGO analysis map."),
+cl::Hidden, cl::init(false));
+
 static cl::opt<bool> BBAddrMapSkipEmitBBEntries(
     "basic-block-address-map-skip-bb-entries",
     cl::desc("Skip emitting basic block entries in the SHT_LLVM_BB_ADDR_MAP "
@@ -474,6 +478,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<GCModuleInfo>();
   AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
   AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
+  AU.addUsedIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
 }
 
 bool AsmPrinter::doInitialization(Module &M) {
@@ -1532,16 +1537,13 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
     assert(BBAddrMapVersion >= 2 &&
            "PGOAnalysisMap only supports version 2 or later");
 
-    // We will emit the BBSPR profile data if availale. Otherwise, we fall back
+    // We will emit the BBSPR profile data if requested and availale. Otherwise, we fall back
     // to MBFI and MBPI.
-    const BasicBlockSectionsProfileReader *BBSPR = nullptr;
-    if (auto *BBSPRPass = getAnalysisIfAvailable<
-            BasicBlockSectionsProfileReaderWrapperPass>())
-      BBSPR = &BBSPRPass->getBBSPR();
-
-    const CFGProfile *FuncCFGProfile = nullptr;
-    if (BBSPR)
-      FuncCFGProfile = BBSPR->getFunctionCFGProfile(MF.getFunction().getName());
+    const CfgProfile *FuncCFGProfile = nullptr;
+    if (PgoAnalysisMapUsePropellerCfg) {
+       if (auto *BBSPR = getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>())
+        FuncCFGProfile = BBSPR->getFunctionCfgProfile(MF.getFunction().getName());
+    }
 
     const MachineBlockFrequencyInfo *MBFI =
         Features.BBFreq
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index 71a12e79fdd85..49de0a351b5f5 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -472,6 +472,11 @@ BasicBlockSectionsProfileReaderWrapperPass::getClonePathsForFunction(
   return BBSPR.getClonePathsForFunction(FuncName);
 }
 
+
+const CfgProfile *BasicBlockSectionsProfileReaderWrapperPass::getFunctionCfgProfile(StringRef FuncName) const  {
+  return BBSPR.getFunctionCfgProfile(FuncName);
+}
+
 BasicBlockSectionsProfileReader &
 BasicBlockSectionsProfileReaderWrapperPass::getBBSPR() {
   return BBSPR;
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
index f535b9f6bd9d2..ee3a24177a466 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -5,7 +5,7 @@
 ; RUN: echo 'g 0:1000,1:800,2:200 1:800,3:800 2:200,3:200 3:1000' >> %t
 ; RUN: echo 'c 0 1 2' >> %t
 ;
-; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -basic-block-address-map -pgo-analysis-map=all | FileCheck %s
+; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -basic-block-address-map -pgo-analysis-map=all -pgo-analysis-map-use-propeller-cfg | FileCheck %s
 
 define void @foo() nounwind !prof !0 {
 entry:

>From d1fc65ba2b54c0f6418412ae1420b73fea85811b Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 22:36:56 +0000
Subject: [PATCH 07/10] clang-format.

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp     | 18 +++++++++++-------
 .../BasicBlockSectionsProfileReader.cpp        |  5 +++--
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 06f57019da40a..b54a89468afb6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -165,9 +165,11 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
         "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "
         "extracted from PGO related analysis."));
 
-static cl::opt<bool> PgoAnalysisMapUsePropellerCfg("pgo-analysis-map-use-propeller-cfg",
-cl::desc("If available, use the Propeller cfg profile in the PGO analysis map."),
-cl::Hidden, cl::init(false));
+static cl::opt<bool> PgoAnalysisMapUsePropellerCfg(
+    "pgo-analysis-map-use-propeller-cfg",
+    cl::desc(
+        "If available, use the Propeller cfg profile in the PGO analysis map."),
+    cl::Hidden, cl::init(false));
 
 static cl::opt<bool> BBAddrMapSkipEmitBBEntries(
     "basic-block-address-map-skip-bb-entries",
@@ -1537,12 +1539,14 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
     assert(BBAddrMapVersion >= 2 &&
            "PGOAnalysisMap only supports version 2 or later");
 
-    // We will emit the BBSPR profile data if requested and availale. Otherwise, we fall back
-    // to MBFI and MBPI.
+    // We will emit the BBSPR profile data if requested and availale. Otherwise,
+    // we fall back to MBFI and MBPI.
     const CfgProfile *FuncCFGProfile = nullptr;
     if (PgoAnalysisMapUsePropellerCfg) {
-       if (auto *BBSPR = getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>())
-        FuncCFGProfile = BBSPR->getFunctionCfgProfile(MF.getFunction().getName());
+      if (auto *BBSPR = getAnalysisIfAvailable<
+              BasicBlockSectionsProfileReaderWrapperPass>())
+        FuncCFGProfile =
+            BBSPR->getFunctionCfgProfile(MF.getFunction().getName());
     }
 
     const MachineBlockFrequencyInfo *MBFI =
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index 49de0a351b5f5..0fb8f3a1503cd 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -472,8 +472,9 @@ BasicBlockSectionsProfileReaderWrapperPass::getClonePathsForFunction(
   return BBSPR.getClonePathsForFunction(FuncName);
 }
 
-
-const CfgProfile *BasicBlockSectionsProfileReaderWrapperPass::getFunctionCfgProfile(StringRef FuncName) const  {
+const CfgProfile *
+BasicBlockSectionsProfileReaderWrapperPass::getFunctionCfgProfile(
+    StringRef FuncName) const {
   return BBSPR.getFunctionCfgProfile(FuncName);
 }
 

>From 497d39e30d3efffd05e631cb5a8ab7717af8ef7e Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Mon, 13 Oct 2025 22:52:16 +0000
Subject: [PATCH 08/10] Fix the undefs in test.

---
 .../test/CodeGen/X86/basic-block-sections-pgo-features.ll | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
index ee3a24177a466..21ff75a5cd354 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -7,12 +7,12 @@
 ;
 ; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -basic-block-address-map -pgo-analysis-map=all -pgo-analysis-map-use-propeller-cfg | FileCheck %s
 
-define void @foo() nounwind !prof !0 {
+define void @foo(i1 %cond) nounwind !prof !0 {
 entry:
   br label %bb1
 
 bb1:
-  br i1 undef, label %bb2, label %bb3, !prof !1
+  br i1 %cond, label %bb2, label %bb3, !prof !1
 
 bb2:
   br label %bb3
@@ -54,9 +54,9 @@ bb3:
 ; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency
 ; CHECK-NEXT:	.byte	0		# basic block successor count
 
-define void @bar() nounwind !prof !2 {
+define void @bar(i1 %cond) nounwind !prof !2 {
 entry:
-  br i1 undef, label %bb1, label %bb2, !prof !3
+  br i1 %cond, label %bb1, label %bb2, !prof !3
 
 bb1:
   ret void

>From 3ed21186ed6b64f9f88b9790b5ed097de020a124 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Tue, 14 Oct 2025 22:00:16 +0000
Subject: [PATCH 09/10] Change CFG to lower-case Cfg.

---
 .../llvm/CodeGen/BasicBlockSectionsProfileReader.h |  6 +++---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp         | 14 +++++++-------
 .../CodeGen/BasicBlockSectionsProfileReader.cpp    | 10 +++++-----
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 4967365f1bfe5..42771fbe18d60 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -42,7 +42,7 @@ struct BBClusterInfo {
   unsigned PositionInCluster;
 };
 
-// This represents the CFG profile data for a function.
+// This represents the cfg profile data for a function.
 struct CfgProfile {
   // Node counts for each basic block.
   DenseMap<UniqueBBID, uint64_t> NodeCounts;
@@ -75,7 +75,7 @@ struct FunctionProfile {
   // determines the `UniqueBBID::CloneID` of the cloned blocks in that path.
   SmallVector<SmallVector<unsigned>> ClonePaths;
   // Cfg profile data (block and edge frequencies).
-  CfgProfile CFG;
+  CfgProfile Cfg;
 };
 
 class BasicBlockSectionsProfileReader {
@@ -109,7 +109,7 @@ class BasicBlockSectionsProfileReader {
     auto It = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
     if (It == ProgramPathAndClusterInfo.end())
       return nullptr;
-    return &It->second.CFG;
+    return &It->second.Cfg;
   }
 
 private:
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d48af1136e4db..0d748217a1ed9 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1542,11 +1542,11 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
 
     // We will emit the BBSPR profile data if requested and availale. Otherwise,
     // we fall back to MBFI and MBPI.
-    const CfgProfile *FuncCFGProfile = nullptr;
+    const CfgProfile *FuncCfgProfile = nullptr;
     if (PgoAnalysisMapUsePropellerCfg) {
       if (auto *BBSPR = getAnalysisIfAvailable<
               BasicBlockSectionsProfileReaderWrapperPass>())
-        FuncCFGProfile =
+        FuncCfgProfile =
             BBSPR->getFunctionCfgProfile(MF.getFunction().getName());
     }
 
@@ -1562,8 +1562,8 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
     if (Features.FuncEntryCount) {
       OutStreamer->AddComment("function entry count");
       uint64_t EntryCount = 0;
-      if (FuncCFGProfile) {
-        EntryCount = FuncCFGProfile->getNodeCount(*MF.front().getBBID());
+      if (FuncCfgProfile) {
+        EntryCount = FuncCfgProfile->getNodeCount(*MF.front().getBBID());
       } else {
         auto MaybeEntryCount = MF.getFunction().getEntryCount();
         EntryCount = MaybeEntryCount ? MaybeEntryCount->getCount() : 0;
@@ -1577,7 +1577,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
         if (Features.BBFreq) {
           OutStreamer->AddComment("basic block frequency");
           uint64_t BlockFrequency =
-              FuncCFGProfile ? FuncCFGProfile->getNodeCount(*MBB.getBBID())
+              FuncCfgProfile ? FuncCfgProfile->getNodeCount(*MBB.getBBID())
                              : MBFI->getBlockFreq(&MBB).getFrequency();
           OutStreamer->emitULEB128IntValue(BlockFrequency);
         }
@@ -1591,8 +1591,8 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
             // For MPBI, we emit the numerator of the probability. For BBSPR, we
             // emit the raw edge count.
             uint64_t EdgeFrequency =
-                FuncCFGProfile
-                    ? FuncCFGProfile->getEdgeCount(*MBB.getBBID(),
+                FuncCfgProfile
+                    ? FuncCfgProfile->getEdgeCount(*MBB.getBBID(),
                                                    *SuccMBB->getBBID())
                     : MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator();
             OutStreamer->emitULEB128IntValue(EdgeFrequency);
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index 0fb8f3a1503cd..adab0e8956268 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -100,7 +100,7 @@ BasicBlockSectionsProfileReader::getClonePathsForFunction(
 // the edge 1->3. Within the given clusters, each cloned block is identified by
 // "<original block id>.<clone id>". For instance, 3.1 represents the first
 // clone of block 3. Original blocks are specified just with their block ids. A
-// block cloned multiple times appears with distinct clone ids. The CFG for bar
+// block cloned multiple times appears with distinct clone ids. The Cfg for bar
 // is shown below before and after cloning with its final clusters labeled.
 //
 // f main
@@ -240,12 +240,12 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
       }
       continue;
     }
-    case 'g': { // CFG profile specifier.
+    case 'g': { // Cfg profile specifier.
       // Skip the profile when we the profile iterator (FI) refers to the
       // past-the-end element.
       if (FI == ProgramPathAndClusterInfo.end())
         continue;
-      // For each node, its CFG profile is encoded as
+      // For each node, its Cfg profile is encoded as
       // <src>:<count>,<sink_1>:<count_1>,<sink_2>:<count_2>,...
       for (auto BasicBlockEdgeProfile : Values) {
         if (BasicBlockEdgeProfile.empty())
@@ -264,10 +264,10 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
                 Twine("unsigned integer expected: '") + CountStr + "'");
           if (i == 0) {
             // The first element represents the source and its total count.
-            FI->second.CFG.NodeCounts[SrcBBID = *BBID] = Count;
+            FI->second.Cfg.NodeCounts[SrcBBID = *BBID] = Count;
             continue;
           }
-          FI->second.CFG.EdgeCounts[SrcBBID][*BBID] = Count;
+          FI->second.Cfg.EdgeCounts[SrcBBID][*BBID] = Count;
         }
       }
       continue;

>From 7e89984eb0b30c38fea2aba5981750a02a4d694a Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Tue, 21 Oct 2025 05:19:29 +0000
Subject: [PATCH 10/10] Emit the Propeller CFG frequencies.

---
 .../CodeGen/BasicBlockSectionsProfileReader.h | 18 ++--
 llvm/include/llvm/Object/ELFTypes.h           | 16 ++--
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    | 95 +++++++++----------
 .../BasicBlockSectionsProfileReader.cpp       | 16 +---
 .../X86/basic-block-sections-pgo-features.ll  | 52 +++++-----
 5 files changed, 99 insertions(+), 98 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 42771fbe18d60..db21455f160b2 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -42,8 +42,8 @@ struct BBClusterInfo {
   unsigned PositionInCluster;
 };
 
-// This represents the cfg profile data for a function.
-struct CfgProfile {
+// This represents the CFG profile data for a function.
+struct CFGProfile {
   // Node counts for each basic block.
   DenseMap<UniqueBBID, uint64_t> NodeCounts;
   // Edge counts for each edge, stored as a nested map.
@@ -51,7 +51,7 @@ struct CfgProfile {
 
   // Returns the profile count for the given basic block or zero if it does not
   // exist.
-  uint64_t getNodeCount(const UniqueBBID &BBID) const {
+  uint64_t getBlockCount(const UniqueBBID &BBID) const {
     return NodeCounts.lookup(BBID);
   }
 
@@ -74,8 +74,8 @@ struct FunctionProfile {
   // the edge a -> b (a is not cloned). The index of the path in this vector
   // determines the `UniqueBBID::CloneID` of the cloned blocks in that path.
   SmallVector<SmallVector<unsigned>> ClonePaths;
-  // Cfg profile data (block and edge frequencies).
-  CfgProfile Cfg;
+  // CFG profile data.
+  CFGProfile CFG;
 };
 
 class BasicBlockSectionsProfileReader {
@@ -103,13 +103,13 @@ class BasicBlockSectionsProfileReader {
   SmallVector<SmallVector<unsigned>>
   getClonePathsForFunction(StringRef FuncName) const;
 
-  // Returns a pointer to the CfgProfile for the given function.
+  // Returns a pointer to the CFGProfile for the given function.
   // Returns nullptr if no profile data is available for the function.
-  const CfgProfile *getFunctionCfgProfile(StringRef FuncName) const {
+  const CFGProfile *getFunctionCFGProfile(StringRef FuncName) const {
     auto It = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
     if (It == ProgramPathAndClusterInfo.end())
       return nullptr;
-    return &It->second.Cfg;
+    return &It->second.CFG;
   }
 
 private:
@@ -218,8 +218,6 @@ class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
   SmallVector<SmallVector<unsigned>>
   getClonePathsForFunction(StringRef FuncName) const;
 
-  const CfgProfile *getFunctionCfgProfile(StringRef FuncName) const;
-
   // Initializes the FunctionNameToDIFilename map for the current module and
   // then reads the profile for the matching functions.
   bool doInitialization(Module &M) override;
diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h
index e9a417d3d4fb3..e6d4552168607 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -834,10 +834,13 @@ struct BBAddrMap {
     bool OmitBBEntries : 1;
     bool CallsiteEndOffsets : 1;
     bool BBHash : 1;
+    bool PropellerCFG : 1;
 
-    bool hasPGOAnalysis() const { return FuncEntryCount || BBFreq || BrProb; }
+    bool hasPGOAnalysis() const {
+      return FuncEntryCount || BBFreq || BrProb || PropellerCFG;
+    }
 
-    bool hasPGOAnalysisBBData() const { return BBFreq || BrProb; }
+    bool hasPGOAnalysisBBData() const { return BBFreq || BrProb || PropellerCFG; }
 
     // Encodes to minimum bit width representation.
     uint8_t encode() const {
@@ -847,7 +850,8 @@ struct BBAddrMap {
              (static_cast<uint8_t>(MultiBBRange) << 3) |
              (static_cast<uint8_t>(OmitBBEntries) << 4) |
              (static_cast<uint8_t>(CallsiteEndOffsets) << 5) |
-             (static_cast<uint8_t>(BBHash) << 6);
+             (static_cast<uint8_t>(BBHash) << 6) |
+             (static_cast<uint8_t>(PropellerCFG) << 7);
     }
 
     // Decodes from minimum bit width representation and validates no
@@ -857,7 +861,7 @@ struct BBAddrMap {
           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 << 5)),
-          static_cast<bool>(Val & (1 << 6))};
+          static_cast<bool>(Val & (1 << 6)), static_cast<bool>(Val & (1 << 7))};
       if (Feat.encode() != Val)
         return createStringError(
             std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
@@ -867,10 +871,10 @@ struct BBAddrMap {
 
     bool operator==(const Features &Other) const {
       return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange,
-                      OmitBBEntries, CallsiteEndOffsets, BBHash) ==
+                      OmitBBEntries, CallsiteEndOffsets, BBHash, PropellerCFG) ==
              std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
                       Other.MultiBBRange, Other.OmitBBEntries,
-                      Other.CallsiteEndOffsets, Other.BBHash);
+                      Other.CallsiteEndOffsets, Other.BBHash, Other.PropellerCFG);
     }
   };
 
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0d748217a1ed9..9ffaa53f8755f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -20,7 +20,6 @@
 #include "WinException.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
-#include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -120,6 +119,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/VCSRevision.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
@@ -149,6 +149,7 @@ enum class PGOMapFeaturesEnum {
   FuncEntryCount,
   BBFreq,
   BrProb,
+  PropellerCFG,
   All,
 };
 static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
@@ -160,17 +161,13 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
         clEnumValN(PGOMapFeaturesEnum::BBFreq, "bb-freq",
                    "Basic Block Frequency"),
         clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob", "Branch Probability"),
+        clEnumValN(PGOMapFeaturesEnum::PropellerCFG, "propeller-cfg",
+                   "Propeller CFG"),
         clEnumValN(PGOMapFeaturesEnum::All, "all", "Enable all options")),
     cl::desc(
         "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "
         "extracted from PGO related analysis."));
 
-static cl::opt<bool> PgoAnalysisMapUsePropellerCfg(
-    "pgo-analysis-map-use-propeller-cfg",
-    cl::desc(
-        "If available, use the Propeller cfg profile in the PGO analysis map."),
-    cl::Hidden, cl::init(false));
-
 static cl::opt<bool> BBAddrMapSkipEmitBBEntries(
     "basic-block-address-map-skip-bb-entries",
     cl::desc("Skip emitting basic block entries in the SHT_LLVM_BB_ADDR_MAP "
@@ -480,7 +477,6 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<GCModuleInfo>();
   AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
   AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
-  AU.addUsedIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
 }
 
 bool AsmPrinter::doInitialization(Module &M) {
@@ -1412,7 +1408,7 @@ static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
 
 static llvm::object::BBAddrMap::Features
 getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
-                    bool HasCalls) {
+                    bool HasCalls, const CFGProfile *FuncCFGProfile) {
   // Ensure that the user has not passed in additional options while also
   // specifying all or none.
   if ((PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::None) ||
@@ -1434,19 +1430,25 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
   bool BrProbEnabled =
       AllFeatures ||
       (!NoFeatures && PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb));
+  bool PropellerCFGEnabled =
+      FuncCFGProfile &&
+      (AllFeatures ||
+       (!NoFeatures &&
+        PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::PropellerCFG)));
 
   if ((BBFreqEnabled || BrProbEnabled) && BBAddrMapSkipEmitBBEntries) {
     MF.getFunction().getContext().emitError(
-        "BB entries info is required for BBFreq and BrProb "
-        "features");
+        "BB entries info is required for BBFreq and BrProb features");
   }
+
   return {FuncEntryCountEnabled,
           BBFreqEnabled,
           BrProbEnabled,
           MF.hasBBSections() && NumMBBSectionRanges > 1,
           static_cast<bool>(BBAddrMapSkipEmitBBEntries),
           HasCalls,
-          false};
+          false,
+          PropellerCFGEnabled};
 }
 
 void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
@@ -1455,6 +1457,14 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
   assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized.");
   bool HasCalls = !CurrentFnCallsiteEndSymbols.empty();
 
+  const BasicBlockSectionsProfileReader *BBSPR = nullptr;
+  if (auto *BBSPRPass =
+          getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>())
+    BBSPR = &BBSPRPass->getBBSPR();
+  const CFGProfile *FuncCFGProfile = nullptr;
+  if (BBSPR)
+    FuncCFGProfile = BBSPR->getFunctionCFGProfile(MF.getFunction().getName());
+
   const MCSymbol *FunctionSymbol = getFunctionBegin();
 
   OutStreamer->pushSection();
@@ -1463,7 +1473,8 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
   uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion();
   OutStreamer->emitInt8(BBAddrMapVersion);
   OutStreamer->AddComment("feature");
-  auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size(), HasCalls);
+  auto Features =
+      getBBAddrMapFeature(MF, MBBSectionRanges.size(), HasCalls, FuncCFGProfile);
   OutStreamer->emitInt8(Features.encode());
   // Emit BB Information for each basic block in the function.
   if (Features.MultiBBRange) {
@@ -1540,16 +1551,12 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
     assert(BBAddrMapVersion >= 2 &&
            "PGOAnalysisMap only supports version 2 or later");
 
-    // We will emit the BBSPR profile data if requested and availale. Otherwise,
-    // we fall back to MBFI and MBPI.
-    const CfgProfile *FuncCfgProfile = nullptr;
-    if (PgoAnalysisMapUsePropellerCfg) {
-      if (auto *BBSPR = getAnalysisIfAvailable<
-              BasicBlockSectionsProfileReaderWrapperPass>())
-        FuncCfgProfile =
-            BBSPR->getFunctionCfgProfile(MF.getFunction().getName());
+    if (Features.FuncEntryCount) {
+      OutStreamer->AddComment("function entry count");
+      auto MaybeEntryCount = MF.getFunction().getEntryCount();
+      OutStreamer->emitULEB128IntValue(
+          MaybeEntryCount ? MaybeEntryCount->getCount() : 0);
     }
-
     const MachineBlockFrequencyInfo *MBFI =
         Features.BBFreq
             ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
@@ -1559,43 +1566,33 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
             ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()
             : nullptr;
 
-    if (Features.FuncEntryCount) {
-      OutStreamer->AddComment("function entry count");
-      uint64_t EntryCount = 0;
-      if (FuncCfgProfile) {
-        EntryCount = FuncCfgProfile->getNodeCount(*MF.front().getBBID());
-      } else {
-        auto MaybeEntryCount = MF.getFunction().getEntryCount();
-        EntryCount = MaybeEntryCount ? MaybeEntryCount->getCount() : 0;
-      }
-      OutStreamer->emitULEB128IntValue(EntryCount);
-    }
-
     if (Features.BBFreq || Features.BrProb) {
       for (const MachineBasicBlock &MBB : MF) {
-
         if (Features.BBFreq) {
           OutStreamer->AddComment("basic block frequency");
-          uint64_t BlockFrequency =
-              FuncCfgProfile ? FuncCfgProfile->getNodeCount(*MBB.getBBID())
-                             : MBFI->getBlockFreq(&MBB).getFrequency();
-          OutStreamer->emitULEB128IntValue(BlockFrequency);
+          OutStreamer->emitULEB128IntValue(
+              MBFI->getBlockFreq(&MBB).getFrequency());
+          if (Features.PropellerCFG) {
+            OutStreamer->AddComment("basic block frequency (propeller)");
+            OutStreamer->emitULEB128IntValue(
+                FuncCFGProfile->getBlockCount(*MBB.getBBID()));
+          }
         }
         if (Features.BrProb) {
+          unsigned SuccCount = MBB.succ_size();
           OutStreamer->AddComment("basic block successor count");
-          OutStreamer->emitULEB128IntValue(MBB.succ_size());
+          OutStreamer->emitULEB128IntValue(SuccCount);
           for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
             OutStreamer->AddComment("successor BB ID");
             OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);
             OutStreamer->AddComment("successor branch probability");
-            // For MPBI, we emit the numerator of the probability. For BBSPR, we
-            // emit the raw edge count.
-            uint64_t EdgeFrequency =
-                FuncCfgProfile
-                    ? FuncCfgProfile->getEdgeCount(*MBB.getBBID(),
-                                                   *SuccMBB->getBBID())
-                    : MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator();
-            OutStreamer->emitULEB128IntValue(EdgeFrequency);
+            OutStreamer->emitULEB128IntValue(
+                MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());
+            if (Features.PropellerCFG) {
+              OutStreamer->AddComment("successor branch frequency (propeller)");
+              OutStreamer->emitULEB128IntValue(FuncCFGProfile->getEdgeCount(
+                  *MBB.getBBID(), *SuccMBB->getBBID()));
+            }
           }
         }
       }
@@ -1715,7 +1712,7 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
   return nullptr;
 }
 
-/// Emits .callgraph section.
+/// Emits .llvm.callgraph section.
 void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
                                       FunctionCallGraphInfo &FuncCGInfo) {
   if (!MF.getTarget().Options.EmitCallGraphSection)
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index adab0e8956268..71a12e79fdd85 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -100,7 +100,7 @@ BasicBlockSectionsProfileReader::getClonePathsForFunction(
 // the edge 1->3. Within the given clusters, each cloned block is identified by
 // "<original block id>.<clone id>". For instance, 3.1 represents the first
 // clone of block 3. Original blocks are specified just with their block ids. A
-// block cloned multiple times appears with distinct clone ids. The Cfg for bar
+// block cloned multiple times appears with distinct clone ids. The CFG for bar
 // is shown below before and after cloning with its final clusters labeled.
 //
 // f main
@@ -240,12 +240,12 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
       }
       continue;
     }
-    case 'g': { // Cfg profile specifier.
+    case 'g': { // CFG profile specifier.
       // Skip the profile when we the profile iterator (FI) refers to the
       // past-the-end element.
       if (FI == ProgramPathAndClusterInfo.end())
         continue;
-      // For each node, its Cfg profile is encoded as
+      // For each node, its CFG profile is encoded as
       // <src>:<count>,<sink_1>:<count_1>,<sink_2>:<count_2>,...
       for (auto BasicBlockEdgeProfile : Values) {
         if (BasicBlockEdgeProfile.empty())
@@ -264,10 +264,10 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
                 Twine("unsigned integer expected: '") + CountStr + "'");
           if (i == 0) {
             // The first element represents the source and its total count.
-            FI->second.Cfg.NodeCounts[SrcBBID = *BBID] = Count;
+            FI->second.CFG.NodeCounts[SrcBBID = *BBID] = Count;
             continue;
           }
-          FI->second.Cfg.EdgeCounts[SrcBBID][*BBID] = Count;
+          FI->second.CFG.EdgeCounts[SrcBBID][*BBID] = Count;
         }
       }
       continue;
@@ -472,12 +472,6 @@ BasicBlockSectionsProfileReaderWrapperPass::getClonePathsForFunction(
   return BBSPR.getClonePathsForFunction(FuncName);
 }
 
-const CfgProfile *
-BasicBlockSectionsProfileReaderWrapperPass::getFunctionCfgProfile(
-    StringRef FuncName) const {
-  return BBSPR.getFunctionCfgProfile(FuncName);
-}
-
 BasicBlockSectionsProfileReader &
 BasicBlockSectionsProfileReaderWrapperPass::getBBSPR() {
   return BBSPR;
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
index 21ff75a5cd354..ad55e86e62e25 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -5,7 +5,7 @@
 ; RUN: echo 'g 0:1000,1:800,2:200 1:800,3:800 2:200,3:200 3:1000' >> %t
 ; RUN: echo 'c 0 1 2' >> %t
 ;
-; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -basic-block-address-map -pgo-analysis-map=all -pgo-analysis-map-use-propeller-cfg | FileCheck %s
+; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -basic-block-address-map -pgo-analysis-map=all | FileCheck %s
 
 define void @foo(i1 %cond) nounwind !prof !0 {
 entry:
@@ -24,35 +24,42 @@ bb3:
 !0 = !{!"function_entry_count", i64 1500}
 !1 = !{!"branch_weights", i32 1200, i32 300}
 
-;; Verify that foo gets its PGO map from its Propeller CFG profile.
+;; Verify that foo's PGO map contains both IRPGO and Propeller CFG profiles.
 
 ; CHECK: 	.section	.llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.foo
 ; CHECK-NEXT:	.byte	3		# version
-; CHECK-NEXT:	.byte	15		# feature
+; CHECK-NEXT:	.byte	143		# feature
 ; CHECK:	.quad	.Lfunc_begin0	# base address
 ; CHECK:	.byte	0		# BB id
 ; CHECK:	.byte	1		# BB id
 ; CHECK:	.byte	2		# BB id
 ; CHECK:	.byte	3		# BB id
 
-; PGO Analysis Map for foo
-; CHECK:	.ascii	"\350\007"	# function entry count
-; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency
-; CHECK-NEXT:	.byte	1		# basic block successor count
-; CHECK-NEXT:	.byte	1		# successor BB ID
-; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability
-; CHECK-NEXT:	.ascii	"\240\006"	# basic block frequency
-; CHECK-NEXT:	.byte	2		# basic block successor count
-; CHECK-NEXT:	.byte	2		# successor BB ID
-; CHECK-NEXT:	.byte	0		# successor branch probability
-; CHECK-NEXT:	.byte	3		# successor BB ID
-; CHECK-NEXT:	.ascii	"\240\006"	# successor branch probability
-; CHECK-NEXT:	.ascii	"\310\001"	# basic block frequency
-; CHECK-NEXT:	.byte	1		# basic block successor count
-; CHECK-NEXT:	.byte	3		# successor BB ID
-; CHECK-NEXT:	.ascii	"\310\001"	# successor branch probability
-; CHECK-NEXT:	.ascii	"\350\007"	# basic block frequency
-; CHECK-NEXT:	.byte	0		# basic block successor count
+; CHECK:	.ascii	"\334\013"				# function entry count
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200 "		# basic block frequency
+; CHECK-NEXT:	.ascii	"\350\007"				# basic block frequency (propeller)
+; CHECK-NEXT:	.byte	1					# basic block successor count
+; CHECK-NEXT:	.byte	1					# successor BB ID
+; CHECK-NEXT:	.ascii	"\200\200\200\200\b"			# successor branch probability
+; CHECK-NEXT:	.ascii	"\240\006"				# successor branch frequency (propeller)
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200 " 	# basic block frequency
+; CHECK-NEXT:	.ascii	"\240\006"				# basic block frequency (propeller)
+; CHECK-NEXT:	.byte	2					# basic block successor count
+; CHECK-NEXT:	.byte	2					# successor BB ID
+; CHECK-NEXT:	.ascii	"\200\200\200\200\004"			# successor branch probability
+; CHECK-NEXT:	.byte	0					# successor branch frequency (propeller)
+; CHECK-NEXT:	.byte	3					# successor BB ID
+; CHECK-NEXT:	.ascii	"\200\200\200\200\004"			# successor branch probability
+; CHECK-NEXT:	.ascii	"\240\006"				# successor branch frequency (propeller)
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200\020"	# basic block frequency
+; CHECK-NEXT:	.ascii	"\310\001"				# basic block frequency (propeller)
+; CHECK-NEXT:	.byte	1					# basic block successor count
+; CHECK-NEXT:	.byte	3					# successor BB ID
+; CHECK-NEXT:	.ascii	"\200\200\200\200\b"			# successor branch probability
+; CHECK-NEXT:	.ascii	"\310\001"				# successor branch frequency (propeller)
+; CHECK-NEXT:	.ascii	"\200\200\200\200\200\200\200 "		# basic block frequency
+; CHECK-NEXT:	.ascii	"\350\007"				# basic block frequency (propeller)
+; CHECK-NEXT:	.byte	0					# basic block successor count
 
 define void @bar(i1 %cond) nounwind !prof !2 {
 entry:
@@ -68,7 +75,8 @@ bb2:
 !2 = !{!"function_entry_count", i64 80}
 !3 = !{!"branch_weights", i32 2, i32 78}
 
-;; Verify that we emit the PGO map for bar which doesn't have Propeller profile.
+;; Verify that the PGO map for bar only includes IRPGO data since it doesn't
+;; have Propeller profile.
 
 ; CHECK: 	.section	.llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.bar
 ; CHECK-NEXT:	.byte	3		# version



More information about the llvm-commits mailing list