LLVM 22.0.0git
BitstreamRemarkParser.h
Go to the documentation of this file.
1//===-- BitstreamRemarkParser.h - Parser for Bitstream remarks --*- C++/-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides the impementation of the Bitstream remark parser.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_REMARKS_BITSTREAM_REMARK_PARSER_H
14#define LLVM_LIB_REMARKS_BITSTREAM_REMARK_PARSER_H
15
16#include "llvm/ADT/StringRef.h"
19#include "llvm/Remarks/Remark.h"
23#include "llvm/Support/Error.h"
25#include <cstdint>
26#include <memory>
27#include <optional>
28
29namespace llvm {
30namespace remarks {
31
33protected:
35
37 unsigned BlockID;
38
39public:
43
44 template <typename... Ts> Error error(char const *Fmt, const Ts &...Vals) {
45 std::string Buffer;
46 raw_string_ostream OS(Buffer);
47 OS << "Error while parsing " << BlockName << " block: ";
48 OS << formatv(Fmt, Vals...);
50 std::move(Buffer),
51 std::make_error_code(std::errc::illegal_byte_sequence));
52 }
53
55
56protected:
58
59 Error unknownRecord(unsigned AbbrevID);
62 Error unexpectedBlock(unsigned Code);
63};
64
65template <typename Derived>
67protected:
69 Derived &derived() { return *static_cast<Derived *>(this); }
70
71 /// Parse a record and fill in the fields in the parser.
72 /// The subclass must statically override this method.
73 Error parseRecord(unsigned Code) = delete;
74
75 /// Parse a subblock and fill in the fields in the parser.
76 /// The subclass can statically override this method.
77 Error parseSubBlock(unsigned Code) { return unexpectedBlock(Code); }
78
79public:
80 /// Enter, parse, and leave this bitstream block. This expects the
81 /// BitstreamCursor to be right after the SubBlock entry (i.e. after calling
82 /// expectBlock).
84 if (Error E = enterBlock())
85 return E;
86
87 // Stop when there is nothing to read anymore or when we encounter an
88 // END_BLOCK.
89 while (true) {
91 if (!Next)
92 return Next.takeError();
93 switch (Next->Kind) {
95 if (Error E = derived().parseSubBlock(Next->ID))
96 return E;
97 continue;
99 return Error::success();
101 if (Error E = derived().parseRecord(Next->ID))
102 return E;
103 continue;
105 return error("Unexpected end of bitstream.");
106 }
107 llvm_unreachable("Unexpected BitstreamEntry");
108 }
109 }
110};
111
112/// Helper to parse a META_BLOCK for a bitstream remark container.
114 : public BitstreamBlockParserHelper<BitstreamMetaParserHelper> {
116
117public:
122
123 /// The parsed content: depending on the container type, some fields might
124 /// be empty.
125 std::optional<ContainerInfo> Container;
126 std::optional<uint64_t> RemarkVersion;
127 std::optional<StringRef> ExternalFilePath;
128 std::optional<StringRef> StrTabBuf;
129
132
133protected:
134 Error parseRecord(unsigned Code);
135};
136
137/// Helper to parse a REMARK_BLOCK for a bitstream remark container.
139 : public BitstreamBlockParserHelper<BitstreamRemarkParserHelper> {
141
142protected:
145 unsigned RecordID;
146
147public:
153
154 struct Argument {
155 std::optional<uint64_t> KeyIdx;
156 std::optional<uint64_t> ValueIdx;
157 std::optional<RemarkLoc> Loc;
158
159 Argument(std::optional<uint64_t> KeyIdx, std::optional<uint64_t> ValueIdx)
161 };
162
163 /// The parsed content: depending on the remark, some fields might be empty.
164 std::optional<uint8_t> Type;
165 std::optional<uint64_t> RemarkNameIdx;
166 std::optional<uint64_t> PassNameIdx;
167 std::optional<uint64_t> FunctionNameIdx;
168 std::optional<uint64_t> Hotness;
169 std::optional<RemarkLoc> Loc;
170
172
175
176 /// Clear helper state and parse next remark block.
178
179protected:
180 Error parseRecord(unsigned Code);
182};
183
184/// Helper to parse any bitstream remark container.
186 /// The Bitstream reader.
188 /// The block info block.
190 /// Start parsing at \p Buffer.
192 /// Parse and validate the magic number.
194 /// Advance to the meta block
196 /// Parse the block info block containing all the abbrevs.
197 /// This needs to be called before calling any other parsing function.
199 /// Return true if the parser reached the end of the stream.
200 bool atEndOfStream() { return Stream.AtEndOfStream(); }
201};
202
203/// Parses and holds the state of the latest parsed remark.
205 /// The buffer to parse.
207 /// The string table used for parsing strings.
208 std::optional<ParsedStringTable> StrTab;
209 /// Temporary remark buffer used when the remarks are stored separately.
210 std::unique_ptr<MemoryBuffer> TmpRemarkBuffer;
211 /// The common metadata used to decide how to parse the buffer.
212 /// This is filled when parsing the metadata block.
217 /// Wether the parser is ready to parse remarks.
219
220 /// Create a parser that expects to find a string table embedded in the
221 /// stream.
222 explicit BitstreamRemarkParser(StringRef Buf);
223
225
226 static bool classof(const RemarkParser *P) {
227 return P->ParserFormat == Format::Bitstream;
228 }
229
230 /// Parse and process the metadata of the buffer.
232
233 /// Parse a Bitstream remark.
235
236private:
237 Error processCommonMeta(BitstreamMetaParserHelper &Helper);
238 Error processStandaloneMeta(BitstreamMetaParserHelper &Helper);
239 Error processSeparateRemarksFileMeta(BitstreamMetaParserHelper &Helper);
240 Error processSeparateRemarksMetaMeta(BitstreamMetaParserHelper &Helper);
241 Error processExternalFilePath(BitstreamMetaParserHelper &Helper);
242 Error processStrTab(BitstreamMetaParserHelper &Helper);
243 Error processRemarkVersion(BitstreamMetaParserHelper &Helper);
244
246 processRemark(BitstreamRemarkParserHelper &Helper);
247};
248
250 StringRef Buf,
251 std::optional<StringRef> ExternalFilePrependPath = std::nullopt);
252
253} // end namespace remarks
254} // end namespace llvm
255
256#endif /* LLVM_LIB_REMARKS_BITSTREAM_REMARK_PARSER_H */
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define P(N)
#define error(X)
This class maintains the abbreviations read from a block info block.
This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
A raw_ostream that writes to an std::string.
BitstreamBlockParserHelperBase(BitstreamCursor &Stream, unsigned BlockID, StringRef BlockName)
Error error(char const *Fmt, const Ts &...Vals)
BitstreamBlockParserHelperBase(BitstreamCursor &Stream, unsigned BlockID, StringRef BlockName)
Error parseBlock()
Enter, parse, and leave this bitstream block.
Error parseRecord(unsigned Code)=delete
Parse a record and fill in the fields in the parser.
Error parseSubBlock(unsigned Code)
Parse a subblock and fill in the fields in the parser.
Helper to parse a META_BLOCK for a bitstream remark container.
std::optional< ContainerInfo > Container
The parsed content: depending on the container type, some fields might be empty.
Helper to parse a REMARK_BLOCK for a bitstream remark container.
std::optional< uint8_t > Type
The parsed content: depending on the remark, some fields might be empty.
Error parseNext()
Clear helper state and parse next remark block.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BitstreamRemarkContainerType
Type of the remark container.
@ REMARK_BLOCK_ID
One remark entry is represented using a REMARK_BLOCK.
@ META_BLOCK_ID
The metadata block is mandatory.
Expected< std::unique_ptr< BitstreamRemarkParser > > createBitstreamParserFromMeta(StringRef Buf, std::optional< StringRef > ExternalFilePrependPath=std::nullopt)
constexpr StringLiteral MetaBlockName("Meta")
constexpr StringLiteral RemarkBlockName("Remark")
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
Helper to parse any bitstream remark container.
BitstreamParserHelper(StringRef Buffer)
Start parsing at Buffer.
Error advanceToMetaBlock()
Advance to the meta block.
bool atEndOfStream()
Return true if the parser reached the end of the stream.
BitstreamBlockInfo BlockInfo
The block info block.
BitstreamCursor Stream
The Bitstream reader.
Error parseBlockInfoBlock()
Parse the block info block containing all the abbrevs.
Error expectMagic()
Parse and validate the magic number.
Argument(std::optional< uint64_t > KeyIdx, std::optional< uint64_t > ValueIdx)
Error parseMeta()
Parse and process the metadata of the buffer.
std::optional< ParsedStringTable > StrTab
The string table used for parsing strings.
Expected< std::unique_ptr< Remark > > parseRemark()
Parse a Bitstream remark.
std::unique_ptr< MemoryBuffer > TmpRemarkBuffer
Temporary remark buffer used when the remarks are stored separately.
uint64_t ContainerVersion
The common metadata used to decide how to parse the buffer.
BitstreamParserHelper ParserHelper
The buffer to parse.
Expected< std::unique_ptr< Remark > > next() override
If no error occurs, this returns a valid Remark object.
static bool classof(const RemarkParser *P)
BitstreamRemarkParser(StringRef Buf)
Create a parser that expects to find a string table embedded in the stream.
BitstreamRemarkContainerType ContainerType
bool ReadyToParseRemarks
Wether the parser is ready to parse remarks.
RemarkParser(Format ParserFormat)