Skip to content

Commit c63002e

Browse files
[NFC][StaticDataProfileInfo] Refactor StaticDataProfileInfo::getConstantSectionPrefix and extract analysis based on PGO-counter to be a helper function (llvm#162388)
`StaticDataProfileInfo::getConstantSectionPrefix` is used twice in codegen ([1] and [2]) to emit section prefix for constants. Before this patch, its implementation does analysis using PGO-counters, and PGO-counters are only available on module-internal constants. After this patch, the PGO-counter analysis are extracted to a helper function, and returns enum rather than StringPrefix. This way, the follow up patch llvm#163325 can extend this function to use global variable section prefix and compute a max (the hotter one). [1] https://github.com/llvm/llvm-project/blob/975fba1b499422713e88cd6f374569f3bd38335e/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp#L3014-L3019 [2] https://github.com/llvm/llvm-project/blob/975fba1b499422713e88cd6f374569f3bd38335e/llvm/lib/CodeGen/StaticDataAnnotator.cpp#L77-L84
1 parent 9a46060 commit c63002e

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

llvm/include/llvm/Analysis/StaticDataProfileInfo.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ bool IsAnnotationOK(const GlobalVariable &GV);
3232
/// profile information and provides methods to operate on them.
3333
class StaticDataProfileInfo {
3434
public:
35-
/// Accummulate the profile count of a constant that will be lowered to static
36-
/// data sections.
35+
/// A constant is tracked only if the following conditions are met.
36+
/// 1) It has local (i.e., private or internal) linkage.
37+
// 2) Its data kind is one of {.rodata, .data, .bss, .data.rel.ro}.
38+
// 3) It's eligible for section prefix annotation. See `AnnotationKind`
39+
// above for ineligible reasons.
3740
DenseMap<const Constant *, uint64_t> ConstantProfileCounts;
3841

3942
/// Keeps track of the constants that are seen at least once without profile
@@ -44,6 +47,22 @@ class StaticDataProfileInfo {
4447
LLVM_ABI std::optional<uint64_t>
4548
getConstantProfileCount(const Constant *C) const;
4649

50+
/// Use signed enums for enum value comparison, and make 'LukewarmOrUnknown'
51+
/// as 0 so any accidentally uninitialized value will default to unknown.
52+
enum class StaticDataHotness : int8_t {
53+
Cold = -1,
54+
LukewarmOrUnknown = 0,
55+
Hot = 1,
56+
};
57+
58+
/// Return the hotness of the constant \p C based on its profile count \p
59+
/// Count.
60+
LLVM_ABI StaticDataHotness getConstantHotnessUsingProfileCount(
61+
const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const;
62+
63+
/// Return the string representation of the hotness enum \p Hotness.
64+
LLVM_ABI StringRef hotnessToStr(StaticDataHotness Hotness) const;
65+
4766
public:
4867
StaticDataProfileInfo() = default;
4968

llvm/lib/Analysis/StaticDataProfileInfo.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,36 @@ void StaticDataProfileInfo::addConstantProfileCount(
6060
OriginalCount = getInstrMaxCountValue();
6161
}
6262

63+
StaticDataProfileInfo::StaticDataHotness
64+
StaticDataProfileInfo::getConstantHotnessUsingProfileCount(
65+
const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const {
66+
// The accummulated counter shows the constant is hot. Return enum 'hot'
67+
// whether this variable is seen by unprofiled functions or not.
68+
if (PSI->isHotCount(Count))
69+
return StaticDataHotness::Hot;
70+
// The constant is not hot, and seen by unprofiled functions. We don't want to
71+
// assign it to unlikely sections, even if the counter says 'cold'. So return
72+
// enum 'LukewarmOrUnknown'.
73+
if (ConstantWithoutCounts.count(C))
74+
return StaticDataHotness::LukewarmOrUnknown;
75+
// The accummulated counter shows the constant is cold so return enum 'cold'.
76+
if (PSI->isColdCount(Count))
77+
return StaticDataHotness::Cold;
78+
79+
return StaticDataHotness::LukewarmOrUnknown;
80+
}
81+
82+
StringRef StaticDataProfileInfo::hotnessToStr(StaticDataHotness Hotness) const {
83+
switch (Hotness) {
84+
case StaticDataHotness::Cold:
85+
return "unlikely";
86+
case StaticDataHotness::Hot:
87+
return "hot";
88+
default:
89+
return "";
90+
}
91+
}
92+
6393
std::optional<uint64_t>
6494
StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const {
6595
auto I = ConstantProfileCounts.find(C);
@@ -70,23 +100,10 @@ StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const {
70100

71101
StringRef StaticDataProfileInfo::getConstantSectionPrefix(
72102
const Constant *C, const ProfileSummaryInfo *PSI) const {
73-
auto Count = getConstantProfileCount(C);
103+
std::optional<uint64_t> Count = getConstantProfileCount(C);
74104
if (!Count)
75105
return "";
76-
// The accummulated counter shows the constant is hot. Return 'hot' whether
77-
// this variable is seen by unprofiled functions or not.
78-
if (PSI->isHotCount(*Count))
79-
return "hot";
80-
// The constant is not hot, and seen by unprofiled functions. We don't want to
81-
// assign it to unlikely sections, even if the counter says 'cold'. So return
82-
// an empty prefix before checking whether the counter is cold.
83-
if (ConstantWithoutCounts.count(C))
84-
return "";
85-
// The accummulated counter shows the constant is cold. Return 'unlikely'.
86-
if (PSI->isColdCount(*Count))
87-
return "unlikely";
88-
// The counter says lukewarm. Return an empty prefix.
89-
return "";
106+
return hotnessToStr(getConstantHotnessUsingProfileCount(C, PSI, *Count));
90107
}
91108

92109
bool StaticDataProfileInfoWrapperPass::doInitialization(Module &M) {

0 commit comments

Comments
 (0)