[llvm] b5c59d7 - [ProfileSummary] Add the PartialProfileRatio field in ProfileSummary metadata.

Hiroshi Yamauchi via llvm-commits llvm-commits at lists.llvm.org
Thu May 21 09:29:18 PDT 2020


Author: Hiroshi Yamauchi
Date: 2020-05-21T09:12:23-07:00
New Revision: b5c59d77c3a0aad21d7dccfa2c3989e627e9f1bd

URL: https://github.com/llvm/llvm-project/commit/b5c59d77c3a0aad21d7dccfa2c3989e627e9f1bd
DIFF: https://github.com/llvm/llvm-project/commit/b5c59d77c3a0aad21d7dccfa2c3989e627e9f1bd.diff

LOG: [ProfileSummary] Add the PartialProfileRatio field in ProfileSummary metadata.

Summary:
PartialProfileRatio approximately represents the ratio of the number of profile
counters of the program being built to the number of profile counters in the
partial sample profile. It is used to scale the working set size under the
partial sample profile to reflect the size of the program being built and to
improve the working set size heuristics.

This is a split from D79831.

Reviewers: davidxl

Subscribers: eraman, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D79951

Added: 
    

Modified: 
    llvm/include/llvm/IR/ProfileSummary.h
    llvm/lib/IR/ProfileSummary.cpp
    llvm/test/Transforms/PGOProfile/unreachable_bb.ll
    llvm/unittests/ProfileData/SampleProfTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/ProfileSummary.h b/llvm/include/llvm/IR/ProfileSummary.h
index 425ee2f1c16d..00af0c5e05c8 100644
--- a/llvm/include/llvm/IR/ProfileSummary.h
+++ b/llvm/include/llvm/IR/ProfileSummary.h
@@ -14,6 +14,7 @@
 #define LLVM_IR_PROFILESUMMARY_H
 
 #include <algorithm>
+#include <cassert>
 #include <cstdint>
 #include <vector>
 
@@ -56,6 +57,10 @@ class ProfileSummary {
   /// code. The common profile is usually merged from profiles collected
   /// from running other targets.
   bool Partial = false;
+  /// This approximately represents the ratio of the number of profile counters
+  /// of the program being built to the number of profile counters in the
+  /// partial sample profile. When 'Partial' is false, it is undefined.
+  double PartialProfileRatio = 0;
   /// Return detailed summary as metadata.
   Metadata *getDetailedSummaryMD(LLVMContext &Context);
 
@@ -66,15 +71,17 @@ class ProfileSummary {
                  uint64_t TotalCount, uint64_t MaxCount,
                  uint64_t MaxInternalCount, uint64_t MaxFunctionCount,
                  uint32_t NumCounts, uint32_t NumFunctions,
-                 bool Partial = false)
+                 bool Partial = false, double PartialProfileRatio = 0)
       : PSK(K), DetailedSummary(std::move(DetailedSummary)),
         TotalCount(TotalCount), MaxCount(MaxCount),
         MaxInternalCount(MaxInternalCount), MaxFunctionCount(MaxFunctionCount),
-        NumCounts(NumCounts), NumFunctions(NumFunctions), Partial(Partial) {}
+        NumCounts(NumCounts), NumFunctions(NumFunctions), Partial(Partial),
+        PartialProfileRatio(PartialProfileRatio) {}
 
   Kind getKind() const { return PSK; }
   /// Return summary information as metadata.
-  Metadata *getMD(LLVMContext &Context, bool AddPartialField = true);
+  Metadata *getMD(LLVMContext &Context, bool AddPartialField = true,
+                  bool AddPartialProfileRatioField = true);
   /// Construct profile summary from metdata.
   static ProfileSummary *getFromMD(Metadata *MD);
   SummaryEntryVector &getDetailedSummary() { return DetailedSummary; }
@@ -86,6 +93,11 @@ class ProfileSummary {
   uint64_t getMaxInternalCount() { return MaxInternalCount; }
   void setPartialProfile(bool PP) { Partial = PP; }
   bool isPartialProfile() { return Partial; }
+  double getPartialProfileRatio() { return PartialProfileRatio; }
+  void setPartialProfileRatio(double R) {
+    assert(isPartialProfile() && "Unexpected when not partial profile");
+    PartialProfileRatio = R;
+  }
   void printSummary(raw_ostream &OS);
   void printDetailedSummary(raw_ostream &OS);
 };

