LLVM 23.0.0git
StaticDataProfileInfo.cpp
Go to the documentation of this file.
3#include "llvm/IR/Constant.h"
4#include "llvm/IR/Constants.h"
6#include "llvm/IR/Module.h"
10
11#define DEBUG_TYPE "static-data-profile-info"
12
13using namespace llvm;
14
15namespace llvm {
16// FIXME: This option is added for incremental rollout purposes.
17// After the option, string literal partitioning should be implied by
18// AnnotateStaticDataSectionPrefix in MemProfUse.cpp and this option should be
19// cleaned up.
21 "memprof-annotate-string-literal-section-prefix", cl::init(false),
23 cl::desc("If true, annotate the string literal data section prefix"));
24namespace memprof {
25// Returns true iff the global variable has custom section either by
26// __attribute__((section("name")))
27// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate)
28// or #pragma clang section directives
29// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section).
30static bool hasExplicitSectionName(const GlobalVariable &GVar) {
31 if (GVar.hasSection())
32 return true;
33
34 auto Attrs = GVar.getAttributes();
35 if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") ||
36 Attrs.hasAttribute("relro-section") ||
37 Attrs.hasAttribute("rodata-section"))
38 return true;
39 return false;
40}
41
45 // Skip 'llvm.'-prefixed global variables conservatively because they are
46 // often handled specially,
47 StringRef Name = GV.getName();
48 if (Name.starts_with("llvm."))
50 // Respect user-specified custom data sections.
54}
55
59} // namespace memprof
60} // namespace llvm
61
63 const Constant *C, std::optional<uint64_t> Count) {
64 if (!Count) {
66 return;
67 }
68 uint64_t &OriginalCount = ConstantProfileCounts[C];
69 OriginalCount = llvm::SaturatingAdd(*Count, OriginalCount);
70 // Clamp the count to getInstrMaxCountValue. InstrFDO reserves a few
71 // large values for special use.
72 if (OriginalCount > getInstrMaxCountValue())
73 OriginalCount = getInstrMaxCountValue();
74}
75
78 const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const {
79 // The accummulated counter shows the constant is hot. Return enum 'hot'
80 // whether this variable is seen by unprofiled functions or not.
81 if (PSI->isHotCount(Count))
83 // The constant is not hot, and seen by unprofiled functions. We don't want to
84 // assign it to unlikely sections, even if the counter says 'cold'. So return
85 // enum 'LukewarmOrUnknown'.
86 if (ConstantWithoutCounts.count(C))
88 // The accummulated counter shows the constant is cold so return enum 'cold'.
89 if (PSI->isColdCount(Count))
91
93}
94
97 std::optional<StringRef> MaybeSectionPrefix) const {
98 if (!MaybeSectionPrefix)
100 StringRef Prefix = *MaybeSectionPrefix;
101 assert((Prefix == "hot" || Prefix == "unlikely") &&
102 "Expect section_prefix to be one of hot or unlikely");
103 return Prefix == "hot" ? StaticDataHotness::Hot : StaticDataHotness::Cold;
104}
105
107 switch (Hotness) {
109 return "unlikely";
111 return "hot";
112 default:
113 return "";
114 }
115}
116
117std::optional<uint64_t>
119 auto I = ConstantProfileCounts.find(C);
120 if (I == ConstantProfileCounts.end())
121 return std::nullopt;
122 return I->second;
123}
124
126 const Constant *C, const ProfileSummaryInfo *PSI) const {
127 std::optional<uint64_t> Count = getConstantProfileCount(C);
128
129#ifndef NDEBUG
130 auto DbgPrintPrefix = [](StringRef Prefix) {
131 return Prefix.empty() ? "<empty>" : Prefix;
132 };
133#endif
134
136 // Both data access profiles and PGO counters are available. Use the
137 // hotter one to be conservative. Basically, we want the non-unlikely
138 // sections to have max coverage of accessed symbols and meanwhile can
139 // tolerant some cold symbols in it, and the unlikely section variant to not
140 // have potentially hot symbols if possible, to avoid the penalty of access
141 // cold pages.
145 !GV->getName().starts_with(".str"))) {
146 // Note a global var is covered by data access profiles iff the
147 // symbol name is preserved in the symbol table; most notably, a string
148 // literal with private linkage (e.g., those not externalized by ThinLTO
149 // and with insignificant address) won't have an entry in the symbol
150 // table (unless there is another string with identical content that
151 // gets a symbol table entry). For the private-linkage string literals,
152 // their hotness will be at least lukewarm (i.e., empty prefix).
153 auto HotnessFromDataAccessProf =
154 getSectionHotnessUsingDataAccessProfile(GV->getSectionPrefix());
155
156 if (!Count) {
157 StringRef Prefix = hotnessToStr(HotnessFromDataAccessProf);
158 LLVM_DEBUG(dbgs() << GV->getName() << " has section prefix "
159 << DbgPrintPrefix(Prefix)
160 << ", solely from data access profiles\n");
161 return Prefix;
162 }
163
164 auto HotnessFromPGO = getConstantHotnessUsingProfileCount(C, PSI, *Count);
166 if (HotnessFromDataAccessProf == StaticDataHotness::Hot ||
167 HotnessFromPGO == StaticDataHotness::Hot) {
168 GlobalVarHotness = StaticDataHotness::Hot;
169 } else if (HotnessFromDataAccessProf ==
171 HotnessFromPGO == StaticDataHotness::LukewarmOrUnknown) {
172 GlobalVarHotness = StaticDataHotness::LukewarmOrUnknown;
173 } else {
174 GlobalVarHotness = StaticDataHotness::Cold;
175 }
176 StringRef Prefix = hotnessToStr(GlobalVarHotness);
178 dbgs() << GV->getName() << " has section prefix "
179 << DbgPrintPrefix(Prefix)
180 << ", the max from data access profiles as "
181 << DbgPrintPrefix(hotnessToStr(HotnessFromDataAccessProf))
182 << " and PGO counters as "
183 << DbgPrintPrefix(hotnessToStr(HotnessFromPGO)) << "\n");
184 return Prefix;
185 }
186 }
187 if (!Count)
188 return "";
190}
191
192static std::unique_ptr<StaticDataProfileInfo>
194 bool EnableDataAccessProf = false;
196 M.getModuleFlag("EnableDataAccessProf")))
197 EnableDataAccessProf = MD->getZExtValue();
198 return std::make_unique<StaticDataProfileInfo>(EnableDataAccessProf);
199}
200
205
207 Info.reset();
208 return false;
209}
210
212 "Static Data Profile Info", false, true)
213
215 : ImmutablePass(ID) {}
216
218
223
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define I(x, y, z)
Definition MD5.cpp:57
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static std::unique_ptr< StaticDataProfileInfo > computeStaticDataProfileInfo(Module &M)
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
#define LLVM_DEBUG(...)
Definition Debug.h:119
This is an important base class in LLVM.
Definition Constant.h:43
bool hasSection() const
Check if this global has a custom object file section.
bool isDeclarationForLinker() const
AttributeSet getAttributes() const
Return the attribute set for this global.
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition Pass.h:285
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Analysis providing profile information.
LLVM_ABI bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
LLVM_ABI bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
Result run(Module &M, ModuleAnalysisManager &)
This wraps the StaticDataProfileInfo object as an immutable pass, for a backend pass to operate on.
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
LLVM_ABI std::optional< uint64_t > getConstantProfileCount(const Constant *C) const
If C has a count, return it. Otherwise, return std::nullopt.
LLVM_ABI StaticDataHotness getConstantHotnessUsingProfileCount(const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const
Return the hotness of the constant C based on its profile count Count.
LLVM_ABI StringRef hotnessToStr(StaticDataHotness Hotness) const
Return the string representation of the hotness enum Hotness.
StaticDataHotness
Use signed enums for enum value comparison, and make 'LukewarmOrUnknown' as 0 so any accidentally uni...
LLVM_ABI void addConstantProfileCount(const Constant *C, std::optional< uint64_t > Count)
If Count is not nullopt, add it to the profile count of the constant C in a saturating way,...
LLVM_ABI StringRef getConstantSectionPrefix(const Constant *C, const ProfileSummaryInfo *PSI) const
Given a constant C, returns a section prefix.
LLVM_ABI StaticDataHotness getSectionHotnessUsingDataAccessProfile(std::optional< StringRef > SectionPrefix) const
Return the hotness based on section prefix SectionPrefix.
DenseMap< const Constant *, uint64_t > ConstantProfileCounts
A constant is tracked only if the following conditions are met.
DenseSet< const Constant * > ConstantWithoutCounts
Keeps track of the constants that are seen at least once without profile counts.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:683
LLVM_ABI AnnotationKind getAnnotationKind(const GlobalVariable &GV)
Returns the annotation kind of the global variable GV.
LLVM_ABI bool IsAnnotationOK(const GlobalVariable &GV)
Returns true if the annotation kind of the global variable GV is AnnotationOK.
static bool hasExplicitSectionName(const GlobalVariable &GVar)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
uint64_t getInstrMaxCountValue()
Return the max count value. We reserver a few large values for special use.
Definition InstrProf.h:97
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
cl::opt< bool > AnnotateStringLiteralSectionPrefix("memprof-annotate-string-literal-section-prefix", cl::init(false), cl::Hidden, cl::desc("If true, annotate the string literal data section prefix"))
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingAdd(T X, T Y, bool *ResultOverflowed=nullptr)
Add two unsigned integers, X and Y, of type T.
Definition MathExtras.h:609
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29