1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[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
This commit is contained in:
Hiroshi Yamauchi 2020-05-14 10:21:53 -07:00
parent 6d06d957a7
commit 4d59570b59
4 changed files with 76 additions and 22 deletions

View File

@ -14,6 +14,7 @@
#define LLVM_IR_PROFILESUMMARY_H
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <vector>
@ -56,6 +57,10 @@ private:
/// 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 @@ public:
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 @@ public:
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);
};

View File

@ -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) {

View File

@ -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}

View File

@ -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,