[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
Wed Dec 10 23:59:54 PST 2025
https://github.com/rlavaee updated https://github.com/llvm/llvm-project/pull/163252
>From 1ed10b00056ac04fdc9933966bc0a3525b54a027 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 1/6] Emit the PGO analysis map based on the Propeller profile.
---
.../CodeGen/BasicBlockSectionsProfileReader.h | 46 ++++++--
llvm/include/llvm/MC/MCContext.h | 2 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 39 +++++--
.../BasicBlockSectionsProfileReader.cpp | 4 +-
.../basic-block-address-map-empty-function.ll | 2 +-
...sic-block-address-map-function-sections.ll | 6 +-
.../basic-block-address-map-pgo-features.ll | 2 +-
...k-address-map-with-basic-block-sections.ll | 2 +-
...sic-block-address-map-with-emit-bb-hash.ll | 2 +-
.../X86/basic-block-address-map-with-mfs.ll | 2 +-
.../CodeGen/X86/basic-block-address-map.ll | 2 +-
.../X86/basic-block-sections-pgo-features.ll | 100 ++++++++++++++++++
12 files changed, 181 insertions(+), 28 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 f0d28d863282e..9ace90fa61394 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 getBlockCount(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 (block and edge frequencies).
+ CfgProfile Cfg;
// Hash for each basic block. The Hashes are stored for every original block
// (not cloned blocks), hence the map key being unsigned instead of
// UniqueBBID.
@@ -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;
+ }
// Return the complete function path and cluster info for the given function.
std::pair<bool, FunctionPathAndClusterInfo>
@@ -136,7 +162,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.
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 74abe3403bbed..c5de76bd30b3f 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -175,7 +175,7 @@ class MCContext {
unsigned GetInstance(unsigned LocalLabelVal);
/// SHT_LLVM_BB_ADDR_MAP version to emit.
- uint8_t BBAddrMapVersion = 4;
+ uint8_t BBAddrMapVersion = 5;
/// The file name of the log file from the environment variable
/// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index c459b80baf4ab..c76b8c3e74bec 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"
@@ -37,6 +36,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"
@@ -150,6 +150,7 @@ enum class PGOMapFeaturesEnum {
FuncEntryCount,
BBFreq,
BrProb,
+ PropellerCFG,
All,
};
static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
@@ -166,6 +167,12 @@ 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> PgoAnalysisMapEmitBBSectionsCfg(
+ "pgo-analysis-map-emit-bb-sections-cfg",
+ cl::desc("Enable the post-link cfg information from the basic block "
+ "sections 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 "
@@ -479,6 +486,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
if (EmitBBHash)
AU.addRequired<MachineBlockHashInfo>();
+ AU.addUsedIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
}
bool AsmPrinter::doInitialization(Module &M) {
@@ -1411,7 +1419,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) ||
@@ -1433,17 +1441,17 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
bool BrProbEnabled =
AllFeatures ||
(!NoFeatures && PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb));
+ bool PostLinkCfgEnabled = FuncCfgProfile && PgoAnalysisMapEmitBBSectionsCfg;
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,
// Use static_cast to avoid breakage of tests on windows.
static_cast<bool>(BBAddrMapSkipEmitBBEntries), HasCalls,
- static_cast<bool>(EmitBBHash), false};
+ static_cast<bool>(EmitBBHash), PostLinkCfgEnabled};
}
void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
@@ -1452,6 +1460,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();
@@ -1460,7 +1476,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) {
@@ -1565,6 +1582,11 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
OutStreamer->AddComment("basic block frequency");
OutStreamer->emitULEB128IntValue(
MBFI->getBlockFreq(&MBB).getFrequency());
+ if (Features.PostLinkCfg) {
+ OutStreamer->AddComment("basic block frequency (propeller)");
+ OutStreamer->emitULEB128IntValue(
+ FuncCfgProfile->getBlockCount(*MBB.getBBID()));
+ }
}
if (Features.BrProb) {
unsigned SuccCount = MBB.succ_size();
@@ -1576,6 +1598,11 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
OutStreamer->AddComment("successor branch probability");
OutStreamer->emitULEB128IntValue(
MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());
+ if (Features.PostLinkCfg) {
+ OutStreamer->AddComment("successor branch frequency (propeller)");
+ OutStreamer->emitULEB128IntValue(FuncCfgProfile->getEdgeCount(
+ *MBB.getBBID(), *SuccMBB->getBBID()));
+ }
}
}
}
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index be1c60c57ccf4..8baa478c7c5c0 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -290,10 +290,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;
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll b/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll
index 423e31868bc5f..7457e3bdb24dc 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll
@@ -19,7 +19,7 @@ entry:
; CHECK: func:
; CHECK: .Lfunc_begin1:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text{{$}}
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; BASIC-NEXT: .byte 0 # feature
; PGO-NEXT: .byte 3 # feature
; CHECK-NEXT: .quad .Lfunc_begin1 # function address
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
index e32e5222bf016..bdfe1e4564fc1 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
@@ -10,7 +10,7 @@ define dso_local i32 @_Z3barv() {
; CHECK-LABEL: _Z3barv:
; CHECK-NEXT: [[BAR_BEGIN:.Lfunc_begin[0-9]+]]:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3barv{{$}}
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; CHECK-NEXT: .byte 0 # feature
; CHECK-NEXT: .quad [[BAR_BEGIN]] # function address
@@ -23,7 +23,7 @@ define dso_local i32 @_Z3foov() {
; CHECK-LABEL: _Z3foov:
; CHECK-NEXT: [[FOO_BEGIN:.Lfunc_begin[0-9]+]]:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3foov{{$}}
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; CHECK-NEXT: .byte 32 # feature
; CHECK-NEXT: .quad [[FOO_BEGIN]] # function address
@@ -36,6 +36,6 @@ define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat {
; CHECK-LABEL: _Z4fooTIiET_v:
; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]:
; CHECK: .section .llvm_bb_addr_map,"oG", at llvm_bb_addr_map,.text._Z4fooTIiET_v,_Z4fooTIiET_v,comdat{{$}}
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; CHECK-NEXT: .byte 0 # feature
; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]] # function address
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
index 12b1297ba97ce..ca3c8d18e7dc5 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
@@ -69,7 +69,7 @@ declare i32 @__gxx_personality_v0(...)
; CHECK-LABEL: .Lfunc_end0:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3bazb{{$}}
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; BASIC-NEXT: .byte 32 # feature
; PGO-ALL-NEXT: .byte 39 # feature
; FEC-ONLY-NEXT:.byte 33 # feature
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
index aeb6dc95e32f3..297cbd81ed036 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
@@ -47,7 +47,7 @@ declare i32 @__gxx_personality_v0(...)
; CHECK-LABEL: .Lfunc_end0:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.hot._Z3bazb
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; CHECK-NEXT: .byte 40 # feature
; CHECK-NEXT: .byte 2 # number of basic block ranges
; CHECK-NEXT: .quad .Lfunc_begin0 # base address
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll
index a567887753245..f17e9a5849150 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll
@@ -50,7 +50,7 @@ declare i32 @__gxx_personality_v0(...)
; UNIQ: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3bazb{{$}}
;; Verify that with -unique-section-names=false, the unique id of the text section gets assigned to the llvm_bb_addr_map section.
; NOUNIQ: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text,unique,1
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; CHECK-NEXT: .byte 96 # feature
; CHECK-NEXT: .quad .Lfunc_begin0 # function address
; CHECK-NEXT: .byte 6 # number of basic blocks
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
index d49b313679628..36e21b9b3faa7 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
@@ -58,7 +58,7 @@ declare i32 @qux()
; CHECK-LABEL: .Lfunc_end0:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.hot.foo
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; BASIC-NEXT: .byte 40 # feature
; PGO-NEXT: .byte 47 # feature
; CHECK-NEXT: .byte 2 # number of basic block ranges
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map.ll b/llvm/test/CodeGen/X86/basic-block-address-map.ll
index 64cf2c709f3df..523b939765525 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map.ll
@@ -52,7 +52,7 @@ declare i32 @__gxx_personality_v0(...)
; UNIQ: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3bazb{{$}}
;; Verify that with -unique-section-names=false, the unique id of the text section gets assigned to the llvm_bb_addr_map section.
; NOUNIQ: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text,unique,1
-; CHECK-NEXT: .byte 4 # version
+; CHECK-NEXT: .byte 5 # version
; CHECK-NEXT: .byte 32 # feature
; CHECK-NEXT: .quad .Lfunc_begin0 # function address
; CHECK-NEXT: .byte 6 # number of basic blocks
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..7f7d87369701b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -0,0 +1,100 @@
+; 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 -pgo-analysis-map-emit-bb-sections-cfg | FileCheck %s
+
+define void @foo(i1 %cond) nounwind !prof !0 {
+entry:
+ br label %bb1
+
+bb1:
+ br i1 %cond, 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}
+
+;; 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 5 # version
+; 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
+
+; 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:
+ br i1 %cond, 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 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 5 # 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 a7bcde5aa7ff3260e15a0c8e3b74edd2d59d188f Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Thu, 11 Dec 2025 04:24:40 +0000
Subject: [PATCH 2/6] Rename functions in BasicBlockSectionsProfileReader.
---
.../CodeGen/BasicBlockSectionsProfileReader.h | 40 ++++++------
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 14 ++--
.../BasicBlockMatchingAndInference.cpp | 21 +++---
.../BasicBlockSectionsProfileReader.cpp | 64 ++++++++-----------
4 files changed, 63 insertions(+), 76 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 9ace90fa61394..898b36ae035d1 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -43,12 +43,18 @@ 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.
DenseMap<UniqueBBID, DenseMap<UniqueBBID, uint64_t>> EdgeCounts;
+ // Hash for each basic block. The Hashes are stored for every original block
+ // (not cloned blocks), hence the map key being unsigned instead of
+ // UniqueBBID.
+ DenseMap<unsigned, uint64_t> BBHashes;
+
+
// Returns the profile count for the given basic block or zero if it does not
// exist.
uint64_t getBlockCount(const UniqueBBID &BBID) const {
@@ -75,11 +81,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;
- // Hash for each basic block. The Hashes are stored for every original block
- // (not cloned blocks), hence the map key being unsigned instead of
- // UniqueBBID.
- DenseMap<unsigned, uint64_t> BBHashes;
+ CFGProfile CFG;
};
class BasicBlockSectionsProfileReader {
@@ -103,19 +105,18 @@ class BasicBlockSectionsProfileReader {
SmallVector<SmallVector<unsigned>>
getClonePathsForFunction(StringRef FuncName) const;
- // Returns a pointer to the CfgProfile for the given function.
+ uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID,
+ const UniqueBBID &DestBBID) const;
+
+ // Returns a pointer to the CFGProfile for the function \p FuncName.
// 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())
+ const CFGProfile *getFunctionCFGProfile(StringRef FuncName) const {
+ auto It = ProgramDirectivesAndProfile.find(getAliasName(FuncName));
+ if (It == ProgramDirectivesAndProfile.end())
return nullptr;
- return &It->second.Cfg;
+ return &It->second.CFG;
}
- // Return the complete function path and cluster info for the given function.
- std::pair<bool, FunctionPathAndClusterInfo>
- getFunctionPathAndClusterInfo(StringRef FuncName) const;
-
private:
StringRef getAliasName(StringRef FuncName) const {
auto R = FuncAliasMap.find(FuncName);
@@ -162,10 +163,10 @@ 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<FunctionProfile> ProgramPathAndClusterInfo;
+ StringMap<FunctionProfile> ProgramDirectivesAndProfile;
// Some functions have alias names. We use this map to find the main alias
- // name which appears in ProgramPathAndClusterInfo as a key.
+ // name which appears in ProgramDirectivesAndProfile as a key.
StringMap<StringRef> FuncAliasMap;
};
@@ -222,12 +223,11 @@ class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
SmallVector<SmallVector<unsigned>>
getClonePathsForFunction(StringRef FuncName) const;
+ const CFGProfile *getFunctionCFGProfile(StringRef FuncName) const;
+
uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID,
const UniqueBBID &DestBBID) const;
- std::pair<bool, FunctionPathAndClusterInfo>
- getFunctionPathAndClusterInfo(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 c76b8c3e74bec..14a96b3c64227 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1419,7 +1419,7 @@ static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
static llvm::object::BBAddrMap::Features
getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
- bool HasCalls, const CfgProfile *FuncCfgProfile) {
+ 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) ||
@@ -1441,7 +1441,7 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
bool BrProbEnabled =
AllFeatures ||
(!NoFeatures && PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb));
- bool PostLinkCfgEnabled = FuncCfgProfile && PgoAnalysisMapEmitBBSectionsCfg;
+ bool PostLinkCfgEnabled = FuncCFGProfile && PgoAnalysisMapEmitBBSectionsCfg;
if ((BBFreqEnabled || BrProbEnabled) && BBAddrMapSkipEmitBBEntries) {
MF.getFunction().getContext().emitError(
@@ -1464,9 +1464,9 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
if (auto *BBSPRPass =
getAnalysisIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>())
BBSPR = &BBSPRPass->getBBSPR();
- const CfgProfile *FuncCfgProfile = nullptr;
+ const CFGProfile *FuncCFGProfile = nullptr;
if (BBSPR)
- FuncCfgProfile = BBSPR->getFunctionCfgProfile(MF.getFunction().getName());
+ FuncCFGProfile = BBSPR->getFunctionCFGProfile(MF.getFunction().getName());
const MCSymbol *FunctionSymbol = getFunctionBegin();
@@ -1477,7 +1477,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
OutStreamer->emitInt8(BBAddrMapVersion);
OutStreamer->AddComment("feature");
auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size(), HasCalls,
- FuncCfgProfile);
+ FuncCFGProfile);
OutStreamer->emitInt8(Features.encode());
// Emit BB Information for each basic block in the function.
if (Features.MultiBBRange) {
@@ -1585,7 +1585,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
if (Features.PostLinkCfg) {
OutStreamer->AddComment("basic block frequency (propeller)");
OutStreamer->emitULEB128IntValue(
- FuncCfgProfile->getBlockCount(*MBB.getBBID()));
+ FuncCFGProfile->getBlockCount(*MBB.getBBID()));
}
}
if (Features.BrProb) {
@@ -1600,7 +1600,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());
if (Features.PostLinkCfg) {
OutStreamer->AddComment("successor branch frequency (propeller)");
- OutStreamer->emitULEB128IntValue(FuncCfgProfile->getEdgeCount(
+ OutStreamer->emitULEB128IntValue(FuncCFGProfile->getEdgeCount(
*MBB.getBBID(), *SuccMBB->getBBID()));
}
}
diff --git a/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp b/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp
index 88c753ff66081..07b7b067e49b5 100644
--- a/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp
+++ b/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp
@@ -119,24 +119,23 @@ BasicBlockMatchingAndInference::initWeightInfoByMatching(MachineFunction &MF) {
StaleMatcher Matcher;
Matcher.init(Blocks, Hashes);
BasicBlockMatchingAndInference::WeightInfo MatchWeight;
- auto [IsValid, PathAndClusterInfo] =
- BSPR->getFunctionPathAndClusterInfo(MF.getName());
- if (!IsValid)
+ const CFGProfile *CFG = BSPR->getFunctionCFGProfile(MF.getName());
+ if (CFG == nullptr)
return MatchWeight;
- for (auto &BlockCount : PathAndClusterInfo.NodeCounts) {
- if (PathAndClusterInfo.BBHashes.count(BlockCount.first.BaseID)) {
- auto Hash = PathAndClusterInfo.BBHashes[BlockCount.first.BaseID];
+ for (auto &BlockCount : CFG->NodeCounts) {
+ if (CFG->BBHashes.count(BlockCount.first.BaseID)) {
+ auto Hash = CFG->BBHashes.lookup(BlockCount.first.BaseID);
MachineBasicBlock *Block = Matcher.matchBlock(BlendedBlockHash(Hash));
// When a basic block has clone copies, sum their counts.
if (Block != nullptr)
MatchWeight.BlockWeights[Block] += BlockCount.second;
}
}
- for (auto &PredItem : PathAndClusterInfo.EdgeCounts) {
+ for (auto &PredItem : CFG->EdgeCounts) {
auto PredID = PredItem.first.BaseID;
- if (!PathAndClusterInfo.BBHashes.count(PredID))
+ if (!CFG->BBHashes.count(PredID))
continue;
- auto PredHash = PathAndClusterInfo.BBHashes[PredID];
+ auto PredHash = CFG->BBHashes.lookup(PredID);
MachineBasicBlock *PredBlock =
Matcher.matchBlock(BlendedBlockHash(PredHash));
if (PredBlock == nullptr)
@@ -144,8 +143,8 @@ BasicBlockMatchingAndInference::initWeightInfoByMatching(MachineFunction &MF) {
for (auto &SuccItem : PredItem.second) {
auto SuccID = SuccItem.first.BaseID;
auto EdgeWeight = SuccItem.second;
- if (PathAndClusterInfo.BBHashes.count(SuccID)) {
- auto SuccHash = PathAndClusterInfo.BBHashes[SuccID];
+ if (CFG->BBHashes.count(SuccID)) {
+ auto SuccHash = CFG->BBHashes.lookup(SuccID);
MachineBasicBlock *SuccBlock =
Matcher.matchBlock(BlendedBlockHash(SuccHash));
// When an edge has clone copies, sum their counts.
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index 8baa478c7c5c0..9674ae4f76ff0 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -64,16 +64,16 @@ bool BasicBlockSectionsProfileReader::isFunctionHot(StringRef FuncName) const {
SmallVector<BBClusterInfo>
BasicBlockSectionsProfileReader::getClusterInfoForFunction(
StringRef FuncName) const {
- auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
- return R != ProgramPathAndClusterInfo.end() ? R->second.ClusterInfo
+ auto R = ProgramDirectivesAndProfile.find(getAliasName(FuncName));
+ return R != ProgramDirectivesAndProfile.end() ? R->second.ClusterInfo
: SmallVector<BBClusterInfo>();
}
SmallVector<SmallVector<unsigned>>
BasicBlockSectionsProfileReader::getClonePathsForFunction(
StringRef FuncName) const {
- auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
- return R != ProgramPathAndClusterInfo.end()
+ auto R = ProgramDirectivesAndProfile.find(getAliasName(FuncName));
+ return R != ProgramDirectivesAndProfile.end()
? R->second.ClonePaths
: SmallVector<SmallVector<unsigned>>();
}
@@ -81,11 +81,10 @@ BasicBlockSectionsProfileReader::getClonePathsForFunction(
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())
+ const CFGProfile *CFG = getFunctionCFGProfile(FuncName);
+ if (CFG == nullptr) return 0;
+ auto NodeIt = CFG->EdgeCounts.find(SrcBBID);
+ if (NodeIt == CFG->EdgeCounts.end())
return 0;
auto EdgeIt = NodeIt->second.find(SinkBBID);
if (EdgeIt == NodeIt->second.end())
@@ -93,15 +92,6 @@ uint64_t BasicBlockSectionsProfileReader::getEdgeCount(
return EdgeIt->second;
}
-std::pair<bool, FunctionPathAndClusterInfo>
-BasicBlockSectionsProfileReader::getFunctionPathAndClusterInfo(
- StringRef FuncName) const {
- auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));
- return R != ProgramPathAndClusterInfo.end()
- ? std::pair(true, R->second)
- : std::pair(false, FunctionPathAndClusterInfo());
-}
-
// Reads the version 1 basic block sections profile. Profile for each function
// is encoded as follows:
// m <module_name>
@@ -158,7 +148,7 @@ BasicBlockSectionsProfileReader::getFunctionPathAndClusterInfo(
// ....
// ****************************************************************************
Error BasicBlockSectionsProfileReader::ReadV1Profile() {
- auto FI = ProgramPathAndClusterInfo.end();
+ auto FI = ProgramDirectivesAndProfile.end();
// Current cluster ID corresponding to this function.
unsigned CurrentCluster = 0;
@@ -202,7 +192,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
if (!FunctionFound) {
// Skip the following profile by setting the profile iterator (FI) to
// the past-the-end element.
- FI = ProgramPathAndClusterInfo.end();
+ FI = ProgramDirectivesAndProfile.end();
DIFilename = "";
continue;
}
@@ -211,7 +201,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
// Prepare for parsing clusters of this function name.
// Start a new cluster map for this function name.
- auto R = ProgramPathAndClusterInfo.try_emplace(Values.front());
+ auto R = ProgramDirectivesAndProfile.try_emplace(Values.front());
// Report error when multiple profiles have been specified for the same
// function.
if (!R.second)
@@ -228,7 +218,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
case 'c': // Basic block cluster specifier.
// Skip the profile when we the profile iterator (FI) refers to the
// past-the-end element.
- if (FI == ProgramPathAndClusterInfo.end())
+ if (FI == ProgramDirectivesAndProfile.end())
continue;
// Reset current cluster position.
CurrentPosition = 0;
@@ -249,7 +239,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
case 'p': { // Basic block cloning path specifier.
// Skip the profile when we the profile iterator (FI) refers to the
// past-the-end element.
- if (FI == ProgramPathAndClusterInfo.end())
+ if (FI == ProgramDirectivesAndProfile.end())
continue;
SmallSet<unsigned, 5> BBsInPath;
FI->second.ClonePaths.push_back({});
@@ -269,7 +259,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
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())
+ if (FI == ProgramDirectivesAndProfile.end())
continue;
// For each node, its CFG profile is encoded as
// <src>:<count>,<sink_1>:<count_1>,<sink_2>:<count_2>,...
@@ -290,10 +280,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;
@@ -301,7 +291,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
case 'h': { // Basic block hash secifier.
// Skip the profile when the profile iterator (FI) refers to the
// past-the-end element.
- if (FI == ProgramPathAndClusterInfo.end())
+ if (FI == ProgramDirectivesAndProfile.end())
continue;
for (auto BBIDHashStr : Values) {
auto [BBIDStr, HashStr] = BBIDHashStr.split(':');
@@ -313,7 +303,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
return createProfileParseError(
Twine("unsigned integer expected in hex format: '") + HashStr +
"'");
- FI->second.BBHashes[BBID] = Hash;
+ FI->second.CFG.BBHashes[BBID] = Hash;
}
continue;
}
@@ -327,7 +317,7 @@ Error BasicBlockSectionsProfileReader::ReadV1Profile() {
}
Error BasicBlockSectionsProfileReader::ReadV0Profile() {
- auto FI = ProgramPathAndClusterInfo.end();
+ auto FI = ProgramDirectivesAndProfile.end();
// Current cluster ID corresponding to this function.
unsigned CurrentCluster = 0;
// Current position in the current cluster.
@@ -348,7 +338,7 @@ Error BasicBlockSectionsProfileReader::ReadV0Profile() {
if (S.consume_front("!")) {
// Skip the profile when we the profile iterator (FI) refers to the
// past-the-end element.
- if (FI == ProgramPathAndClusterInfo.end())
+ if (FI == ProgramDirectivesAndProfile.end())
continue;
SmallVector<StringRef, 4> BBIDs;
S.split(BBIDs, ' ');
@@ -400,7 +390,7 @@ Error BasicBlockSectionsProfileReader::ReadV0Profile() {
if (!FunctionFound) {
// Skip the following profile by setting the profile iterator (FI) to
// the past-the-end element.
- FI = ProgramPathAndClusterInfo.end();
+ FI = ProgramDirectivesAndProfile.end();
continue;
}
for (size_t i = 1; i < Aliases.size(); ++i)
@@ -408,7 +398,7 @@ Error BasicBlockSectionsProfileReader::ReadV0Profile() {
// Prepare for parsing clusters of this function name.
// Start a new cluster map for this function name.
- auto R = ProgramPathAndClusterInfo.try_emplace(Aliases.front());
+ auto R = ProgramDirectivesAndProfile.try_emplace(Aliases.front());
// Report error when multiple profiles have been specified for the same
// function.
if (!R.second)
@@ -517,18 +507,16 @@ BasicBlockSectionsProfileReaderWrapperPass::getClonePathsForFunction(
return BBSPR.getClonePathsForFunction(FuncName);
}
+const CFGProfile *BasicBlockSectionsProfileReaderWrapperPass::getFunctionCFGProfile(StringRef FuncName) const {
+ return BBSPR.getFunctionCFGProfile(FuncName);
+}
+
uint64_t BasicBlockSectionsProfileReaderWrapperPass::getEdgeCount(
StringRef FuncName, const UniqueBBID &SrcBBID,
const UniqueBBID &SinkBBID) const {
return BBSPR.getEdgeCount(FuncName, SrcBBID, SinkBBID);
}
-std::pair<bool, FunctionPathAndClusterInfo>
-BasicBlockSectionsProfileReaderWrapperPass::getFunctionPathAndClusterInfo(
- StringRef FuncName) const {
- return BBSPR.getFunctionPathAndClusterInfo(FuncName);
-}
-
BasicBlockSectionsProfileReader &
BasicBlockSectionsProfileReaderWrapperPass::getBBSPR() {
return BBSPR;
>From ff9e7169f17255453a6b3fc09c2583b85893352c Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Thu, 11 Dec 2025 07:21:36 +0000
Subject: [PATCH 3/6] Update feature to 2 bytes.
---
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +-
.../X86/basic-block-address-map-empty-function.ll | 6 +++---
.../X86/basic-block-address-map-function-sections.ll | 12 ++++++------
.../X86/basic-block-address-map-pgo-features.ll | 12 ++++++------
...ic-block-address-map-with-basic-block-sections.ll | 2 +-
.../X86/basic-block-address-map-with-emit-bb-hash.ll | 2 +-
.../CodeGen/X86/basic-block-address-map-with-mfs.ll | 4 ++--
llvm/test/CodeGen/X86/basic-block-address-map.ll | 2 +-
.../CodeGen/X86/basic-block-sections-pgo-features.ll | 4 ++--
9 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 14a96b3c64227..8ac7856d2fb56 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1478,7 +1478,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
OutStreamer->AddComment("feature");
auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size(), HasCalls,
FuncCFGProfile);
- OutStreamer->emitInt8(Features.encode());
+ OutStreamer->emitInt16(Features.encode());
// Emit BB Information for each basic block in the function.
if (Features.MultiBBRange) {
OutStreamer->AddComment("number of basic block ranges");
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll b/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll
index 7457e3bdb24dc..c63022ed05c4e 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-empty-function.ll
@@ -19,7 +19,7 @@ entry:
; CHECK: func:
; CHECK: .Lfunc_begin1:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text{{$}}
-; CHECK-NEXT: .byte 5 # version
-; BASIC-NEXT: .byte 0 # feature
-; PGO-NEXT: .byte 3 # feature
+; CHECK-NEXT: .byte 5 # version
+; BASIC-NEXT: .short 0 # feature
+; PGO-NEXT: .short 3 # feature
; CHECK-NEXT: .quad .Lfunc_begin1 # function address
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
index bdfe1e4564fc1..892fa009935d2 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
@@ -10,8 +10,8 @@ define dso_local i32 @_Z3barv() {
; CHECK-LABEL: _Z3barv:
; CHECK-NEXT: [[BAR_BEGIN:.Lfunc_begin[0-9]+]]:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3barv{{$}}
-; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 0 # feature
+; CHECK-NEXT: .byte 5 # version
+; CHECK-NEXT: .short 0 # feature
; CHECK-NEXT: .quad [[BAR_BEGIN]] # function address
@@ -23,8 +23,8 @@ define dso_local i32 @_Z3foov() {
; CHECK-LABEL: _Z3foov:
; CHECK-NEXT: [[FOO_BEGIN:.Lfunc_begin[0-9]+]]:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3foov{{$}}
-; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 32 # feature
+; CHECK-NEXT: .byte 5 # version
+; CHECK-NEXT: .short 32 # feature
; CHECK-NEXT: .quad [[FOO_BEGIN]] # function address
@@ -36,6 +36,6 @@ define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat {
; CHECK-LABEL: _Z4fooTIiET_v:
; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]:
; CHECK: .section .llvm_bb_addr_map,"oG", at llvm_bb_addr_map,.text._Z4fooTIiET_v,_Z4fooTIiET_v,comdat{{$}}
-; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 0 # feature
+; CHECK-NEXT: .byte 5 # version
+; CHECK-NEXT: .short 0 # feature
; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]] # function address
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll b/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
index ca3c8d18e7dc5..8dff2873b12c4 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-pgo-features.ll
@@ -70,11 +70,11 @@ declare i32 @__gxx_personality_v0(...)
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text._Z3bazb{{$}}
; CHECK-NEXT: .byte 5 # version
-; BASIC-NEXT: .byte 32 # feature
-; PGO-ALL-NEXT: .byte 39 # feature
-; FEC-ONLY-NEXT:.byte 33 # feature
-; BBF-ONLY-NEXT:.byte 34 # feature
-; BRP-ONLY-NEXT:.byte 36 # feature
+; BASIC-NEXT: .short 32 # feature
+; PGO-ALL-NEXT: .short 39 # feature
+; FEC-ONLY-NEXT:.short 33 # feature
+; BBF-ONLY-NEXT:.short 34 # feature
+; BRP-ONLY-NEXT:.short 36 # feature
; CHECK-NEXT: .quad .Lfunc_begin0 # function address
; CHECK-NEXT: .byte 6 # number of basic blocks
; CHECK-NEXT: .byte 0 # BB id
@@ -146,7 +146,7 @@ declare i32 @__gxx_personality_v0(...)
; PGO-BRP-NEXT: .byte 5 # successor BB ID
; PGO-BRP-NEXT: .ascii "\200\200\200\200\b" # successor branch probability
-; SKIP-BB-ENTRIES: .byte 49 # feature
+; SKIP-BB-ENTRIES: .short 49 # feature
; SKIP-BB-ENTRIES-NEXT: .quad .Lfunc_begin0 # function address
; SKIP-BB-ENTRIES-NEXT: .byte 6 # number of basic blocks
; SKIP-BB-ENTRIES-NEXT: .byte 100 # function entry count
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
index 297cbd81ed036..16808819ab2d3 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-basic-block-sections.ll
@@ -48,7 +48,7 @@ declare i32 @__gxx_personality_v0(...)
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.hot._Z3bazb
; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 40 # feature
+; CHECK-NEXT: .short 40 # feature
; CHECK-NEXT: .byte 2 # number of basic block ranges
; CHECK-NEXT: .quad .Lfunc_begin0 # base address
; CHECK-NEXT: .byte 2 # number of basic blocks
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll
index f17e9a5849150..39d83cd26f316 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-emit-bb-hash.ll
@@ -51,7 +51,7 @@ declare i32 @__gxx_personality_v0(...)
;; Verify that with -unique-section-names=false, the unique id of the text section gets assigned to the llvm_bb_addr_map section.
; NOUNIQ: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text,unique,1
; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 96 # feature
+; CHECK-NEXT: .short 96 # feature
; CHECK-NEXT: .quad .Lfunc_begin0 # function address
; CHECK-NEXT: .byte 6 # number of basic blocks
; CHECK-NEXT: .byte 0 # BB id
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll b/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
index 36e21b9b3faa7..f8146bb38f71e 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-with-mfs.ll
@@ -59,8 +59,8 @@ declare i32 @qux()
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.hot.foo
; CHECK-NEXT: .byte 5 # version
-; BASIC-NEXT: .byte 40 # feature
-; PGO-NEXT: .byte 47 # feature
+; BASIC-NEXT: .short 40 # feature
+; PGO-NEXT: .short 47 # feature
; CHECK-NEXT: .byte 2 # number of basic block ranges
; CHECK-NEXT: .quad .Lfunc_begin0 # base address
; CHECK-NEXT: .byte 2 # number of basic blocks
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map.ll b/llvm/test/CodeGen/X86/basic-block-address-map.ll
index 523b939765525..5567ccd4f9e75 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map.ll
@@ -53,7 +53,7 @@ declare i32 @__gxx_personality_v0(...)
;; Verify that with -unique-section-names=false, the unique id of the text section gets assigned to the llvm_bb_addr_map section.
; NOUNIQ: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text,unique,1
; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 32 # feature
+; CHECK-NEXT: .short 32 # feature
; CHECK-NEXT: .quad .Lfunc_begin0 # function address
; CHECK-NEXT: .byte 6 # number of basic blocks
; CHECK-NEXT: .byte 0 # BB id
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 7f7d87369701b..5beb422919de5 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-pgo-features.ll
@@ -28,7 +28,7 @@ bb3:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.foo
; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 143 # feature
+; CHECK-NEXT: .short 143 # feature
; CHECK: .quad .Lfunc_begin0 # base address
; CHECK: .byte 0 # BB id
; CHECK: .byte 1 # BB id
@@ -80,7 +80,7 @@ bb2:
; CHECK: .section .llvm_bb_addr_map,"o", at llvm_bb_addr_map,.text.bar
; CHECK-NEXT: .byte 5 # version
-; CHECK-NEXT: .byte 7 # feature
+; CHECK-NEXT: .short 7 # feature
; CHECK: .quad .Lfunc_begin1 # function address
; CHECK: .byte 0 # BB id
; CHECK: .byte 1 # BB id
>From 4d06f1ba7b83dedcb656638940a3f710bae52c97 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Thu, 11 Dec 2025 07:21:59 +0000
Subject: [PATCH 4/6] clang-format.
---
.../llvm/CodeGen/BasicBlockSectionsProfileReader.h | 1 -
llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp | 9 ++++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 898b36ae035d1..c33b13602e027 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -54,7 +54,6 @@ struct CFGProfile {
// UniqueBBID.
DenseMap<unsigned, uint64_t> BBHashes;
-
// Returns the profile count for the given basic block or zero if it does not
// exist.
uint64_t getBlockCount(const UniqueBBID &BBID) const {
diff --git a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
index 9674ae4f76ff0..76ed2ea541ea5 100644
--- a/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -66,7 +66,7 @@ BasicBlockSectionsProfileReader::getClusterInfoForFunction(
StringRef FuncName) const {
auto R = ProgramDirectivesAndProfile.find(getAliasName(FuncName));
return R != ProgramDirectivesAndProfile.end() ? R->second.ClusterInfo
- : SmallVector<BBClusterInfo>();
+ : SmallVector<BBClusterInfo>();
}
SmallVector<SmallVector<unsigned>>
@@ -82,7 +82,8 @@ uint64_t BasicBlockSectionsProfileReader::getEdgeCount(
StringRef FuncName, const UniqueBBID &SrcBBID,
const UniqueBBID &SinkBBID) const {
const CFGProfile *CFG = getFunctionCFGProfile(FuncName);
- if (CFG == nullptr) return 0;
+ if (CFG == nullptr)
+ return 0;
auto NodeIt = CFG->EdgeCounts.find(SrcBBID);
if (NodeIt == CFG->EdgeCounts.end())
return 0;
@@ -507,7 +508,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 13d94b22861a99b23eded233594cd75c675ec253 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Thu, 11 Dec 2025 07:46:40 +0000
Subject: [PATCH 5/6] Fix comments after renaming
---
llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index c33b13602e027..1c96b484a2090 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -158,7 +158,7 @@ class BasicBlockSectionsProfileReader {
// This contains the BB cluster information for the whole program.
//
- // For every function name, it contains the cloning and cluster information
+ // For every function name, it contains the cloning directives and profile data
// 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.
>From 97c4f1ed6b57a84d4c9c890a6493df691d0a9c44 Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Thu, 11 Dec 2025 07:59:36 +0000
Subject: [PATCH 6/6] clang-format.
---
.../llvm/CodeGen/BasicBlockSectionsProfileReader.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
index 1c96b484a2090..59401ed27f901 100644
--- a/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ b/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -158,10 +158,10 @@ class BasicBlockSectionsProfileReader {
// This contains the BB cluster information for the whole program.
//
- // For every function name, it contains the cloning directives and profile data
- // 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.
+ // For every function name, it contains the cloning directives and profile
+ // data 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<FunctionProfile> ProgramDirectivesAndProfile;
// Some functions have alias names. We use this map to find the main alias
More information about the llvm-commits
mailing list