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"
9
10#define DEBUG_TYPE "static-data-profile-info"
11
12using namespace llvm;
13
14namespace llvm {
15// FIXME: This option is added for incremental rollout purposes.
16// After the option, string literal partitioning should be implied by
17// AnnotateStaticDataSectionPrefix in MemProfUse.cpp and this option should be
18// cleaned up.
20 "memprof-annotate-string-literal-section-prefix", cl::init(false),
22 cl::desc("If true, annotate the string literal data section prefix"));
23namespace memprof {
24// Returns true iff the global variable has custom section either by
25// __attribute__((section("name")))
26// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate)
27// or #pragma clang section directives
28// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section).
29static bool hasExplicitSectionName(const GlobalVariable &GVar) {
30 if (GVar.hasSection())
31 return true;
32
33 auto Attrs = GVar.getAttributes();
34 if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") ||
35 Attrs.hasAttribute("relro-section") ||
36 Attrs.hasAttribute("rodata-section"))
37 return true;
38 return false;
39}
40
44 // Skip 'llvm.'-prefixed global variables conservatively because they are
45 // often handled specially,
46 StringRef Name = GV.getName();
47 if (Name.starts_with("llvm."))
49 // Respect user-specified custom data sections.
53}
54
58} // namespace memprof
59} // namespace llvm
60
62 const Constant *C, std::optional<uint64_t> Count) {
63 if (!Count) {
65 return;
66 }
67 uint64_t &OriginalCount = ConstantProfileCounts[C];
68 OriginalCount = llvm::SaturatingAdd(*Count, OriginalCount);
69 // Clamp the count to getInstrMaxCountValue. InstrFDO reserves a few
70 // large values for special use.
71 if (OriginalCount > getInstrMaxCountValue())
72 OriginalCount = getInstrMaxCountValue();
73}
74
77 const Constant *C, const ProfileSummaryInfo *PSI, uint64_t Count) const {
78 // The accummulated counter shows the constant is hot. Return enum 'hot'
79 // whether this variable is seen by unprofiled functions or not.
80 if (PSI->isHotCount(Count))
82 // The constant is not hot, and seen by unprofiled functions. We don't want to
83 // assign it to unlikely sections, even if the counter says 'cold'. So return
84 // enum 'LukewarmOrUnknown'.
85 if (ConstantWithoutCounts.count(C))
87 // The accummulated counter shows the constant is cold so return enum 'cold'.
88 if (PSI->isColdCount(Count))
90
92}
93
96 std::optional<StringRef> MaybeSectionPrefix) const {
97 if (!MaybeSectionPrefix)
99 StringRef Prefix = *MaybeSectionPrefix;
100 assert((Prefix == "hot" || Prefix == "unlikely") &&
101 "Expect section_prefix to be one of hot or unlikely");
102 return Prefix == "hot" ? StaticDataHotness::Hot : StaticDataHotness::Cold;
103}
104
106 switch (Hotness) {
108 return "unlikely";
110 return "hot";
111 default:
112 return "";
113 }
114}
115
116std::optional<uint64_t>
118 auto I = ConstantProfileCounts.find(C);
119 if (I == ConstantProfileCounts.end())
120 return std::nullopt;
121 return I->second;
122}
123
125 const Constant *C, const ProfileSummaryInfo *PSI) const {
126 std::optional<uint64_t> Count = getConstantProfileCount(C);
127
128#ifndef NDEBUG
129 auto DbgPrintPrefix = [](StringRef Prefix) {
130 return Prefix.empty() ? "<empty>" : Prefix;
131 };
132#endif
133
135 // Both data access profiles and PGO counters are available. Use the
136 // hotter one to be conservative. Basically, we want the non-unlikely
137 // sections to have max coverage of accessed symbols and meanwhile can
138 // tolerant some cold symbols in it, and the unlikely section variant to not
139 // have potentially hot symbols if possible, to avoid the penalty of access
140 // cold pages.
144 !GV->getName().starts_with(".str"))) {
145 // Note a global var is covered by data access profiles iff the
146 // symbol name is preserved in the symbol table; most notably, a string
147 // literal with private linkage (e.g., those not externalized by ThinLTO
148 // and with insignificant address) won't have an entry in the symbol
149 // table (unless there is another string with identical content that
150 // gets a symbol table entry). For the private-linkage string literals,
151 // their hotness will be at least lukewarm (i.e., empty prefix).
152 auto HotnessFromDataAccessProf =
153 getSectionHotnessUsingDataAccessProfile(GV->getSectionPrefix());
154
155 if (!Count) {
156 StringRef Prefix = hotnessToStr(HotnessFromDataAccessProf);
157 LLVM_DEBUG(dbgs() << GV->getName() << " has section prefix "
158 << DbgPrintPrefix(Prefix)
159 << ", solely from data access profiles\n");
160 return Prefix;
161 }
162
163 auto HotnessFromPGO = getConstantHotnessUsingProfileCount(C, PSI, *Count);
165 if (HotnessFromDataAccessProf == StaticDataHotness::Hot ||
166 HotnessFromPGO == StaticDataHotness::Hot) {
167 GlobalVarHotness = StaticDataHotness::Hot;
168 } else if (HotnessFromDataAccessProf ==
170 HotnessFromPGO == StaticDataHotness::LukewarmOrUnknown) {
171 GlobalVarHotness = StaticDataHotness::LukewarmOrUnknown;
172 } else {
173 GlobalVarHotness = StaticDataHotness::Cold;
174 }
175 StringRef Prefix = hotnessToStr(GlobalVarHotness);
177 dbgs() << GV->getName() << " has section prefix "
178 << DbgPrintPrefix(Prefix)
179 << ", the max from data access profiles as "
180 << DbgPrintPrefix(hotnessToStr(HotnessFromDataAccessProf))
181 << " and PGO counters as "
182 << DbgPrintPrefix(hotnessToStr(HotnessFromPGO)) << "\n");
183 return Prefix;
184 }
185 }
186 if (!Count)
187 return "";
189}
190
192 bool EnableDataAccessProf = false;
194 M.getModuleFlag("EnableDataAccessProf")))
195 EnableDataAccessProf = MD->getZExtValue();
196 Info.reset(new StaticDataProfileInfo(EnableDataAccessProf));
197 return false;
198}
199
201 Info.reset();
202 return false;
203}
204
206 "Static Data Profile Info", false, true)
207
209 : ImmutablePass(ID) {}
210
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.
#define I(x, y, z)
Definition MD5.cpp:57
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
#define LLVM_DEBUG(...)
Definition Debug.h:114
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.
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 ...
A class that holds the constants that represent static data and their profile information and provide...
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
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
AnnotationKind getAnnotationKind(const GlobalVariable &GV)
Returns the annotation kind of the global variable GV.
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.
Definition Types.h:26
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:207
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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"))
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