@@ -58,26 +58,33 @@ Error PGOCtxProfileReader::unsupported(const Twine &Msg) {
5858 return make_error<InstrProfError>(instrprof_error::unsupported_version, Msg);
5959}
6060
61- bool PGOCtxProfileReader::canReadContext ( ) {
61+ bool PGOCtxProfileReader::canEnterBlockWithID (PGOCtxProfileBlockIDs ID ) {
6262 auto Blk = advance ();
6363 if (!Blk) {
6464 consumeError (Blk.takeError ());
6565 return false ;
6666 }
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 ();
6972}
7073
7174Expected<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));
7480
7581 std::optional<ctx_profile::GUID> Guid;
7682 std::optional<SmallVector<uint64_t , 16 >> Counters;
7783 std::optional<uint32_t > CallsiteIndex;
7884
7985 SmallVector<uint64_t , 1 > RecordValues;
8086
87+ const bool ExpectIndex = Kind == PGOCtxProfileBlockIDs::ContextNodeBlockID;
8188 // We don't prescribe the order in which the records come in, and we are ok
8289 // if other unsupported records appear. We seek in the current subblock until
8390 // we get all we know.
@@ -121,8 +128,8 @@ PGOCtxProfileReader::readContext(bool ExpectIndex) {
121128
122129 PGOCtxProfContext Ret (*Guid, std::move (*Counters));
123130
124- while (canReadContext ( )) {
125- EXPECT_OR_RET (SC, readContext ( true ));
131+ while (canEnterBlockWithID (PGOCtxProfileBlockIDs::ContextNodeBlockID )) {
132+ EXPECT_OR_RET (SC, readProfile (PGOCtxProfileBlockIDs::ContextNodeBlockID ));
126133 auto &Targets = Ret.callsites ()[*SC->first ];
127134 auto [_, Inserted] =
128135 Targets.insert ({SC->second .guid (), std::move (SC->second )});
@@ -168,16 +175,23 @@ Error PGOCtxProfileReader::readMetadata() {
168175 return Error::success ();
169176}
170177
171- Expected<std::map<GlobalValue::GUID, PGOCtxProfContext>>
172- PGOCtxProfileReader::loadContexts ( ) {
173- std::map<GlobalValue::GUID, PGOCtxProfContext> Ret ;
174- RET_ON_ERR ( readMetadata ());
175- while ( canReadContext ()) {
176- EXPECT_OR_RET (E, readContext ( false ) );
177- auto Key = E->second . guid ();
178- if (!Ret. insert ({Key, std::move (E-> second )}). second )
179- return wrongValue ( " Duplicate roots " );
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+ }
180187 }
188+ return Error::success ();
189+ }
190+
191+ Expected<PGOCtxProfile> PGOCtxProfileReader::loadProfiles () {
192+ RET_ON_ERR (readMetadata ());
193+ PGOCtxProfile Ret;
194+ RET_ON_ERR (loadContexts (Ret.Contexts ));
181195 return std::move (Ret);
182196}
183197
@@ -225,41 +239,54 @@ void toYaml(yaml::Output &Out,
225239 Out.endSequence ();
226240}
227241
228- 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) {
229245 yaml::EmptyContext Empty;
230246 Out.beginMapping ();
231247 void *SaveInfo = nullptr ;
232248 bool UseDefault = false ;
233249 {
234250 Out.preflightKey (" Guid" , /* Required=*/ true , /* SameAsDefault=*/ false ,
235251 UseDefault, SaveInfo);
236- auto Guid = Ctx.guid ();
237252 yaml::yamlize (Out, Guid, true , Empty);
238253 Out.postflightKey (nullptr );
239254 }
240255 {
241256 Out.preflightKey (" Counters" , true , false , UseDefault, SaveInfo);
242257 Out.beginFlowSequence ();
243- for (size_t I = 0U , E = Ctx. counters () .size (); I < E; ++I) {
258+ for (size_t I = 0U , E = Counters .size (); I < E; ++I) {
244259 Out.preflightFlowElement (I, SaveInfo);
245- uint64_t V = Ctx. counters () [I];
260+ uint64_t V = Counters [I];
246261 yaml::yamlize (Out, V, true , Empty);
247262 Out.postflightFlowElement (SaveInfo);
248263 }
249264 Out.endFlowSequence ();
250265 Out.postflightKey (nullptr );
251266 }
252- if (!Ctx. callsites () .empty ()) {
267+ if (!Callsites .empty ()) {
253268 Out.preflightKey (" Callsites" , true , false , UseDefault, SaveInfo);
254- toYaml (Out, Ctx. callsites () );
269+ toYaml (Out, Callsites );
255270 Out.postflightKey (nullptr );
256271 }
257272 Out.endMapping ();
258273}
274+ void toYaml (yaml::Output &Out, const PGOCtxProfContext &Ctx) {
275+ toYaml (Out, Ctx.guid (), Ctx.counters (), Ctx.callsites ());
276+ }
277+
259278} // namespace
260279
261- void llvm::convertCtxProfToYaml (
262- raw_ostream &OS, const PGOCtxProfContext::CallTargetMapTy &Profiles) {
280+ void llvm::convertCtxProfToYaml (raw_ostream &OS,
281+ const PGOCtxProfile &Profiles) {
263282 yaml::Output Out (OS);
264- 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 ();
265292}
0 commit comments