LLVM: lib/ProfileData/PGOCtxProfWriter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
20
21using namespace llvm;
23
26 cl::desc("Also write profiles with all-zero counters. "
27 "Intended for testing/debugging."));
28
30 raw_ostream &Out, std::optional VersionOverride,
31 bool IncludeEmpty)
32 : Writer(Out, 0),
34 : IncludeEmpty) {
37 Writer.EnterBlockInfoBlock();
38 {
39 auto DescribeBlock = [&](unsigned ID, StringRef Name) {
40 Writer.EmitRecord(bitc::BLOCKINFO_CODE_SETBID,
41 SmallVector<unsigned, 1>{ID});
42 Writer.EmitRecord(bitc::BLOCKINFO_CODE_BLOCKNAME,
43 llvm::arrayRefFromStringRef(Name));
44 };
46 auto DescribeRecord = [&](unsigned RecordID, StringRef Name) {
47 Data.clear();
48 Data.push_back(RecordID);
49 llvm::append_range(Data, Name);
50 Writer.EmitRecord(bitc::BLOCKINFO_CODE_SETRECORDNAME, Data);
51 };
53 DescribeRecord(PGOCtxProfileRecords::Version, "Version");
58 "TotalRootEntryCount");
66 "FlatProfiles");
70 }
71 Writer.ExitBlock();
73 const auto Version = VersionOverride.value_or(CurrentVersion);
74 Writer.EmitRecord(PGOCtxProfileRecords::Version,
76}
77
84}
85
88}
89
90void PGOCtxProfileWriter::writeCallsiteIndex(uint32_t CallsiteIndex) {
93}
94
95void PGOCtxProfileWriter::writeRootEntryCount(uint64_t TotalRootEntryCount) {
98}
99
100
101
102
103
104void PGOCtxProfileWriter::writeNode(uint32_t CallsiteIndex,
105 const ContextNode &Node) {
106
107
108 if (!IncludeEmpty && (Node.counters_size() > 0 && Node.entrycount() == 0))
109 return;
111 writeGuid(Node.guid());
113 writeCounters({Node.counters(), Node.counters_size()});
114 writeSubcontexts(Node);
115 Writer.ExitBlock();
116}
117
118void PGOCtxProfileWriter::writeSubcontexts(const ContextNode &Node) {
119 for (uint32_t I = 0U; I < Node.callsites_size(); ++I)
120 for (const auto *Subcontext = Node.subContexts()[I]; Subcontext;
121 Subcontext = Subcontext->next())
122 writeNode(I, *Subcontext);
123}
124
128
133
136
142 return;
144 writeGuid(RootNode.guid());
147
149 for (const auto *P = Unhandled; P; P = P->next())
150 writeFlat(P->guid(), P->counters(), P->counters_size());
151 Writer.ExitBlock();
152
153 writeSubcontexts(RootNode);
154 Writer.ExitBlock();
155}
156
160 writeGuid(Guid);
161 writeCounters({Buffer, Size});
162 Writer.ExitBlock();
163}
164
165namespace {
166
167
168
169using SerializableFlatProfileRepresentation =
170 std::pair<ctx_profile::GUID, std::vector<uint64_t>>;
171
172struct SerializableCtxRepresentation {
174 std::vector<uint64_t> Counters;
175 std::vector<std::vector> Callsites;
176};
177
178struct SerializableRootRepresentation : public SerializableCtxRepresentation {
180 std::vector Unhandled;
181};
182
183struct SerializableProfileRepresentation {
184 std::vector Contexts;
185 std::vector FlatProfiles;
186};
187
189createNode(std::vector<std::unique_ptr<char[]>> &Nodes,
190 const std::vector &DCList);
191
192
193
195createNode(std::vector<std::unique_ptr<char[]>> &Nodes,
196 const SerializableCtxRepresentation &DC,
199 DC.Callsites.size());
200 auto *Mem = Nodes.emplace_back(std::make_unique<char[]>(AllocSize)).get();
201 std::memset(Mem, 0, AllocSize);
203 DC.Callsites.size(), Next);
204 std::memcpy(Ret->counters(), DC.Counters.data(),
205 sizeof(uint64_t) * DC.Counters.size());
206 for (const auto &[I, DCList] : llvm::enumerate(DC.Callsites))
207 Ret->subContexts()[I] = createNode(Nodes, DCList);
208 return Ret;
209}
210
211
212
214createNode(std::vector<std::unique_ptr<char[]>> &Nodes,
215 const std::vector &DCList) {
217 for (const auto &DC : DCList)
218 List = createNode(Nodes, DC, List);
220}
221}
222
234
238 IO.mapRequired("TotalRootEntryCount", R.TotalRootEntryCount);
240 }
241};
242
249
252 SerializableFlatProfileRepresentation &SFPR) {
255 }
256};
257
260 SerializableProfileRepresentation SPR;
261 In >> SPR;
262 if (In.error())
264 std::vector<std::unique_ptr<char[]>> Nodes;
265 std::error_code EC;
266 if (EC)
269
270 if (!SPR.Contexts.empty()) {
272 for (const auto &DC : SPR.Contexts) {
273 auto *TopList = createNode(Nodes, DC);
274 if (!TopList)
276 "Unexpected error converting internal structure to ctx profile");
277
279 for (const auto &U : DC.Unhandled) {
280 SerializableCtxRepresentation Unhandled;
281 Unhandled.Guid = U.first;
282 Unhandled.Counters = U.second;
283 FirstUnhandled = createNode(Nodes, Unhandled, FirstUnhandled);
284 }
285 Writer.writeContextual(*TopList, FirstUnhandled, DC.TotalRootEntryCount);
286 }
288 }
289 if (!SPR.FlatProfiles.empty()) {
291 for (const auto &[Guid, Counters] : SPR.FlatProfiles)
294 }
295 if (EC)
298}
static cl::opt< bool > IncludeEmptyOpt("ctx-prof-include-empty", cl::init(false), cl::desc("Also write profiles with all-zero counters. " "Intended for testing/debugging."))
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
Utility for declaring that a std::vector of a particular type should be considered a YAML sequence.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Write one or more ContextNodes to the provided raw_fd_stream.
void startFlatSection() override
Definition PGOCtxProfWriter.cpp:129
void writeContextual(const ctx_profile::ContextNode &RootNode, const ctx_profile::ContextNode *Unhandled, uint64_t TotalRootEntryCount) override
Definition PGOCtxProfWriter.cpp:137
static constexpr unsigned VBREncodingBits
PGOCtxProfileWriter(raw_ostream &Out, std::optional< unsigned > VersionOverride=std::nullopt, bool IncludeEmpty=false)
Definition PGOCtxProfWriter.cpp:29
void endFlatSection() override
Definition PGOCtxProfWriter.cpp:135
static constexpr StringRef ContainerMagic
static constexpr unsigned CodeLen
void startContextSection() override
Definition PGOCtxProfWriter.cpp:125
void endContextSection() override
Definition PGOCtxProfWriter.cpp:134
void writeFlat(ctx_profile::GUID Guid, const uint64_t *Buffer, size_t BufferSize) override
Definition PGOCtxProfWriter.cpp:157
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
uint64_t entrycount() const
static size_t getAllocSize(uint32_t NumCounters, uint32_t NumCallsites)
uint32_t counters_size() const
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write(unsigned char C)
void mapOptional(StringRef Key, T &Val)
void mapRequired(StringRef Key, T &Val)
The Input class is used to parse a yaml document into in-memory structs and vectors.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI Error createCtxProfFromYAML(StringRef Profile, raw_ostream &Out)
Definition PGOCtxProfWriter.cpp:258
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
FunctionAddr VTableAddr uintptr_t uintptr_t Version
FunctionAddr VTableAddr uintptr_t uintptr_t Data
FunctionAddr VTableAddr Next
@ FlatProfilesSectionBlockID
This class should be specialized by any type that needs to be converted to/from a YAML mapping.
static void mapping(yaml::IO &IO, SerializableCtxRepresentation &SCR)
Definition PGOCtxProfWriter.cpp:228
static void mapping(yaml::IO &IO, SerializableFlatProfileRepresentation &SFPR)
Definition PGOCtxProfWriter.cpp:251
static void mapping(yaml::IO &IO, SerializableProfileRepresentation &SPR)
Definition PGOCtxProfWriter.cpp:244
static void mapping(yaml::IO &IO, SerializableRootRepresentation &R)
Definition PGOCtxProfWriter.cpp:236