11#include " llvm/Analysis/StaticDataProfileInfo.h"
22#include " llvm/Analysis/ProfileSummaryInfo.h"
33#include " llvm/IR/Constant.h"
4+ #include " llvm/IR/Constants.h"
45#include " llvm/IR/GlobalVariable.h"
6+ #include " llvm/IR/Module.h"
57#include " llvm/InitializePasses.h"
68#include " llvm/ProfileData/InstrProf.h"
79
10+ #define DEBUG_TYPE " static-data-profile-info"
11+
812using namespace llvm ;
913
1014namespace llvm {
@@ -46,6 +50,12 @@ bool IsAnnotationOK(const GlobalVariable &GV) {
4650} // namespace memprof
4751} // namespace llvm
4852
53+ #ifndef NDEBUG
54+ static StringRef debugPrintSectionPrefix (StringRef Prefix) {
55+ return Prefix.empty () ? " <empty>" : Prefix;
56+ }
57+ #endif
58+
4959void StaticDataProfileInfo::addConstantProfileCount (
5060 const Constant *C, std::optional<uint64_t > Count) {
5161 if (!Count) {
@@ -79,6 +89,18 @@ StaticDataProfileInfo::getSectionHotnessUsingProfileCount(
7989 return StaticDataHotness::LukewarmOrUnknown;
8090}
8191
92+ StaticDataProfileInfo::StaticDataHotness
93+ StaticDataProfileInfo::getSectionHotnessUsingDAP (
94+ std::optional<StringRef> MaybeSectionPrefix) const {
95+ if (!MaybeSectionPrefix)
96+ return StaticDataProfileInfo::StaticDataHotness::LukewarmOrUnknown;
97+ StringRef Prefix = *MaybeSectionPrefix;
98+ assert ((Prefix == " hot" || Prefix == " unlikely" ) &&
99+ " Expect section_prefix to be one of hot or unlikely" );
100+ return Prefix == " hot" ? StaticDataProfileInfo::StaticDataHotness::Hot
101+ : StaticDataProfileInfo::StaticDataHotness::Cold;
102+ }
103+
82104StringRef StaticDataProfileInfo::hotnessToStr (
83105 StaticDataProfileInfo::StaticDataHotness Hotness) const {
84106 switch (Hotness) {
@@ -102,13 +124,49 @@ StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const {
102124StringRef StaticDataProfileInfo::getConstantSectionPrefix (
103125 const Constant *C, const ProfileSummaryInfo *PSI) const {
104126 std::optional<uint64_t > Count = getConstantProfileCount (C);
127+
128+ if (EnableDataAccessProf) {
129+ // Module flag `HasDataAccessProf` is 1 -> empty section prefix means
130+ // unknown hotness except for string literals.
131+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(C);
132+ GV && llvm::memprof::IsAnnotationOK (*GV) &&
133+ !GV->getName ().starts_with (" .str" )) {
134+ auto HotnessFromDAP = getSectionHotnessUsingDAP (GV->getSectionPrefix ());
135+
136+ if (!Count) {
137+ StringRef Prefix = hotnessToStr (HotnessFromDAP);
138+ LLVM_DEBUG (dbgs () << GV->getName () << " has section prefix "
139+ << debugPrintSectionPrefix (Prefix)
140+ << " , solely from data access profiles\n " );
141+ return Prefix;
142+ }
143+
144+ // Both DAP and PGO counters are available. Use the hotter one.
145+ auto HotnessFromPGO = getSectionHotnessUsingProfileCount (C, PSI, *Count);
146+ StringRef Prefix = hotnessToStr (std::max (HotnessFromDAP, HotnessFromPGO));
147+ LLVM_DEBUG (dbgs () << GV->getName () << " has section prefix "
148+ << debugPrintSectionPrefix (Prefix)
149+ << " , the max from DAP as "
150+ << debugPrintSectionPrefix (hotnessToStr (HotnessFromDAP))
151+ << " and PGO counters as "
152+ << debugPrintSectionPrefix (hotnessToStr (HotnessFromPGO))
153+ << " \n " );
154+ return Prefix;
155+ }
156+ }
105157 if (!Count)
106158 return " " ;
159+
107160 return hotnessToStr (getSectionHotnessUsingProfileCount (C, PSI, *Count));
108161}
109162
110163bool StaticDataProfileInfoWrapperPass::doInitialization (Module &M) {
111- Info.reset (new StaticDataProfileInfo ());
164+ bool EnableDataAccessProf = false ;
165+ if (auto *MD = mdconst::extract_or_null<ConstantInt>(
166+ M.getModuleFlag (" EnableDataAccessProf" )))
167+ EnableDataAccessProf = MD->getZExtValue ();
168+ errs () << " EnableDataAccessProf: " << EnableDataAccessProf << " \n " ;
169+ Info.reset (new StaticDataProfileInfo (EnableDataAccessProf));
112170 return false ;
113171}
114172
0 commit comments