[llvm] 4d6f3ee - [PSI] Add the isCold query support with a given percentile value.
Hiroshi Yamauchi via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 12:50:46 PST 2020
Author: Hiroshi Yamauchi
Date: 2020-03-02T12:50:15-08:00
New Revision: 4d6f3ee2ba5b3ea6d9f80e7baf9a746848c790aa
URL: https://github.com/llvm/llvm-project/commit/4d6f3ee2ba5b3ea6d9f80e7baf9a746848c790aa
DIFF: https://github.com/llvm/llvm-project/commit/4d6f3ee2ba5b3ea6d9f80e7baf9a746848c790aa.diff
LOG: [PSI] Add the isCold query support with a given percentile value.
Summary: This follows up D67377 that added the isHot side.
Reviewers: davidxl
Subscribers: eraman, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D75283
Added:
Modified:
llvm/include/llvm/Analysis/ProfileSummaryInfo.h
llvm/lib/Analysis/ProfileSummaryInfo.cpp
llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ProfileSummaryInfo.h b/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
index 6693e40ccf22..f90dcf604e9b 100644
--- a/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
+++ b/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
@@ -120,6 +120,11 @@ class ProfileSummaryInfo {
bool isFunctionHotInCallGraphNthPercentile(int PercentileCutoff,
const Function *F,
BlockFrequencyInfo &BFI);
+ /// Returns true if \p F contains cold code with regard to a given cold
+ /// percentile cutoff value.
+ bool isFunctionColdInCallGraphNthPercentile(int PercentileCutoff,
+ const Function *F,
+ BlockFrequencyInfo &BFI);
/// Returns true if count \p C is considered hot.
bool isHotCount(uint64_t C);
/// Returns true if count \p C is considered cold.
@@ -127,6 +132,9 @@ class ProfileSummaryInfo {
/// Returns true if count \p C is considered hot with regard to a given
/// hot percentile cutoff value.
bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C);
+ /// Returns true if count \p C is considered cold with regard to a given
+ /// cold percentile cutoff value.
+ bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C);
/// Returns true if BasicBlock \p BB is considered hot.
bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
/// Returns true if BasicBlock \p BB is considered cold.
@@ -135,6 +143,10 @@ class ProfileSummaryInfo {
/// hot percentile cutoff value.
bool isHotBlockNthPercentile(int PercentileCutoff,
const BasicBlock *BB, BlockFrequencyInfo *BFI);
+ /// Returns true if BasicBlock \p BB is considered cold with regard to a given
+ /// cold percentile cutoff value.
+ bool isColdBlockNthPercentile(int PercentileCutoff,
+ const BasicBlock *BB, BlockFrequencyInfo *BFI);
/// Returns true if CallSite \p CS is considered hot.
bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
/// Returns true if Callsite \p CS is considered cold.
@@ -153,6 +165,17 @@ class ProfileSummaryInfo {
uint64_t getColdCountThreshold() {
return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
}
+
+ private:
+ template<bool isHot>
+ bool isFunctionHotOrColdInCallGraphNthPercentile(int PercentileCutoff,
+ const Function *F,
+ BlockFrequencyInfo &BFI);
+ template<bool isHot>
+ bool isHotOrColdCountNthPercentile(int PercentileCutoff, uint64_t C);
+ template<bool isHot>
+ bool isHotOrColdBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
+ BlockFrequencyInfo *BFI);
};
/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
diff --git a/llvm/lib/Analysis/ProfileSummaryInfo.cpp b/llvm/lib/Analysis/ProfileSummaryInfo.cpp
index 911d39d9a263..678d66f632a8 100644
--- a/llvm/lib/Analysis/ProfileSummaryInfo.cpp
+++ b/llvm/lib/Analysis/ProfileSummaryInfo.cpp
@@ -195,15 +195,19 @@ bool ProfileSummaryInfo::isFunctionColdInCallGraph(const Function *F,
return true;
}
-// Like isFunctionHotInCallGraph but for a given cutoff.
-bool ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile(
+template<bool isHot>
+bool ProfileSummaryInfo::isFunctionHotOrColdInCallGraphNthPercentile(
int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) {
if (!F || !computeSummary())
return false;
- if (auto FunctionCount = F->getEntryCount())
- if (isHotCountNthPercentile(PercentileCutoff, FunctionCount.getCount()))
+ if (auto FunctionCount = F->getEntryCount()) {
+ if (isHot &&
+ isHotCountNthPercentile(PercentileCutoff, FunctionCount.getCount()))
return true;
-
+ if (!isHot &&
+ !isColdCountNthPercentile(PercentileCutoff, FunctionCount.getCount()))
+ return false;
+ }
if (hasSampleProfile()) {
uint64_t TotalCallCount = 0;
for (const auto &BB : *F)
@@ -211,13 +215,31 @@ bool ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile(
if (isa<CallInst>(I) || isa<InvokeInst>(I))
if (auto CallCount = getProfileCount(&I, nullptr))
TotalCallCount += CallCount.getValue();
- if (isHotCountNthPercentile(PercentileCutoff, TotalCallCount))
+ if (isHot && isHotCountNthPercentile(PercentileCutoff, TotalCallCount))
return true;
+ if (!isHot && !isColdCountNthPercentile(PercentileCutoff, TotalCallCount))
+ return false;
}
- for (const auto &BB : *F)
- if (isHotBlockNthPercentile(PercentileCutoff, &BB, &BFI))
+ for (const auto &BB : *F) {
+ if (isHot && isHotBlockNthPercentile(PercentileCutoff, &BB, &BFI))
return true;
- return false;
+ if (!isHot && !isColdBlockNthPercentile(PercentileCutoff, &BB, &BFI))
+ return false;
+ }
+ return !isHot;
+}
+
+// Like isFunctionHotInCallGraph but for a given cutoff.
+bool ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile(
+ int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) {
+ return isFunctionHotOrColdInCallGraphNthPercentile<true>(
+ PercentileCutoff, F, BFI);
+}
+
+bool ProfileSummaryInfo::isFunctionColdInCallGraphNthPercentile(
+ int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) {
+ return isFunctionHotOrColdInCallGraphNthPercentile<false>(
+ PercentileCutoff, F, BFI);
}
/// Returns true if the function's entry is a cold. If it returns false, it
@@ -299,9 +321,22 @@ bool ProfileSummaryInfo::isColdCount(uint64_t C) {
return ColdCountThreshold && C <= ColdCountThreshold.getValue();
}
-bool ProfileSummaryInfo::isHotCountNthPercentile(int PercentileCutoff, uint64_t C) {
+template<bool isHot>
+bool ProfileSummaryInfo::isHotOrColdCountNthPercentile(int PercentileCutoff,
+ uint64_t C) {
auto CountThreshold = computeThreshold(PercentileCutoff);
- return CountThreshold && C >= CountThreshold.getValue();
+ if (isHot)
+ return CountThreshold && C >= CountThreshold.getValue();
+ else
+ return CountThreshold && C <= CountThreshold.getValue();
+}
+
+bool ProfileSummaryInfo::isHotCountNthPercentile(int PercentileCutoff, uint64_t C) {
+ return isHotOrColdCountNthPercentile<true>(PercentileCutoff, C);
+}
+
+bool ProfileSummaryInfo::isColdCountNthPercentile(int PercentileCutoff, uint64_t C) {
+ return isHotOrColdCountNthPercentile<false>(PercentileCutoff, C);
}
uint64_t ProfileSummaryInfo::getOrCompHotCountThreshold() {
@@ -327,11 +362,27 @@ bool ProfileSummaryInfo::isColdBlock(const BasicBlock *BB,
return Count && isColdCount(*Count);
}
+template<bool isHot>
+bool ProfileSummaryInfo::isHotOrColdBlockNthPercentile(int PercentileCutoff,
+ const BasicBlock *BB,
+ BlockFrequencyInfo *BFI) {
+ auto Count = BFI->getBlockProfileCount(BB);
+ if (isHot)
+ return Count && isHotCountNthPercentile(PercentileCutoff, *Count);
+ else
+ return Count && isColdCountNthPercentile(PercentileCutoff, *Count);
+}
+
bool ProfileSummaryInfo::isHotBlockNthPercentile(int PercentileCutoff,
const BasicBlock *BB,
BlockFrequencyInfo *BFI) {
- auto Count = BFI->getBlockProfileCount(BB);
- return Count && isHotCountNthPercentile(PercentileCutoff, *Count);
+ return isHotOrColdBlockNthPercentile<true>(PercentileCutoff, BB, BFI);
+}
+
+bool ProfileSummaryInfo::isColdBlockNthPercentile(int PercentileCutoff,
+ const BasicBlock *BB,
+ BlockFrequencyInfo *BFI) {
+ return isHotOrColdBlockNthPercentile<false>(PercentileCutoff, BB, BFI);
}
bool ProfileSummaryInfo::isHotCallSite(const CallSite &CS,
diff --git a/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp b/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
index 8072e05c7cea..6c4e42aa7e05 100644
--- a/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
+++ b/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
@@ -65,6 +65,20 @@ class ProfileSummaryInfoTest : public testing::Test {
" %y2 = phi i32 [0, %bb1], [1, %bb2] \n"
" ret i32 %y2\n"
"}\n"
+ "define i32 @l(i32 %x) {{\n"
+ "bb0:\n"
+ " %y1 = icmp eq i32 %x, 0 \n"
+ " br i1 %y1, label %bb1, label %bb2, !prof !23 \n"
+ "bb1:\n"
+ " %z1 = call i32 @g(i32 %x)\n"
+ " br label %bb3\n"
+ "bb2:\n"
+ " %z2 = call i32 @h(i32 %x)\n"
+ " br label %bb3\n"
+ "bb3:\n"
+ " %y2 = phi i32 [0, %bb1], [1, %bb2] \n"
+ " ret i32 %y2\n"
+ "}\n"
"!20 = !{{!\"function_entry_count\", i64 400}\n"
"!21 = !{{!\"function_entry_count\", i64 1}\n"
"!22 = !{{!\"function_entry_count\", i64 100}\n"
@@ -141,14 +155,26 @@ TEST_F(ProfileSummaryInfoTest, TestCommon) {
EXPECT_FALSE(PSI.isHotCountNthPercentile(990000, 100));
EXPECT_FALSE(PSI.isHotCountNthPercentile(990000, 2));
+ EXPECT_FALSE(PSI.isColdCountNthPercentile(990000, 400));
+ EXPECT_TRUE(PSI.isColdCountNthPercentile(990000, 100));
+ EXPECT_TRUE(PSI.isColdCountNthPercentile(990000, 2));
+
EXPECT_TRUE(PSI.isHotCountNthPercentile(999999, 400));
EXPECT_TRUE(PSI.isHotCountNthPercentile(999999, 100));
EXPECT_FALSE(PSI.isHotCountNthPercentile(999999, 2));
+ EXPECT_FALSE(PSI.isColdCountNthPercentile(999999, 400));
+ EXPECT_FALSE(PSI.isColdCountNthPercentile(999999, 100));
+ EXPECT_TRUE(PSI.isColdCountNthPercentile(999999, 2));
+
EXPECT_FALSE(PSI.isHotCountNthPercentile(10000, 400));
EXPECT_FALSE(PSI.isHotCountNthPercentile(10000, 100));
EXPECT_FALSE(PSI.isHotCountNthPercentile(10000, 2));
+ EXPECT_TRUE(PSI.isColdCountNthPercentile(10000, 400));
+ EXPECT_TRUE(PSI.isColdCountNthPercentile(10000, 100));
+ EXPECT_TRUE(PSI.isColdCountNthPercentile(10000, 2));
+
EXPECT_TRUE(PSI.isFunctionEntryHot(F));
EXPECT_FALSE(PSI.isFunctionEntryHot(G));
EXPECT_FALSE(PSI.isFunctionEntryHot(H));
@@ -177,16 +203,31 @@ TEST_F(ProfileSummaryInfoTest, InstrProf) {
EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB2, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(990000, BB3, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB3, &BFI));
+
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, &BB0, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, BB1, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, BB2, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, BB3, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, BB1, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, BB3, &BFI));
+
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, &BB0, &BFI));
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, BB1, &BFI));
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, BB2, &BFI));
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, BB3, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, &BB0, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, BB1, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, BB2, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, BB3, &BFI));
+
CallSite CS1(BB1->getFirstNonPHI());
auto *CI2 = BB2->getFirstNonPHI();
CallSite CS2(CI2);
@@ -201,6 +242,31 @@ TEST_F(ProfileSummaryInfoTest, InstrProf) {
EXPECT_FALSE(PSI.isHotCallSite(CS2, &BFI));
}
+TEST_F(ProfileSummaryInfoTest, InstrProfNoFuncEntryCount) {
+ auto M = makeLLVMModule("InstrProf");
+ Function *F = M->getFunction("l");
+ ProfileSummaryInfo PSI = buildPSI(M.get());
+ EXPECT_TRUE(PSI.hasProfileSummary());
+ EXPECT_TRUE(PSI.hasInstrumentationProfile());
+
+ BasicBlock &BB0 = F->getEntryBlock();
+ BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0);
+ BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1);
+ BasicBlock *BB3 = BB1->getSingleSuccessor();
+
+ BlockFrequencyInfo BFI = buildBFI(*F);
+
+ // Without the entry count, all should return false.
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB3, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB3, &BFI));
+}
+
TEST_F(ProfileSummaryInfoTest, SampleProf) {
auto M = makeLLVMModule("SampleProfile");
Function *F = M->getFunction("f");
@@ -224,16 +290,31 @@ TEST_F(ProfileSummaryInfoTest, SampleProf) {
EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB2, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(990000, BB3, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB3, &BFI));
+
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, &BB0, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, BB1, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, BB2, &BFI));
EXPECT_TRUE(PSI.isHotBlockNthPercentile(999900, BB3, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, BB1, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(999900, BB3, &BFI));
+
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, &BB0, &BFI));
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, BB1, &BFI));
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, BB2, &BFI));
EXPECT_FALSE(PSI.isHotBlockNthPercentile(10000, BB3, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, &BB0, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, BB1, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, BB2, &BFI));
+ EXPECT_TRUE(PSI.isColdBlockNthPercentile(10000, BB3, &BFI));
+
CallSite CS1(BB1->getFirstNonPHI());
auto *CI2 = BB2->getFirstNonPHI();
// Manually attach branch weights metadata to the call instruction.
@@ -250,6 +331,51 @@ TEST_F(ProfileSummaryInfoTest, SampleProf) {
// weights that exceed the hot count threshold.
CI2->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights({400}));
EXPECT_TRUE(PSI.isHotCallSite(CS2, &BFI));
+
+ {
+ Function *F = M->getFunction("l");
+ BlockFrequencyInfo BFI = buildBFI(*F);
+ BasicBlock &BB0 = F->getEntryBlock();
+ BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0);
+ BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1);
+ BasicBlock *BB3 = BB1->getSingleSuccessor();
+
+ // Without the entry count, all should return false.
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB3, &BFI));
+
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB3, &BFI));
+ }
+}
+
+TEST_F(ProfileSummaryInfoTest, SampleProfNoFuncEntryCount) {
+ auto M = makeLLVMModule("SampleProfile");
+ Function *F = M->getFunction("l");
+ ProfileSummaryInfo PSI = buildPSI(M.get());
+ EXPECT_TRUE(PSI.hasProfileSummary());
+ EXPECT_TRUE(PSI.hasSampleProfile());
+
+ BasicBlock &BB0 = F->getEntryBlock();
+ BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0);
+ BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1);
+ BasicBlock *BB3 = BB1->getSingleSuccessor();
+
+ BlockFrequencyInfo BFI = buildBFI(*F);
+
+ // Without the entry count, all should return false.
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isHotBlockNthPercentile(990000, BB3, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, &BB0, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB1, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB2, &BFI));
+ EXPECT_FALSE(PSI.isColdBlockNthPercentile(990000, BB3, &BFI));
}
} // end anonymous namespace
More information about the llvm-commits
mailing list