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