[llvm-branch-commits] [IR] Remove Synthetic Profile Support from Function (PR #204768)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jun 19 15:52:36 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Aiden Grossman (boomanaiden154)

<details>
<summary>Changes</summary>

Synthetic profiles are not generated anywhere and support is very
sporadic across the code base. They are slated to be removed, so remove
support for them from Function member functions.

A future PR will clean up the ProfileCount abstraction that is now no
longer necessary.


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


5 Files Affected:

- (modified) llvm/include/llvm/IR/Function.h (+3-7) 
- (modified) llvm/lib/IR/Function.cpp (+10-16) 
- (modified) llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp (+2-2) 
- (modified) llvm/lib/Transforms/Utils/ProfileVerify.cpp (+3-3) 
- (modified) llvm/unittests/IR/MetadataTest.cpp (-10) 


``````````diff
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index f39fe509a49a4..0b48e088c3db2 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -325,17 +325,13 @@ 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;
+  std::optional<ProfileCount> getEntryCount() 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.
+  bool hasProfileData() const { return getEntryCount().has_value(); }
 
   /// Returns the set of GUIDs that needs to be imported to the function for
   /// sample PGO, to enable the same inlines as the profiled optimized binary.
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 0cf23f0ddda7c..ff5a11fbb08cd 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -1101,25 +1101,19 @@ 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() const {
   MDNode *MD = getMetadata(LLVMContext::MD_prof);
   if (MD && MD->getOperand(0))
     if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
-      if (MDS->getString() == MDProfLabels::FunctionEntryCount) {
-        ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
-        uint64_t Count = CI->getValue().getZExtValue();
-        // A value of -1 is used for SamplePGO when there were no samples.
-        // Treat this the same as unknown.
-        if (Count == (uint64_t)-1)
-          return std::nullopt;
-        return ProfileCount(Count, PCT_Real);
-      } else if (AllowSynthetic &&
-                 MDS->getString() ==
-                     MDProfLabels::SyntheticFunctionEntryCount) {
-        ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
-        uint64_t Count = CI->getValue().getZExtValue();
-        return ProfileCount(Count, PCT_Synthetic);
-      }
+      if (MDS->getString() != MDProfLabels::FunctionEntryCount)
+        return std::nullopt;
+      ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
+      uint64_t Count = CI->getValue().getZExtValue();
+      // A value of -1 is used for SamplePGO when there were no samples.
+      // Treat this the same as unknown.
+      if (Count == static_cast<uint64_t>(-1))
+        return std::nullopt;
+      return ProfileCount(Count, PCT_Real);
     }
   return std::nullopt;
 }
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index e1da7b7cd4e92..c48771506b73f 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -1579,7 +1579,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
         auto &F = *CB.getCaller();
         auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
         auto EC = BFI.getBlockFreq(&F.getEntryBlock());
-        auto CC = F.getEntryCount(/*AllowSynthetic=*/true);
+        auto CC = F.getEntryCount();
         double CallCount = 0.0;
         if (EC.getFrequency() != 0 && CC && CC->getCount() != 0) {
           double CallFreq =
@@ -1629,7 +1629,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
   for (auto &P : SlotInfo.ConstCSInfo)
     Apply(P.second);
   for (auto &[F, C] : FunctionEntryCounts) {
-    assert(!F->getEntryCount(/*AllowSynthetic=*/true) &&
+    assert(!F->getEntryCount() &&
            "Unexpected entry count for funnel that was freshly synthesized");
     F->setEntryCount(static_cast<uint64_t>(std::round(C)));
   }
diff --git a/llvm/lib/Transforms/Utils/ProfileVerify.cpp b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
index 84c5787205db5..70376edd0d32e 100644
--- a/llvm/lib/Transforms/Utils/ProfileVerify.cpp
+++ b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
@@ -116,11 +116,11 @@ bool ProfileInjector::inject() {
   // as cold (we do want some explicit information in the spirit of what this
   // verifier wants to achieve - make dropping / corrupting MD_prof
   // unit-testable)
-  if (!F.getEntryCount(/*AllowSynthetic=*/true))
+  if (!F.getEntryCount())
     F.setEntryCount(DefaultFunctionEntryCount);
   // If there is an entry count that's 0, then don't bother injecting. We won't
   // verify these either.
-  if (F.getEntryCount(/*AllowSynthetic=*/true)->getCount() == 0)
+  if (F.getEntryCount()->getCount() == 0)
     return false;
   bool Changed = false;
   // Cycle through the weights list. If we didn't, tests with more than (say)
@@ -241,7 +241,7 @@ PreservedAnalyses ProfileVerifierPass::run(Function &F,
   if (IgnoreList.contains(&F))
     return PreservedAnalyses::all();
 
-  const auto EntryCount = F.getEntryCount(/*AllowSynthetic=*/true);
+  const auto EntryCount = F.getEntryCount();
   if (!EntryCount) {
     auto *MD = F.getMetadata(LLVMContext::MD_prof);
     if (!MD || !isExplicitlyUnknownProfileMetadata(*MD)) {
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 7222c885548e0..3b5978792c849 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -5225,16 +5225,6 @@ TEST_F(FunctionAttachmentTest, RealEntryCount) {
   EXPECT_EQ(Function::PCT_Real, Count->getType());
 }
 
-TEST_F(FunctionAttachmentTest, SyntheticEntryCount) {
-  Function *F = getFunction("bar");
-  EXPECT_FALSE(F->getEntryCount().has_value());
-  F->setEntryCount(123, Function::PCT_Synthetic);
-  auto Count = F->getEntryCount(true /*allow synthetic*/);
-  EXPECT_TRUE(Count.has_value());
-  EXPECT_EQ(123u, Count->getCount());
-  EXPECT_EQ(Function::PCT_Synthetic, Count->getType());
-}
-
 TEST_F(FunctionAttachmentTest, SubprogramAttachment) {
   Function *F = getFunction("foo");
   DISubprogram *SP = getSubprogram();

``````````

</details>


https://github.com/llvm/llvm-project/pull/204768


More information about the llvm-branch-commits mailing list