diff  --git a/llvm/lib/IR/ProfileSummary.cpp b/llvm/lib/IR/ProfileSummary.cpp
index 4f01879b1fb6..fbd2fa5ed8a7 100644
--- a/llvm/lib/IR/ProfileSummary.cpp
+++ b/llvm/lib/IR/ProfileSummary.cpp
@@ -31,6 +31,14 @@ static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
   return MDTuple::get(Context, Ops);
 }
 
+static Metadata *getKeyFPValMD(LLVMContext &Context, const char *Key,
+                               double Val) {
+  Type *DoubleTy = Type::getDoubleTy(Context);
+  Metadata *Ops[2] = {MDString::get(Context, Key),
+                      ConstantAsMetadata::get(ConstantFP::get(DoubleTy, Val))};
+  return MDTuple::get(Context, Ops);
+}
+
 // Return an MDTuple with two elements. The first element is a string Key and
 // the second is a string Value.
 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
@@ -67,7 +75,10 @@ Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
 // to the kind of profile summary as returned by getFormatSpecificMD.
 // IsPartialProfile is an optional field and \p AddPartialField will decide
 // whether to add a field for it.
-Metadata *ProfileSummary::getMD(LLVMContext &Context, bool AddPartialField) {
+// PartialProfileRatio is an optional field and \p AddPartialProfileRatioField
+// will decide whether to add a field for it.
+Metadata *ProfileSummary::getMD(LLVMContext &Context, bool AddPartialField,
+                                bool AddPartialProfileRatioField) {
   const char *KindStr[3] = {"InstrProf", "CSInstrProf", "SampleProfile"};
   SmallVector<Metadata *, 16> Components;
   Components.push_back(getKeyValMD(Context, "ProfileFormat", KindStr[PSK]));
@@ -82,24 +93,43 @@ Metadata *ProfileSummary::getMD(LLVMContext &Context, bool AddPartialField) {
   if (AddPartialField)
     Components.push_back(
         getKeyValMD(Context, "IsPartialProfile", isPartialProfile()));
+  if (AddPartialProfileRatioField)
+    Components.push_back(getKeyFPValMD(Context, "PartialProfileRatio",
+                                       getPartialProfileRatio()));
   Components.push_back(getDetailedSummaryMD(Context));
   return MDTuple::get(Context, Components);
 }
 
-// Parse an MDTuple representing (Key, Val) pair.
-static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
+// Get the value metadata for the input MD/Key.
+static ConstantAsMetadata *getValMD(MDTuple *MD, const char *Key) {
   if (!MD)
-    return false;
+    return nullptr;
   if (MD->getNumOperands() != 2)
-    return false;
+    return nullptr;
   MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
   ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1));
   if (!KeyMD || !ValMD)
-    return false;
+    return nullptr;
   if (!KeyMD->getString().equals(Key))
-    return false;
-  Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
-  return true;
+    return nullptr;
+  return ValMD;
+}
+
+// Parse an MDTuple representing (Key, Val) pair.
+static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
+  if (auto *ValMD = getValMD(MD, Key)) {
+    Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
+    return true;
+  }
+  return false;
+}
+
+static bool getVal(MDTuple *MD, const char *Key, double &Val) {
+  if (auto *ValMD = getValMD(MD, Key)) {
+    Val = cast<ConstantFP>(ValMD->getValue())->getValueAPF().convertToDouble();
+    return true;
+  }
+  return false;
 }
 
 // Check if an MDTuple represents a (Key, Val) pair.
