25#define EXPECT_OR_RET(LHS, RHS) \
28 return LHS.takeError();
30#define RET_ON_ERR(EXPR) \
31 if (auto Err = (EXPR)) \
37 auto [Iter, Inserted] =
41 "Duplicate GUID for same callsite.");
49Error PGOCtxProfileReader::wrongValue(
const Twine &Msg) {
53Error PGOCtxProfileReader::unsupported(
const Twine &Msg) {
57bool PGOCtxProfileReader::canReadContext() {
68PGOCtxProfileReader::readContext(
bool ExpectIndex) {
71 std::optional<ctx_profile::GUID>
Guid;
72 std::optional<SmallVector<uint64_t, 16>>
Counters;
73 std::optional<uint32_t> CallsiteIndex;
80 auto GotAllWeNeed = [&]() {
82 (!ExpectIndex || CallsiteIndex.has_value());
84 while (!GotAllWeNeed()) {
89 "Expected records before encountering more subcontexts");
92 switch (*ReadRecord) {
94 if (RecordValues.
size() != 1)
95 return wrongValue(
"The GUID record should have exactly one value");
96 Guid = RecordValues[0];
101 return wrongValue(
"Empty counters. At least the entry counter (one "
102 "value) was expected");
106 return wrongValue(
"The root context should not have a callee index");
107 if (RecordValues.
size() != 1)
108 return wrongValue(
"The callee index should have exactly one value");
109 CallsiteIndex = RecordValues[0];
120 while (canReadContext()) {
122 auto &Targets =
Ret.callsites()[*
SC->first];
124 Targets.insert({
SC->second.guid(), std::move(
SC->second)});
127 "Unexpected duplicate target (callee) at the same callsite.");
129 return std::make_pair(CallsiteIndex, std::move(Ret));
132Error PGOCtxProfileReader::readMetadata() {
142 return unsupported(
"Expected Block ID");
149 return unsupported(
"Expected Version record");
154 return unsupported(
"Expected Version record");
159 return unsupported(
"Expected Version record");
161 return unsupported(
"Version " +
Twine(*Code) +
162 " is higher than supported version " +
169 std::map<GlobalValue::GUID, PGOCtxProfContext> Ret;
171 while (canReadContext()) {
173 auto Key = E->second.guid();
174 if (!Ret.insert({Key, std::move(E->second)}).second)
175 return wrongValue(
"Duplicate roots");
177 return std::move(Ret);
#define EXPECT_OR_RET(LHS, RHS)
Reader for contextual iFDO profile, which comes in bitstream format.
Expected< BitstreamEntry > advance(unsigned Flags=0)
Advance the current bitstream, returning the next entry in the stream.
Expected< unsigned > readRecord(unsigned AbbrevID, SmallVectorImpl< uint64_t > &Vals, StringRef *Blob=nullptr)
Error EnterSubBlock(unsigned BlockID, unsigned *NumWordsP=nullptr)
Having read the ENTER_SUBBLOCK abbrevid, and enter the block.
@ AF_DontAutoprocessAbbrevs
If this flag is used, abbrev entries are returned just like normal records.
Error SkipBlock()
Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body of this block.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
A node (context) in the loaded contextual profile, suitable for mutation during IPO passes.
Expected< std::map< GlobalValue::GUID, PGOCtxProfContext > > loadContexts()
static constexpr uint32_t CurrentVersion
static constexpr StringRef ContainerMagic
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
constexpr size_t size() const
size - Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ BLOCKINFO_BLOCK_ID
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
This is an optimization pass for GlobalISel generic memory operations.
void consumeError(Error Err)
Consume a Error without doing anything.
When advancing through a bitstream cursor, each advance can discover a few different kinds of entries...