@@ -58,26 +58,33 @@ Error PGOCtxProfileReader::unsupported(const Twine &Msg) {
58
58
return make_error<InstrProfError>(instrprof_error::unsupported_version, Msg);
59
59
}
60
60
61
- bool PGOCtxProfileReader::canReadContext ( ) {
61
+ bool PGOCtxProfileReader::canEnterBlockWithID (PGOCtxProfileBlockIDs ID ) {
62
62
auto Blk = advance ();
63
63
if (!Blk) {
64
64
consumeError (Blk.takeError ());
65
65
return false ;
66
66
}
67
- return Blk->Kind == BitstreamEntry::SubBlock &&
68
- Blk->ID == PGOCtxProfileBlockIDs::ContextNodeBlockID;
67
+ return Blk->Kind == BitstreamEntry::SubBlock && Blk->ID == ID;
68
+ }
69
+ Error PGOCtxProfileReader::enterBlockWithID (PGOCtxProfileBlockIDs ID) {
70
+ RET_ON_ERR (Cursor.EnterSubBlock (ID));
71
+ return Error::success ();
69
72
}
70
73
71
74
Expected<std::pair<std::optional<uint32_t >, PGOCtxProfContext>>
72
- PGOCtxProfileReader::readContext (bool ExpectIndex) {
73
- RET_ON_ERR (Cursor.EnterSubBlock (PGOCtxProfileBlockIDs::ContextNodeBlockID));
75
+ PGOCtxProfileReader::readProfile (PGOCtxProfileBlockIDs Kind) {
76
+ assert ((Kind == PGOCtxProfileBlockIDs::ContextRootBlockID ||
77
+ Kind == PGOCtxProfileBlockIDs::ContextNodeBlockID) &&
78
+ " Unexpected profile kind" );
79
+ RET_ON_ERR (enterBlockWithID (Kind));
74
80
75
81
std::optional<ctx_profile::GUID> Guid;
76
82
std::optional<SmallVector<uint64_t , 16 >> Counters;
77
83
std::optional<uint32_t > CallsiteIndex;
78
84
79
85
SmallVector<uint64_t , 1 > RecordValues;
80
86
87
+ const bool ExpectIndex = Kind == PGOCtxProfileBlockIDs::ContextNodeBlockID;
81
88
// We don't prescribe the order in which the records come in, and we are ok
82
89
// if other unsupported records appear. We seek in the current subblock until
83
90
// we get all we know.
@@ -121,8 +128,8 @@ PGOCtxProfileReader::readContext(bool ExpectIndex) {
121
128
122
129
PGOCtxProfContext Ret (*Guid, std::move (*Counters));
123
130
124
- while (canReadContext ( )) {
125
- EXPECT_OR_RET (SC, readContext ( true ));
131
+ while (canEnterBlockWithID (PGOCtxProfileBlockIDs::ContextNodeBlockID )) {
132
+ EXPECT_OR_RET (SC, readProfile (PGOCtxProfileBlockIDs::ContextNodeBlockID ));
126
133
auto &Targets = Ret.callsites ()[*SC->first ];
127
134
auto [_, Inserted] =
128
135
Targets.insert ({SC->second .guid (), std::move (SC->second )});
@@ -168,15 +175,23 @@ Error PGOCtxProfileReader::readMetadata() {
168
175
return Error::success ();
169
176
}
170
177
178
+ Error PGOCtxProfileReader::loadContexts (CtxProfContextualProfiles &P) {
179
+ if (canEnterBlockWithID (PGOCtxProfileBlockIDs::ContextsSectionBlockID)) {
180
+ RET_ON_ERR (enterBlockWithID (PGOCtxProfileBlockIDs::ContextsSectionBlockID));
181
+ while (canEnterBlockWithID (PGOCtxProfileBlockIDs::ContextRootBlockID)) {
182
+ EXPECT_OR_RET (E, readProfile (PGOCtxProfileBlockIDs::ContextRootBlockID));
183
+ auto Key = E->second .guid ();
184
+ if (!P.insert ({Key, std::move (E->second )}).second )
185
+ return wrongValue (" Duplicate roots" );
186
+ }
187
+ }
188
+ return Error::success ();
189
+ }
190
+
171
191
Expected<PGOCtxProfile> PGOCtxProfileReader::loadProfiles () {
172
- PGOCtxProfile Ret;
173
192
RET_ON_ERR (readMetadata ());
174
- while (canReadContext ()) {
175
- EXPECT_OR_RET (E, readContext (false ));
176
- auto Key = E->second .guid ();
177
- if (!Ret.Contexts .insert ({Key, std::move (E->second )}).second )
178
- return wrongValue (" Duplicate roots" );
179
- }
193
+ PGOCtxProfile Ret;
194
+ RET_ON_ERR (loadContexts (Ret.Contexts ));
180
195
return std::move (Ret);
181
196
}
182
197
@@ -224,41 +239,54 @@ void toYaml(yaml::Output &Out,
224
239
Out.endSequence ();
225
240
}
226
241
227
- void toYaml (yaml::Output &Out, const PGOCtxProfContext &Ctx) {
242
+ void toYaml (yaml::Output &Out, GlobalValue::GUID Guid,
243
+ const SmallVectorImpl<uint64_t > &Counters,
244
+ const PGOCtxProfContext::CallsiteMapTy &Callsites) {
228
245
yaml::EmptyContext Empty;
229
246
Out.beginMapping ();
230
247
void *SaveInfo = nullptr ;
231
248
bool UseDefault = false ;
232
249
{
233
250
Out.preflightKey (" Guid" , /* Required=*/ true , /* SameAsDefault=*/ false ,
234
251
UseDefault, SaveInfo);
235
- auto Guid = Ctx.guid ();
236
252
yaml::yamlize (Out, Guid, true , Empty);
237
253
Out.postflightKey (nullptr );
238
254
}
239
255
{
240
256
Out.preflightKey (" Counters" , true , false , UseDefault, SaveInfo);
241
257
Out.beginFlowSequence ();
242
- for (size_t I = 0U , E = Ctx. counters () .size (); I < E; ++I) {
258
+ for (size_t I = 0U , E = Counters .size (); I < E; ++I) {
243
259
Out.preflightFlowElement (I, SaveInfo);
244
- uint64_t V = Ctx. counters () [I];
260
+ uint64_t V = Counters [I];
245
261
yaml::yamlize (Out, V, true , Empty);
246
262
Out.postflightFlowElement (SaveInfo);
247
263
}
248
264
Out.endFlowSequence ();
249
265
Out.postflightKey (nullptr );
250
266
}
251
- if (!Ctx. callsites () .empty ()) {
267
+ if (!Callsites .empty ()) {
252
268
Out.preflightKey (" Callsites" , true , false , UseDefault, SaveInfo);
253
- toYaml (Out, Ctx. callsites () );
269
+ toYaml (Out, Callsites );
254
270
Out.postflightKey (nullptr );
255
271
}
256
272
Out.endMapping ();
257
273
}
274
+ void toYaml (yaml::Output &Out, const PGOCtxProfContext &Ctx) {
275
+ toYaml (Out, Ctx.guid (), Ctx.counters (), Ctx.callsites ());
276
+ }
277
+
258
278
} // namespace
259
279
260
- void llvm::convertCtxProfToYaml (
261
- raw_ostream &OS, const PGOCtxProfContext::CallTargetMapTy &Profiles) {
280
+ void llvm::convertCtxProfToYaml (raw_ostream &OS,
281
+ const PGOCtxProfile &Profiles) {
262
282
yaml::Output Out (OS);
263
- toYaml (Out, Profiles);
283
+ void *SaveInfo = nullptr ;
284
+ bool UseDefault = false ;
285
+ Out.beginMapping ();
286
+ if (!Profiles.Contexts .empty ()) {
287
+ Out.preflightKey (" Contexts" , false , false , UseDefault, SaveInfo);
288
+ toYaml (Out, Profiles.Contexts );
289
+ Out.postflightKey (nullptr );
290
+ }
291
+ Out.endMapping ();
264
292
}
0 commit comments