| 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; |
| 9 | void StaticDataProfileInfo::addConstantProfileCount( |
| 10 | const Constant *C, std::optional<uint64_t> Count) { |
| 11 | if (!Count) { |
| 12 | ConstantWithoutCounts.insert(V: C); |
| 13 | return; |
| 14 | } |
| 15 | uint64_t &OriginalCount = ConstantProfileCounts[C]; |
| 16 | OriginalCount = llvm::SaturatingAdd(X: *Count, Y: 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> |
| 24 | StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const { |
| 25 | auto I = ConstantProfileCounts.find(Val: C); |
| 26 | if (I == ConstantProfileCounts.end()) |
| 27 | return std::nullopt; |
| 28 | return I->second; |
| 29 | } |
| 30 | |
| 31 | 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(C: *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(V: C)) |
| 44 | return ""; |
| 45 | // The accummulated counter shows the constant is cold. Return 'unlikely'. |
| 46 | if (PSI->isColdCount(C: *Count)) |
| 47 | return "unlikely"; |
| 48 | // The counter says lukewarm. Return an empty prefix. |
| 49 | return ""; |
| 50 | } |
| 51 | |
| 52 | bool StaticDataProfileInfoWrapperPass::doInitialization(Module &M) { |
| 53 | Info.reset(p: new StaticDataProfileInfo()); |
| 54 | return false; |
| 55 | } |
| 56 | |
| 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 | |
| 65 | StaticDataProfileInfoWrapperPass::StaticDataProfileInfoWrapperPass() |
| 66 | : ImmutablePass(ID) {} |
| 67 | |
| 68 | char StaticDataProfileInfoWrapperPass::ID = 0; |
| 69 |