LLVM 20.0.0git
BitstreamRemarkSerializer.cpp
Go to the documentation of this file.
1//===- BitstreamRemarkSerializer.cpp --------------------------------------===//
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 implementation of the LLVM bitstream remark serializer
10// using LLVM's bitstream writer.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/Remarks/Remark.h"
16#include <optional>
17
18using namespace llvm;
19using namespace llvm::remarks;
20
22 BitstreamRemarkContainerType ContainerType)
23 : Bitstream(Encoded), ContainerType(ContainerType) {}
24
26 append_range(R, Str);
27}
28
29static void setRecordName(unsigned RecordID, BitstreamWriter &Bitstream,
31 R.clear();
32 R.push_back(RecordID);
33 push(R, Str);
35}
36
37static void initBlock(unsigned BlockID, BitstreamWriter &Bitstream,
39 R.clear();
40 R.push_back(BlockID);
42
43 R.clear();
44 push(R, Str);
46}
47
49 // Setup the metadata block.
51
52 // The container information.
55
56 auto Abbrev = std::make_shared<BitCodeAbbrev>();
58 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version.
59 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Type.
62}
63
67
68 auto Abbrev = std::make_shared<BitCodeAbbrev>();
70 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version.
73}
74
76 uint64_t RemarkVersion) {
77 // The remark version is emitted only if we emit remarks.
78 R.clear();
80 R.push_back(RemarkVersion);
82}
83
86
87 auto Abbrev = std::make_shared<BitCodeAbbrev>();
89 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Raw table.
92}
93
95 const StringTable &StrTab) {
96 // The string table is not emitted if we emit remarks separately.
97 R.clear();
99
100 // Serialize to a blob.
101 std::string Buf;
103 StrTab.serialize(OS);
104 StringRef Blob = OS.str();
106}
107
110
111 auto Abbrev = std::make_shared<BitCodeAbbrev>();
113 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename.
116}
117
119 // The external file is emitted only if we emit the separate metadata.
120 R.clear();
123}
124
126 // Setup the remark block.
128
129 // The header of a remark.
130 {
132
133 auto Abbrev = std::make_shared<BitCodeAbbrev>();
135 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Type
136 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Remark Name
137 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Pass name
138 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Function name
141 }
142
143 // The location of a remark.
144 {
146
147 auto Abbrev = std::make_shared<BitCodeAbbrev>();
149 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // File
150 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line
151 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column
154 }
155
156 // The hotness of a remark.
157 {
159
160 auto Abbrev = std::make_shared<BitCodeAbbrev>();
162 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Hotness
165 }
166
167 // An argument entry with a debug location attached.
168 {
171
172 auto Abbrev = std::make_shared<BitCodeAbbrev>();
174 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key
175 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value
176 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // File
177 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line
178 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column
181 }
182
183 // An argument entry with no debug location attached.
184 {
187
188 auto Abbrev = std::make_shared<BitCodeAbbrev>();
190 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key
191 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value
194 }
195}
196
198 // Emit magic number.
199 for (const char C : ContainerMagic)
200 Bitstream.Emit(static_cast<unsigned>(C), 8);
201
203
204 // Setup the main metadata. Depending on the container type, we'll setup the
205 // required records next.
207
208 switch (ContainerType) {
210 // Needs a string table that the separate remark file is using.
212 // Needs to know where the external remarks file is.
214 break;
216 // Contains remarks: emit the version.
218 // Contains remarks: emit the remark abbrevs.
220 break;
222 // Contains remarks: emit the version.
224 // Needs a string table.
226 // Contains remarks: emit the remark abbrevs.
228 break;
229 }
230
232}
233
235 uint64_t ContainerVersion, std::optional<uint64_t> RemarkVersion,
236 std::optional<const StringTable *> StrTab,
237 std::optional<StringRef> Filename) {
238 // Emit the meta block
240
241 // The container version and type.
242 R.clear();
244 R.push_back(ContainerVersion);
245 R.push_back(static_cast<uint64_t>(ContainerType));
247
248 switch (ContainerType) {
250 assert(StrTab != std::nullopt && *StrTab != nullptr);
251 emitMetaStrTab(**StrTab);
252 assert(Filename != std::nullopt);
253 emitMetaExternalFile(*Filename);
254 break;
256 assert(RemarkVersion != std::nullopt);
257 emitMetaRemarkVersion(*RemarkVersion);
258 break;
260 assert(RemarkVersion != std::nullopt);
261 emitMetaRemarkVersion(*RemarkVersion);
262 assert(StrTab != std::nullopt && *StrTab != nullptr);
263 emitMetaStrTab(**StrTab);
264 break;
265 }
266
268}
269
271 StringTable &StrTab) {
273
274 R.clear();
276 R.push_back(static_cast<uint64_t>(Remark.RemarkType));
277 R.push_back(StrTab.add(Remark.RemarkName).first);
278 R.push_back(StrTab.add(Remark.PassName).first);
279 R.push_back(StrTab.add(Remark.FunctionName).first);
281
282 if (const std::optional<RemarkLocation> &Loc = Remark.Loc) {
283 R.clear();
285 R.push_back(StrTab.add(Loc->SourceFilePath).first);
286 R.push_back(Loc->SourceLine);
287 R.push_back(Loc->SourceColumn);
289 }
290
291 if (std::optional<uint64_t> Hotness = Remark.Hotness) {
292 R.clear();
294 R.push_back(*Hotness);
296 }
297
298 for (const Argument &Arg : Remark.Args) {
299 R.clear();
300 unsigned Key = StrTab.add(Arg.Key).first;
301 unsigned Val = StrTab.add(Arg.Val).first;
302 bool HasDebugLoc = Arg.Loc != std::nullopt;
305 R.push_back(Key);
306 R.push_back(Val);
307 if (HasDebugLoc) {
308 R.push_back(StrTab.add(Arg.Loc->SourceFilePath).first);
309 R.push_back(Arg.Loc->SourceLine);
310 R.push_back(Arg.Loc->SourceColumn);
311 }
315 R);
316 }
318}
319
322 Encoded.clear();
323}
324
326 return StringRef(Encoded.data(), Encoded.size());
327}
328
330 SerializerMode Mode)
334 "For SerializerMode::Standalone, a pre-filled string table needs to "
335 "be provided.");
336 // We always use a string table with bitstream.
337 StrTab.emplace();
338}
339
341 SerializerMode Mode,
342 StringTable StrTabIn)
344 Helper(Mode == SerializerMode::Separate
347 StrTab = std::move(StrTabIn);
348}
349
351 if (!DidSetUp) {
352 // Emit the metadata that is embedded in the remark file.
353 // If we're in standalone mode, serialize the string table as well.
354 bool IsStandalone =
357 OS, Helper,
358 IsStandalone ? &*StrTab
359 : std::optional<const StringTable *>(std::nullopt));
361 DidSetUp = true;
362 }
363
365 "The Block info block and the meta block were not emitted yet.");
367
369}
370
371std::unique_ptr<MetaSerializer> BitstreamRemarkSerializer::metaSerializer(
372 raw_ostream &OS, std::optional<StringRef> ExternalFilename) {
375 bool IsStandalone =
377 return std::make_unique<BitstreamMetaSerializer>(
378 OS,
381 &*StrTab, ExternalFilename);
382}
383
389}
static void initBlock(unsigned BlockID, BitstreamWriter &Bitstream, SmallVectorImpl< uint64_t > &R, StringRef Str)
static void push(SmallVectorImpl< uint64_t > &R, StringRef Str)
static void setRecordName(unsigned RecordID, BitstreamWriter &Bitstream, SmallVectorImpl< uint64_t > &R, StringRef Str)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
Definition: BitCodes.h:33
void Emit(uint32_t Val, unsigned NumBits)
void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, StringRef Blob)
EmitRecordWithBlob - Emit the specified record to the stream, using an abbrev that includes a blob at...
unsigned EmitBlockInfoAbbrev(unsigned BlockID, std::shared_ptr< BitCodeAbbrev > Abbv)
EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified BlockID.
void EnterBlockInfoBlock()
EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
void EnterSubblock(unsigned BlockID, unsigned CodeLen)
void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals)
EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
size_t size() const
Definition: SmallVector.h:92
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:587
void push_back(const T &Elt)
Definition: SmallVector.h:427
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:300
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BLOCKINFO_CODE_BLOCKNAME
Definition: BitCodeEnums.h:82
@ BLOCKINFO_CODE_SETRECORDNAME
Definition: BitCodeEnums.h:83
@ BLOCKINFO_CODE_SETBID
Definition: BitCodeEnums.h:81
constexpr StringRef RemarkBlockName
BitstreamRemarkContainerType
Type of the remark container.
@ SeparateRemarksFile
The remarks emitted separately.
@ SeparateRemarksMeta
The metadata emitted separately.
@ Standalone
Everything is emitted together.
constexpr StringRef RemarkHotnessName
@ REMARK_BLOCK_ID
One remark entry is represented using a REMARK_BLOCK.
@ META_BLOCK_ID
The metadata block is mandatory.
constexpr StringRef RemarkArgWithDebugLocName
constexpr StringRef MetaStrTabName
constexpr uint64_t CurrentContainerVersion
The current version of the remark container.
constexpr StringRef MetaRemarkVersionName
Format
The format used for serializing/deserializing remarks.
Definition: RemarkFormat.h:25
constexpr StringRef MetaBlockName
constexpr uint64_t CurrentRemarkVersion
The current version of the remark entry.
Definition: Remark.h:28
constexpr StringRef MetaContainerInfoName
constexpr StringRef RemarkHeaderName
constexpr StringLiteral ContainerMagic("RMRK")
The magic number used for identifying remark blocks.
constexpr StringRef MetaExternalFileName
constexpr StringRef RemarkArgWithoutDebugLocName
constexpr StringRef RemarkDebugLocName
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2073
A key-value pair with a debug location that is used to display the remarks at the right place in the ...
Definition: Remark.h:46
std::optional< RemarkLocation > Loc
Definition: Remark.h:51
Serializer of metadata for bitstream remarks.
std::optional< const StringTable * > StrTab
BitstreamRemarkSerializerHelper * Helper
The actual helper, that can point to TmpHelper or to an external helper object.
SmallVector< char, 1024 > Encoded
Buffer used for encoding the bitstream before writing it to the final stream.
BitstreamWriter Bitstream
The Bitstream writer.
void setupMetaBlockInfo()
Set up the block info for the metadata block.
StringRef getBuffer()
Finalize the writing to a buffer.
SmallVector< uint64_t, 64 > R
Buffer used to construct records and pass to the bitstream writer.
BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType)
BitstreamRemarkContainerType ContainerType
The type of the container we are serializing.
void setupRemarkBlockInfo()
The block info for the remarks block.
void emitMetaBlock(uint64_t ContainerVersion, std::optional< uint64_t > RemarkVersion, std::optional< const StringTable * > StrTab=std::nullopt, std::optional< StringRef > Filename=std::nullopt)
Emit the metadata for the remarks.
void setupMetaExternalFile()
The external file in the metadata block.
void setupBlockInfo()
Set up the necessary block info entries according to the container type.
void setupMetaRemarkVersion()
The remark version in the metadata block.
void emitRemarkBlock(const Remark &Remark, StringTable &StrTab)
Emit a remark block. The string table is required.
void setupMetaStrTab()
The strtab in the metadata block.
void flushToStream(raw_ostream &OS)
Finalize the writing to OS.
uint64_t RecordMetaContainerInfoAbbrevID
Abbrev IDs initialized in the block info block.
BitstreamRemarkSerializer(raw_ostream &OS, SerializerMode Mode)
Construct a serializer that will create its own string table.
bool DidSetUp
The file should contain: 1) The block info block that describes how to read the blocks.
BitstreamRemarkSerializerHelper Helper
The helper to emit bitstream.
void emit(const Remark &Remark) override
Emit a remark to the stream.
std::unique_ptr< MetaSerializer > metaSerializer(raw_ostream &OS, std::optional< StringRef > ExternalFilename=std::nullopt) override
The metadata serializer associated to this remark serializer.
This is the base class for a remark metadata serializer.
raw_ostream & OS
The open raw_ostream that the metadata is emitted to.
This is the base class for a remark serializer.
SerializerMode Mode
The serialization mode.
std::optional< StringTable > StrTab
The string table containing all the unique strings used in the output.
raw_ostream & OS
The open raw_ostream that the remark diagnostics are emitted to.
A remark type used for both emission and parsing.
Definition: Remark.h:97
Type RemarkType
The type of the remark.
Definition: Remark.h:99
StringRef PassName
Name of the pass that triggers the emission of this remark.
Definition: Remark.h:102
std::optional< RemarkLocation > Loc
The location in the source file of the remark.
Definition: Remark.h:113
std::optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
Definition: Remark.h:117
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
Definition: Remark.h:107
StringRef FunctionName
Mangled name of the function that triggers the emssion of this remark.
Definition: Remark.h:110
SmallVector< Argument, 5 > Args
Arguments collected via the streaming interface.
Definition: Remark.h:120
The string table used for serializing remarks.
void serialize(raw_ostream &OS) const
Serialize the string table to a stream.
std::pair< unsigned, StringRef > add(StringRef Str)
Add a string to the table. It returns an unique ID of the string.