xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/StaticDataProfileInfo.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric #include "llvm/Analysis/StaticDataProfileInfo.h"
2*700637cbSDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
3*700637cbSDimitry Andric #include "llvm/IR/Constant.h"
4*700637cbSDimitry Andric #include "llvm/IR/GlobalVariable.h"
5*700637cbSDimitry Andric #include "llvm/InitializePasses.h"
6*700637cbSDimitry Andric #include "llvm/ProfileData/InstrProf.h"
7*700637cbSDimitry Andric 
8*700637cbSDimitry Andric using namespace llvm;
addConstantProfileCount(const Constant * C,std::optional<uint64_t> Count)9*700637cbSDimitry Andric void StaticDataProfileInfo::addConstantProfileCount(
10*700637cbSDimitry Andric     const Constant *C, std::optional<uint64_t> Count) {
11*700637cbSDimitry Andric   if (!Count) {
12*700637cbSDimitry Andric     ConstantWithoutCounts.insert(C);
13*700637cbSDimitry Andric     return;
14*700637cbSDimitry Andric   }
15*700637cbSDimitry Andric   uint64_t &OriginalCount = ConstantProfileCounts[C];
16*700637cbSDimitry Andric   OriginalCount = llvm::SaturatingAdd(*Count, OriginalCount);
17*700637cbSDimitry Andric   // Clamp the count to getInstrMaxCountValue. InstrFDO reserves a few
18*700637cbSDimitry Andric   // large values for special use.
19*700637cbSDimitry Andric   if (OriginalCount > getInstrMaxCountValue())
20*700637cbSDimitry Andric     OriginalCount = getInstrMaxCountValue();
21*700637cbSDimitry Andric }
22*700637cbSDimitry Andric 
23*700637cbSDimitry Andric std::optional<uint64_t>
getConstantProfileCount(const Constant * C) const24*700637cbSDimitry Andric StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const {
25*700637cbSDimitry Andric   auto I = ConstantProfileCounts.find(C);
26*700637cbSDimitry Andric   if (I == ConstantProfileCounts.end())
27*700637cbSDimitry Andric     return std::nullopt;
28*700637cbSDimitry Andric   return I->second;
29*700637cbSDimitry Andric }
30*700637cbSDimitry Andric 
getConstantSectionPrefix(const Constant * C,const ProfileSummaryInfo * PSI) const31*700637cbSDimitry Andric StringRef StaticDataProfileInfo::getConstantSectionPrefix(
32*700637cbSDimitry Andric     const Constant *C, const ProfileSummaryInfo *PSI) const {
33*700637cbSDimitry Andric   auto Count = getConstantProfileCount(C);
34*700637cbSDimitry Andric   if (!Count)
35*700637cbSDimitry Andric     return "";
36*700637cbSDimitry Andric   // The accummulated counter shows the constant is hot. Return 'hot' whether
37*700637cbSDimitry Andric   // this variable is seen by unprofiled functions or not.
38*700637cbSDimitry Andric   if (PSI->isHotCount(*Count))
39*700637cbSDimitry Andric     return "hot";
40*700637cbSDimitry Andric   // The constant is not hot, and seen by unprofiled functions. We don't want to
41*700637cbSDimitry Andric   // assign it to unlikely sections, even if the counter says 'cold'. So return
42*700637cbSDimitry Andric   // an empty prefix before checking whether the counter is cold.
43*700637cbSDimitry Andric   if (ConstantWithoutCounts.count(C))
44*700637cbSDimitry Andric     return "";
45*700637cbSDimitry Andric   // The accummulated counter shows the constant is cold. Return 'unlikely'.
46*700637cbSDimitry Andric   if (PSI->isColdCount(*Count))
47*700637cbSDimitry Andric     return "unlikely";
48*700637cbSDimitry Andric   // The counter says lukewarm. Return an empty prefix.
49*700637cbSDimitry Andric   return "";
50*700637cbSDimitry Andric }
51*700637cbSDimitry Andric 
doInitialization(Module & M)52*700637cbSDimitry Andric bool StaticDataProfileInfoWrapperPass::doInitialization(Module &M) {
53*700637cbSDimitry Andric   Info.reset(new StaticDataProfileInfo());
54*700637cbSDimitry Andric   return false;
55*700637cbSDimitry Andric }
56*700637cbSDimitry Andric 
doFinalization(Module & M)57*700637cbSDimitry Andric bool StaticDataProfileInfoWrapperPass::doFinalization(Module &M) {
58*700637cbSDimitry Andric   Info.reset();
59*700637cbSDimitry Andric   return false;
60*700637cbSDimitry Andric }
61*700637cbSDimitry Andric 
62*700637cbSDimitry Andric INITIALIZE_PASS(StaticDataProfileInfoWrapperPass, "static-data-profile-info",
63*700637cbSDimitry Andric                 "Static Data Profile Info", false, true)
64*700637cbSDimitry Andric 
StaticDataProfileInfoWrapperPass()65*700637cbSDimitry Andric StaticDataProfileInfoWrapperPass::StaticDataProfileInfoWrapperPass()
66*700637cbSDimitry Andric     : ImmutablePass(ID) {}
67*700637cbSDimitry Andric 
68*700637cbSDimitry Andric char StaticDataProfileInfoWrapperPass::ID = 0;
69