[llvm] [NFCI][PGO]Re-purpose synthetic entry count to pseduo entry count for AFDO supplementary profiles (PR #139578)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Mon May 12 09:51:29 PDT 2025
https://github.com/mingmingl-llvm created https://github.com/llvm/llvm-project/pull/139578
>From https://github.com/llvm/llvm-project/pull/107471 and on, there are no active user of setting a function's synthetic counts (except in unit tests). This patch proposes to repurpose the synthetic count concepts to record the fact that a function's entry count is generated from AFDO supplementary profiles. This patch doesn't include the change to 'set' pseudo count itself. A follow-up change will do it.
AFDO supplementary profiles are introduced to enhance instrumented FDO profiles for representativeness, by merging a binary's AFDO production sample into FDO profile. During the merge, a function's hot/cold attribute is _corrected_ by AFDO profiles, and the branch weights of the function's basic blocks are not accurate.
The goal of this re-purpose is for compiler passes to tell whether a function's branch weights are static or based on profiles.
>From 64dfe1b68b3330dbc1d98d56d5bff0e9eeb6521f Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Sun, 11 May 2025 23:31:37 -0700
Subject: [PATCH] [PGO]Re-purpose synthetic entry count to pseduo entry count
for AFDO supplementary profiles
---
llvm/include/llvm/IR/Function.h | 19 ++++++++++---------
llvm/include/llvm/IR/MDBuilder.h | 8 ++++----
llvm/lib/IR/Function.cpp | 13 ++++++-------
llvm/lib/IR/MDBuilder.cpp | 7 +++----
llvm/lib/Transforms/Utils/InlineFunction.cpp | 2 +-
llvm/unittests/IR/MetadataTest.cpp | 8 ++++----
6 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 6d4a53da7ff22..f2242742de0bd 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -296,11 +296,11 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
}
}
- enum ProfileCountType { PCT_Real, PCT_Synthetic };
+ enum ProfileCountType { PCT_Real, PCT_Pseudo };
/// Class to represent profile counts.
///
- /// This class represents both real and synthetic profile counts.
+ /// This class represents both real and supplementary profile counts.
class ProfileCount {
private:
uint64_t Count = 0;
@@ -311,7 +311,7 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
: Count(Count), PCT(PCT) {}
uint64_t getCount() const { return Count; }
ProfileCountType getType() const { return PCT; }
- bool isSynthetic() const { return PCT == PCT_Synthetic; }
+ bool isPseudo() const { return PCT == PCT_Pseudo; }
};
/// Set the entry count for this function.
@@ -330,16 +330,17 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
/// Get the entry count for this function.
///
/// Entry count is the number of times the function was executed.
- /// When AllowSynthetic is false, only pgo_data will be returned.
- std::optional<ProfileCount> getEntryCount(bool AllowSynthetic = false) const;
+ /// When \p AllowPseudo is false, supplementary AFDO profile counts in an
+ /// iFDO-optimized binary is not used.
+ std::optional<ProfileCount> getEntryCount(bool AllowPseudo = false) const;
/// Return true if the function is annotated with profile data.
///
/// Presence of entry counts from a profile run implies the function has
- /// profile annotations. If IncludeSynthetic is false, only return true
- /// when the profile data is real.
- bool hasProfileData(bool IncludeSynthetic = false) const {
- return getEntryCount(IncludeSynthetic).has_value();
+ /// profile annotations. If \p AllowPseudo is false, supplementary AFDO
+ /// profile counts in an iFDO-optimized binary is not used.
+ bool hasProfileData(bool AllowPseudo = false) const {
+ return getEntryCount(AllowPseudo).has_value();
}
/// Returns the set of GUIDs that needs to be imported to the function for
diff --git a/llvm/include/llvm/IR/MDBuilder.h b/llvm/include/llvm/IR/MDBuilder.h
index ce4e1da656049..c1aa28557f210 100644
--- a/llvm/include/llvm/IR/MDBuilder.h
+++ b/llvm/include/llvm/IR/MDBuilder.h
@@ -83,10 +83,10 @@ class MDBuilder {
MDNode *createUnpredictable();
/// Return metadata containing the entry \p Count for a function, a boolean
- /// \Synthetic indicating whether the counts were synthetized, and the
- /// GUIDs stored in \p Imports that need to be imported for sample PGO, to
- /// enable the same inlines as the profiled optimized binary
- MDNode *createFunctionEntryCount(uint64_t Count, bool Synthetic,
+ /// \p Pseudo indicating whether the counts were from supplementary AFDO
+ /// profiles, and the GUIDs stored in \p Imports that need to be imported for
+ /// sample PGO, to enable the same inlines as the profiled optimized binary
+ MDNode *createFunctionEntryCount(uint64_t Count, bool Pseudo,
const DenseSet<GlobalValue::GUID> *Imports);
/// Return metadata containing the section prefix for a global object.
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 85c28b0205691..23e08ba66238a 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -1119,9 +1119,8 @@ void Function::setEntryCount(ProfileCount Count,
S = &ImportGUIDs;
MDBuilder MDB(getContext());
- setMetadata(
- LLVMContext::MD_prof,
- MDB.createFunctionEntryCount(Count.getCount(), Count.isSynthetic(), S));
+ setMetadata(LLVMContext::MD_prof, MDB.createFunctionEntryCount(
+ Count.getCount(), Count.isPseudo(), S));
}
void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type,
@@ -1129,7 +1128,7 @@ void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type,
setEntryCount(ProfileCount(Count, Type), Imports);
}
-std::optional<ProfileCount> Function::getEntryCount(bool AllowSynthetic) const {
+std::optional<ProfileCount> Function::getEntryCount(bool AllowPseudo) const {
MDNode *MD = getMetadata(LLVMContext::MD_prof);
if (MD && MD->getOperand(0))
if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
@@ -1141,11 +1140,11 @@ std::optional<ProfileCount> Function::getEntryCount(bool AllowSynthetic) const {
if (Count == (uint64_t)-1)
return std::nullopt;
return ProfileCount(Count, PCT_Real);
- } else if (AllowSynthetic &&
- MDS->getString() == "synthetic_function_entry_count") {
+ } else if (AllowPseudo &&
+ MDS->getString() == "pseudo_function_entry_count") {
ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
uint64_t Count = CI->getValue().getZExtValue();
- return ProfileCount(Count, PCT_Synthetic);
+ return ProfileCount(Count, PCT_Pseudo);
}
}
return std::nullopt;
diff --git a/llvm/lib/IR/MDBuilder.cpp b/llvm/lib/IR/MDBuilder.cpp
index b6aa8844a7eaf..849fd52024f30 100644
--- a/llvm/lib/IR/MDBuilder.cpp
+++ b/llvm/lib/IR/MDBuilder.cpp
@@ -69,12 +69,11 @@ MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights,
MDNode *MDBuilder::createUnpredictable() { return MDNode::get(Context, {}); }
MDNode *MDBuilder::createFunctionEntryCount(
- uint64_t Count, bool Synthetic,
- const DenseSet<GlobalValue::GUID> *Imports) {
+ uint64_t Count, bool Pseudo, const DenseSet<GlobalValue::GUID> *Imports) {
Type *Int64Ty = Type::getInt64Ty(Context);
SmallVector<Metadata *, 8> Ops;
- if (Synthetic)
- Ops.push_back(createString("synthetic_function_entry_count"));
+ if (Pseudo)
+ Ops.push_back(createString("pseudo_function_entry_count"));
else
Ops.push_back(createString("function_entry_count"));
Ops.push_back(createConstant(ConstantInt::get(Int64Ty, Count)));
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index eaf57e7bf899d..92361b934e498 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2046,7 +2046,7 @@ static void updateCallProfile(Function *Callee, const ValueToValueMapTy &VMap,
const ProfileCount &CalleeEntryCount,
const CallBase &TheCall, ProfileSummaryInfo *PSI,
BlockFrequencyInfo *CallerBFI) {
- if (CalleeEntryCount.isSynthetic() || CalleeEntryCount.getCount() < 1)
+ if (CalleeEntryCount.isPseudo() || CalleeEntryCount.getCount() < 1)
return;
auto CallSiteCount =
PSI ? PSI->getProfileCount(TheCall, CallerBFI) : std::nullopt;
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 56367e07b9d09..cc4b3ab10903b 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -5190,14 +5190,14 @@ TEST_F(FunctionAttachmentTest, RealEntryCount) {
EXPECT_EQ(Function::PCT_Real, Count->getType());
}
-TEST_F(FunctionAttachmentTest, SyntheticEntryCount) {
+TEST_F(FunctionAttachmentTest, PseudoEntryCount) {
Function *F = getFunction("bar");
EXPECT_FALSE(F->getEntryCount().has_value());
- F->setEntryCount(123, Function::PCT_Synthetic);
- auto Count = F->getEntryCount(true /*allow synthetic*/);
+ F->setEntryCount(123, Function::PCT_Pseudo);
+ auto Count = F->getEntryCount(true /*allow pseudo*/);
EXPECT_TRUE(Count.has_value());
EXPECT_EQ(123u, Count->getCount());
- EXPECT_EQ(Function::PCT_Synthetic, Count->getType());
+ EXPECT_EQ(Function::PCT_Pseudo, Count->getType());
}
TEST_F(FunctionAttachmentTest, SubprogramAttachment) {
More information about the llvm-commits
mailing list