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