mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
[NFC][StaticDataProfileInfo] Refactor StaticDataProfileInfo::getConstantSectionPrefix and extract analysis based on PGO-counter to be a helper function (#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 https://github.com/llvm/llvm-project/pull/163325 can extend this function to use global variable section prefix and compute a max (the hotter one). [1]975fba1b49/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (L3014-L3019)[2]975fba1b49/llvm/lib/CodeGen/StaticDataAnnotator.cpp (L77-L84)
This commit is contained in:
@@ -32,8 +32,11 @@ bool IsAnnotationOK(const GlobalVariable &GV);
|
||||
/// profile information and provides methods to operate on them.
|
||||
class StaticDataProfileInfo {
|
||||
public:
|
||||
/// Accummulate the profile count of a constant that will be lowered to static
|
||||
/// data sections.
|
||||
/// A constant is tracked only if the following conditions are met.
|
||||
/// 1) It has local (i.e., private or internal) linkage.
|
||||
// 2) Its data kind is one of {.rodata, .data, .bss, .data.rel.ro}.
|
||||
// 3) It's eligible for section prefix annotation. See `AnnotationKind`
|
||||
// above for ineligible reasons.
|
||||
DenseMap<const Constant *, uint64_t> ConstantProfileCounts;
|
||||
|
||||
/// Keeps track of the constants that are seen at least once without profile
|
||||
@@ -44,6 +47,22 @@ public:
|
||||
LLVM_ABI std::optional<uint64_t>
|
||||
getConstantProfileCount(const Constant *C) const;
|
||||
|
||||
/// Use signed enums for enum value comparison, and make 'LukewarmOrUnknown'
|
||||
/// as 0 so any accidentally uninitialized value will default to unknown.
|
||||
enum class StaticDataHotness : int8_t {
|
||||
Cold = -1,
|
||||
LukewarmOrUnknown = 0,
|
||||
Hot = 1,
|
||||
};
|
||||
|
||||
/// Return the hotness of the constant \p C based on its profile count \p
|
||||
/// Count.
|
||||
LLVM_ABI StaticDataHotness getConstantHotnessUsingProfileCount(
|
||||
const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const;
|
||||
|
||||
/// Return the string representation of the hotness enum \p Hotness.
|
||||
LLVM_ABI StringRef hotnessToStr(StaticDataHotness Hotness) const;
|
||||
|
||||
public:
|
||||
StaticDataProfileInfo() = default;
|
||||
|
||||
|
||||
@@ -60,6 +60,36 @@ void StaticDataProfileInfo::addConstantProfileCount(
|
||||
OriginalCount = getInstrMaxCountValue();
|
||||
}
|
||||
|
||||
StaticDataProfileInfo::StaticDataHotness
|
||||
StaticDataProfileInfo::getConstantHotnessUsingProfileCount(
|
||||
const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const {
|
||||
// The accummulated counter shows the constant is hot. Return enum 'hot'
|
||||
// whether this variable is seen by unprofiled functions or not.
|
||||
if (PSI->isHotCount(Count))
|
||||
return StaticDataHotness::Hot;
|
||||
// The constant is not hot, and seen by unprofiled functions. We don't want to
|
||||
// assign it to unlikely sections, even if the counter says 'cold'. So return
|
||||
// enum 'LukewarmOrUnknown'.
|
||||
if (ConstantWithoutCounts.count(C))
|
||||
return StaticDataHotness::LukewarmOrUnknown;
|
||||
// The accummulated counter shows the constant is cold so return enum 'cold'.
|
||||
if (PSI->isColdCount(Count))
|
||||
return StaticDataHotness::Cold;
|
||||
|
||||
return StaticDataHotness::LukewarmOrUnknown;
|
||||
}
|
||||
|
||||
StringRef StaticDataProfileInfo::hotnessToStr(StaticDataHotness Hotness) const {
|
||||
switch (Hotness) {
|
||||
case StaticDataHotness::Cold:
|
||||
return "unlikely";
|
||||
case StaticDataHotness::Hot:
|
||||
return "hot";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint64_t>
|
||||
StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const {
|
||||
auto I = ConstantProfileCounts.find(C);
|
||||
@@ -70,23 +100,10 @@ StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const {
|
||||
|
||||
StringRef StaticDataProfileInfo::getConstantSectionPrefix(
|
||||
const Constant *C, const ProfileSummaryInfo *PSI) const {
|
||||
auto Count = getConstantProfileCount(C);
|
||||
std::optional<uint64_t> Count = getConstantProfileCount(C);
|
||||
if (!Count)
|
||||
return "";
|
||||
// The accummulated counter shows the constant is hot. Return 'hot' whether
|
||||
// this variable is seen by unprofiled functions or not.
|
||||
if (PSI->isHotCount(*Count))
|
||||
return "hot";
|
||||
// The constant is not hot, and seen by unprofiled functions. We don't want to
|
||||
// assign it to unlikely sections, even if the counter says 'cold'. So return
|
||||
// an empty prefix before checking whether the counter is cold.
|
||||
if (ConstantWithoutCounts.count(C))
|
||||
return "";
|
||||
// The accummulated counter shows the constant is cold. Return 'unlikely'.
|
||||
if (PSI->isColdCount(*Count))
|
||||
return "unlikely";
|
||||
// The counter says lukewarm. Return an empty prefix.
|
||||
return "";
|
||||
return hotnessToStr(getConstantHotnessUsingProfileCount(C, PSI, *Count));
|
||||
}
|
||||
|
||||
bool StaticDataProfileInfoWrapperPass::doInitialization(Module &M) {
|
||||
|
||||
Reference in New Issue
Block a user