1919#include " llvm/Support/Error.h"
2020#include " llvm/Support/ErrorHandling.h"
2121#include " llvm/Support/YAMLTraits.h"
22- #include < iterator>
2322#include < utility>
2423
2524using namespace llvm ;
@@ -58,26 +57,34 @@ Error PGOCtxProfileReader::unsupported(const Twine &Msg) {
5857 return make_error<InstrProfError>(instrprof_error::unsupported_version, Msg);
5958}
6059
61- bool PGOCtxProfileReader::canReadContext ( ) {
60+ bool PGOCtxProfileReader::canEnterBlockWithID (PGOCtxProfileBlockIDs ID ) {
6261 auto Blk = advance ();
6362 if (!Blk) {
6463 consumeError (Blk.takeError ());
6564 return false ;
6665 }
67- return Blk->Kind == BitstreamEntry::SubBlock &&
68- Blk->ID == PGOCtxProfileBlockIDs::ContextNodeBlockID;
66+ return Blk->Kind == BitstreamEntry::SubBlock && Blk->ID == ID;
67+ }
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,15 +175,23 @@ Error PGOCtxProfileReader::readMetadata() {
168175 return Error::success ();
169176}
170177
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+
171191Expected<PGOCtxProfile> PGOCtxProfileReader::loadProfiles () {
172- PGOCtxProfile Ret;
173192 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 ));
180195 return std::move (Ret);
181196}
182197
@@ -224,41 +239,54 @@ void toYaml(yaml::Output &Out,
224239 Out.endSequence ();
225240}
226241
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) {
228245 yaml::EmptyContext Empty;
229246 Out.beginMapping ();
230247 void *SaveInfo = nullptr ;
231248 bool UseDefault = false ;
232249 {
233250 Out.preflightKey (" Guid" , /* Required=*/ true , /* SameAsDefault=*/ false ,
234251 UseDefault, SaveInfo);
235- auto Guid = Ctx.guid ();
236252 yaml::yamlize (Out, Guid, true , Empty);
237253 Out.postflightKey (nullptr );
238254 }
239255 {
240256 Out.preflightKey (" Counters" , true , false , UseDefault, SaveInfo);
241257 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) {
243259 Out.preflightFlowElement (I, SaveInfo);
244- uint64_t V = Ctx. counters () [I];
260+ uint64_t V = Counters [I];
245261 yaml::yamlize (Out, V, true , Empty);
246262 Out.postflightFlowElement (SaveInfo);
247263 }
248264 Out.endFlowSequence ();
249265 Out.postflightKey (nullptr );
250266 }
251- if (!Ctx. callsites () .empty ()) {
267+ if (!Callsites .empty ()) {
252268 Out.preflightKey (" Callsites" , true , false , UseDefault, SaveInfo);
253- toYaml (Out, Ctx. callsites () );
269+ toYaml (Out, Callsites );
254270 Out.postflightKey (nullptr );
255271 }
256272 Out.endMapping ();
257273}
274+ void toYaml (yaml::Output &Out, const PGOCtxProfContext &Ctx) {
275+ toYaml (Out, Ctx.guid (), Ctx.counters (), Ctx.callsites ());
276+ }
277+
258278} // namespace
259279
260- void llvm::convertCtxProfToYaml (
261- raw_ostream &OS, const PGOCtxProfContext::CallTargetMapTy &Profiles) {
280+ void llvm::convertCtxProfToYaml (raw_ostream &OS,
281+ const PGOCtxProfile &Profiles) {
262282 yaml::Output Out (OS);
263- toYaml (Out, Profiles);
264- }
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 ();
292+ }
0 commit comments