mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
Use isFunctionHotInCallGraph to set the function section prefix.
Summary: The current prefix based function layout algorithm only looks at function's entry count, which is not sufficient. A function should be grouped together if its entry count or any call edge count is hot. Reviewers: davidxl, eraman Reviewed By: eraman Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31225 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298656 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cfb0063c60
commit
261eb1f850
@ -59,8 +59,12 @@ public:
|
|||||||
BlockFrequencyInfo *BFI);
|
BlockFrequencyInfo *BFI);
|
||||||
/// \brief Returns true if \p F has hot function entry.
|
/// \brief Returns true if \p F has hot function entry.
|
||||||
bool isFunctionEntryHot(const Function *F);
|
bool isFunctionEntryHot(const Function *F);
|
||||||
|
/// Returns true if \p F has hot function entry or hot call edge.
|
||||||
|
bool isFunctionHotInCallGraph(const Function *F);
|
||||||
/// \brief Returns true if \p F has cold function entry.
|
/// \brief Returns true if \p F has cold function entry.
|
||||||
bool isFunctionEntryCold(const Function *F);
|
bool isFunctionEntryCold(const Function *F);
|
||||||
|
/// Returns true if \p F has cold function entry or cold call edge.
|
||||||
|
bool isFunctionColdInCallGraph(const Function *F);
|
||||||
/// \brief Returns true if \p F is a hot function.
|
/// \brief Returns true if \p F is a hot function.
|
||||||
bool isHotCount(uint64_t C);
|
bool isHotCount(uint64_t C);
|
||||||
/// \brief Returns true if count \p C is considered cold.
|
/// \brief Returns true if count \p C is considered cold.
|
||||||
|
@ -98,6 +98,44 @@ bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) {
|
|||||||
return FunctionCount && isHotCount(FunctionCount.getValue());
|
return FunctionCount && isHotCount(FunctionCount.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the function's entry or total call edge count is hot.
|
||||||
|
/// If it returns false, it either means it is not hot or it is unknown
|
||||||
|
/// whether it is hot or not (for example, no profile data is available).
|
||||||
|
bool ProfileSummaryInfo::isFunctionHotInCallGraph(const Function *F) {
|
||||||
|
if (!F || !computeSummary())
|
||||||
|
return false;
|
||||||
|
if (auto FunctionCount = F->getEntryCount())
|
||||||
|
if (isHotCount(FunctionCount.getValue()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
uint64_t TotalCallCount = 0;
|
||||||
|
for (const auto &BB : *F)
|
||||||
|
for (const auto &I : BB)
|
||||||
|
if (isa<CallInst>(I) || isa<InvokeInst>(I))
|
||||||
|
if (auto CallCount = getProfileCount(&I, nullptr))
|
||||||
|
TotalCallCount += CallCount.getValue();
|
||||||
|
return isHotCount(TotalCallCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the function's entry and total call edge count is cold.
|
||||||
|
/// If it returns false, it either means it is not cold or it is unknown
|
||||||
|
/// whether it is cold or not (for example, no profile data is available).
|
||||||
|
bool ProfileSummaryInfo::isFunctionColdInCallGraph(const Function *F) {
|
||||||
|
if (!F || !computeSummary())
|
||||||
|
return false;
|
||||||
|
if (auto FunctionCount = F->getEntryCount())
|
||||||
|
if (!isColdCount(FunctionCount.getValue()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint64_t TotalCallCount = 0;
|
||||||
|
for (const auto &BB : *F)
|
||||||
|
for (const auto &I : BB)
|
||||||
|
if (isa<CallInst>(I) || isa<InvokeInst>(I))
|
||||||
|
if (auto CallCount = getProfileCount(&I, nullptr))
|
||||||
|
TotalCallCount += CallCount.getValue();
|
||||||
|
return isColdCount(TotalCallCount);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the function's entry is a cold. If it returns false, it
|
/// Returns true if the function's entry is a cold. If it returns false, it
|
||||||
/// either means it is not cold or it is unknown whether it is cold or not (for
|
/// either means it is not cold or it is unknown whether it is cold or not (for
|
||||||
/// example, no profile data is available).
|
/// example, no profile data is available).
|
||||||
|
@ -270,9 +270,9 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
|
|||||||
if (ProfileGuidedSectionPrefix) {
|
if (ProfileGuidedSectionPrefix) {
|
||||||
ProfileSummaryInfo *PSI =
|
ProfileSummaryInfo *PSI =
|
||||||
getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
|
getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
|
||||||
if (PSI->isFunctionEntryHot(&F))
|
if (PSI->isFunctionHotInCallGraph(&F))
|
||||||
F.setSectionPrefix(".hot");
|
F.setSectionPrefix(".hot");
|
||||||
else if (PSI->isFunctionEntryCold(&F))
|
else if (PSI->isFunctionColdInCallGraph(&F))
|
||||||
F.setSectionPrefix(".cold");
|
F.setSectionPrefix(".cold");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,32 @@ target triple = "x86_64-pc-linux-gnu"
|
|||||||
; This tests that hot/cold functions get correct section prefix assigned
|
; This tests that hot/cold functions get correct section prefix assigned
|
||||||
|
|
||||||
; CHECK: hot_func{{.*}}!section_prefix ![[HOT_ID:[0-9]+]]
|
; CHECK: hot_func{{.*}}!section_prefix ![[HOT_ID:[0-9]+]]
|
||||||
|
; The entry is hot
|
||||||
define void @hot_func() !prof !15 {
|
define void @hot_func() !prof !15 {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK: hot_call_func{{.*}}!section_prefix ![[HOT_ID]]
|
||||||
|
; The sum of 2 callsites are hot
|
||||||
|
define void @hot_call_func() !prof !16 {
|
||||||
|
call void @hot_func(), !prof !17
|
||||||
|
call void @hot_func(), !prof !17
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-NOT: normal_func{{.*}}!section_prefix
|
||||||
|
; The sum of all callsites are neither hot or cold
|
||||||
|
define void @normal_func() !prof !16 {
|
||||||
|
call void @hot_func(), !prof !17
|
||||||
|
call void @hot_func(), !prof !18
|
||||||
|
call void @hot_func(), !prof !18
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
; CHECK: cold_func{{.*}}!section_prefix ![[COLD_ID:[0-9]+]]
|
; CHECK: cold_func{{.*}}!section_prefix ![[COLD_ID:[0-9]+]]
|
||||||
|
; The entry and the callsite are both cold
|
||||||
define void @cold_func() !prof !16 {
|
define void @cold_func() !prof !16 {
|
||||||
|
call void @hot_func(), !prof !18
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,3 +53,5 @@ define void @cold_func() !prof !16 {
|
|||||||
!14 = !{i32 999999, i64 1, i32 2}
|
!14 = !{i32 999999, i64 1, i32 2}
|
||||||
!15 = !{!"function_entry_count", i64 1000}
|
!15 = !{!"function_entry_count", i64 1000}
|
||||||
!16 = !{!"function_entry_count", i64 1}
|
!16 = !{!"function_entry_count", i64 1}
|
||||||
|
!17 = !{!"branch_weights", i32 80}
|
||||||
|
!18 = !{!"branch_weights", i32 1}
|
||||||
|
Loading…
Reference in New Issue
Block a user