@@ -163,7 +193,7 @@ static bool getOptionalVal(MDTuple *Tuple, unsigned &Idx, const char *Key,
 
 ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
   MDTuple *Tuple = dyn_cast_or_null<MDTuple>(MD);
-  if (!Tuple || Tuple->getNumOperands() < 8 || Tuple->getNumOperands() > 9)
+  if (!Tuple || Tuple->getNumOperands() < 8 || Tuple->getNumOperands() > 10)
     return nullptr;
 
   unsigned I = 0;
@@ -205,13 +235,17 @@ ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
   uint64_t IsPartialProfile = 0;
   if (!getOptionalVal(Tuple, I, "IsPartialProfile", IsPartialProfile))
     return nullptr;
+  double PartialProfileRatio = 0;
+  if (!getOptionalVal(Tuple, I, "PartialProfileRatio", PartialProfileRatio))
+    return nullptr;
 
   SummaryEntryVector Summary;
   if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(I++)), Summary))
     return nullptr;
   return new ProfileSummary(SummaryKind, std::move(Summary), TotalCount,
                             MaxCount, MaxInternalCount, MaxFunctionCount,
-                            NumCounts, NumFunctions, IsPartialProfile);
+                            NumCounts, NumFunctions, IsPartialProfile,
+                            PartialProfileRatio);
 }
 
 void ProfileSummary::printSummary(raw_ostream &OS) {

diff  --git a/llvm/test/Transforms/PGOProfile/unreachable_bb.ll b/llvm/test/Transforms/PGOProfile/unreachable_bb.ll
index 96aca895ac44..8b3162d2b832 100644
--- a/llvm/test/Transforms/PGOProfile/unreachable_bb.ll
+++ b/llvm/test/Transforms/PGOProfile/unreachable_bb.ll
@@ -16,7 +16,7 @@ return:
 declare void @bar()
 
 ;USE: !0 = !{i32 1, !"ProfileSummary", !1}
-;USE: !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10}
+;USE: !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11}
 ;USE: !2 = !{!"ProfileFormat", !"InstrProf"}
 ;USE: !3 = !{!"TotalCount", i64 0}
 

diff  --git a/llvm/unittests/ProfileData/SampleProfTest.cpp b/llvm/unittests/ProfileData/SampleProfTest.cpp
index 62273740c91a..26b01e4b2849 100644
--- a/llvm/unittests/ProfileData/SampleProfTest.cpp
+++ b/llvm/unittests/ProfileData/SampleProfTest.cpp
@@ -81,10 +81,13 @@ struct SampleProfTest : ::testing::Test {
   // Metadata. \p AddPartialField is to choose whether the Metadata
   // contains the IsPartialProfile field which is optional.
   void verifyProfileSummary(ProfileSummary &Summary, Module &M,
-                            const bool AddPartialField) {
+                            const bool AddPartialField,
+                            const bool AddPartialProfileRatioField) {
     LLVMContext &Context = M.getContext();
     const bool IsPartialProfile = Summary.isPartialProfile();
-    auto VerifySummary = [IsPartialProfile](ProfileSummary &Summary) mutable {
+    const double PartialProfileRatio = Summary.getPartialProfileRatio();
+    auto VerifySummary = [IsPartialProfile, PartialProfileRatio](
+                             ProfileSummary &Summary) mutable {
       ASSERT_EQ(ProfileSummary::PSK_Sample, Summary.getKind());
       ASSERT_EQ(137392u, Summary.getTotalCount());
       ASSERT_EQ(8u, Summary.getNumCounts());
@@ -92,6 +95,7 @@ struct SampleProfTest : ::testing::Test {
       ASSERT_EQ(1437u, Summary.getMaxFunctionCount());
       ASSERT_EQ(60351u, Summary.getMaxCount());
       ASSERT_EQ(IsPartialProfile, Summary.isPartialProfile());
+      ASSERT_EQ(PartialProfileRatio, Summary.getPartialProfileRatio());
 
       uint32_t Cutoff = 800000;
       auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
@@ -113,7 +117,8 @@ struct SampleProfTest : ::testing::Test {
     VerifySummary(Summary);
 
     // Test that conversion of summary to and from Metadata works.
-    Metadata *MD = Summary.getMD(Context, AddPartialField);
+    Metadata *MD =
+        Summary.getMD(Context, AddPartialField, AddPartialProfileRatioField);
     ASSERT_TRUE(MD);
     ProfileSummary *PS = ProfileSummary::getFromMD(MD);
     ASSERT_TRUE(PS);
@@ -271,13 +276,16 @@ struct SampleProfTest : ::testing::Test {
 
     ProfileSummary &Summary = Reader->getSummary();
     Summary.setPartialProfile(true);
-    verifyProfileSummary(Summary, M, true);
+    verifyProfileSummary(Summary, M, true, false);
 
     Summary.setPartialProfile(false);
-    verifyProfileSummary(Summary, M, true);
+    verifyProfileSummary(Summary, M, true, false);
 
-    Summary.setPartialProfile(false);
-    verifyProfileSummary(Summary, M, false);
+    verifyProfileSummary(Summary, M, false, false);
+
+    Summary.setPartialProfile(true);
+    Summary.setPartialProfileRatio(0.5);
+    verifyProfileSummary(Summary, M, true, true);
   }
 
   void addFunctionSamples(StringMap<FunctionSamples> *Smap, const char *Fname,


        


More information about the llvm-commits mailing list