Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.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/ADT/ScopeExit.h"
16#include "llvm/Remarks/Remark.h"
17#include <cassert>
18#include <optional>
19
20using namespace llvm;
21using namespace llvm::remarks;
22
26
27static void setRecordName(unsigned RecordID, BitstreamWriter &Bitstream,
29 R.clear();
30 R.push_back(RecordID);
31 append_range(R, Str);
33}
34
35static void initBlock(unsigned BlockID, BitstreamWriter &Bitstream,
37 R.clear();
38 R.push_back(BlockID);
40
41 R.clear();
42 append_range(R, Str);
44}
45
47 // Setup the metadata block.
49
50 // The container information.
53
54 auto Abbrev = std::make_shared<BitCodeAbbrev>();
56 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version.
57 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Type.
59 Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
60}
61
65
66 auto Abbrev = std::make_shared<BitCodeAbbrev>();
68 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Version.
70 Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
71}
72
74 uint64_t RemarkVersion) {
75 // The remark version is emitted only if we emit remarks.
76 R.clear();
78 R.push_back(RemarkVersion);
79 Bitstream.EmitRecordWithAbbrev(RecordMetaRemarkVersionAbbrevID, R);
80}
81
84
85 auto Abbrev = std::make_shared<BitCodeAbbrev>();
87 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Raw table.
89 Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
90}
91
93 const StringTable &StrTab) {
94 // The string table is not emitted if we emit remarks separately.
95 R.clear();
96 R.push_back(RECORD_META_STRTAB);
97
98 // Serialize to a blob.
99 std::string Buf;
100 raw_string_ostream OS(Buf);
101 StrTab.serialize(OS);
102 StringRef Blob = OS.str();
103 Bitstream.EmitRecordWithBlob(RecordMetaStrTabAbbrevID, R, Blob);
104}
105
108
109 auto Abbrev = std::make_shared<BitCodeAbbrev>();
111 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename.
113 Bitstream.EmitBlockInfoAbbrev(META_BLOCK_ID, Abbrev);
114}
115
117 // The external file is emitted only if we emit the separate metadata.
118 R.clear();
119 R.push_back(RECORD_META_EXTERNAL_FILE);
120 Bitstream.EmitRecordWithBlob(RecordMetaExternalFileAbbrevID, R, Filename);
121}
122
124 // Setup the remark block.
126
127 // The header of a remark.
128 {
130
131 auto Abbrev = std::make_shared<BitCodeAbbrev>();
133 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Type
134 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Remark Name
135 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Pass name
136 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Function name
138 Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
139 }
140
141 // The location of a remark.
142 {
144
145 auto Abbrev = std::make_shared<BitCodeAbbrev>();
147 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // File
148 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line
149 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column
151 Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
152 }
153
154 // The hotness of a remark.
155 {
157
158 auto Abbrev = std::make_shared<BitCodeAbbrev>();
160 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Hotness
162 Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
163 }
164
165 // An argument entry with a debug location attached.
166 {
169
170 auto Abbrev = std::make_shared<BitCodeAbbrev>();
172 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key
173 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value
174 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // File
175 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line
176 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column
178 Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
179 }
180
181 // An argument entry with no debug location attached.
182 {
185
186 auto Abbrev = std::make_shared<BitCodeAbbrev>();
188 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Key
189 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // Value
191 Bitstream.EmitBlockInfoAbbrev(REMARK_BLOCK_ID, Abbrev);
192 }
193}
194
196 // Emit magic number.
197 for (const char C : ContainerMagic)
198 Bitstream.Emit(static_cast<unsigned>(C), 8);
199
200 Bitstream.EnterBlockInfoBlock();
201 auto ExitBlock = make_scope_exit([&] { Bitstream.ExitBlock(); });
202
203 // Setup the main metadata. Depending on the container type, we'll setup the
204 // required records next.
206
207 switch (ContainerType) {
209 // Needs to know where the external remarks file is.
211 return;
213 // Contains remarks: emit the version.
215 // Needs a string table.
217 // Contains remarks: emit the remark abbrevs.
219 return;
220 }
221 llvm_unreachable("Unexpected BitstreamRemarkContainerType");
222}
223
225 std::optional<StringRef> Filename) {
226 // Emit the meta block
227 Bitstream.EnterSubblock(META_BLOCK_ID, 3);
228 auto ExitBlock = make_scope_exit([&] { Bitstream.ExitBlock(); });
229
230 // The container version and type.
231 R.clear();
232 R.push_back(RECORD_META_CONTAINER_INFO);
233 R.push_back(CurrentContainerVersion);
234 R.push_back(static_cast<uint64_t>(ContainerType));
235 Bitstream.EmitRecordWithAbbrev(RecordMetaContainerInfoAbbrevID, R);
236
237 switch (ContainerType) {
239 assert(Filename != std::nullopt);
240 emitMetaExternalFile(*Filename);
241 return;
244 return;
245 }
246 llvm_unreachable("Unexpected BitstreamRemarkContainerType");
247}
248
250 const StringTable &StrTab) {
251 // Emit the late meta block (after all remarks are serialized)
252 Bitstream.EnterSubblock(META_BLOCK_ID, 3);
253 emitMetaStrTab(StrTab);
254 Bitstream.ExitBlock();
255}
256
258 StringTable &StrTab) {
259 Bitstream.EnterSubblock(REMARK_BLOCK_ID, 4);
260
261 R.clear();
262 R.push_back(RECORD_REMARK_HEADER);
263 R.push_back(static_cast<uint64_t>(Remark.RemarkType));
264 R.push_back(StrTab.add(Remark.RemarkName).first);
265 R.push_back(StrTab.add(Remark.PassName).first);
266 R.push_back(StrTab.add(Remark.FunctionName).first);
267 Bitstream.EmitRecordWithAbbrev(RecordRemarkHeaderAbbrevID, R);
268
269 if (const std::optional<RemarkLocation> &Loc = Remark.Loc) {
270 R.clear();
271 R.push_back(RECORD_REMARK_DEBUG_LOC);
272 R.push_back(StrTab.add(Loc->SourceFilePath).first);
273 R.push_back(Loc->SourceLine);
274 R.push_back(Loc->SourceColumn);
275 Bitstream.EmitRecordWithAbbrev(RecordRemarkDebugLocAbbrevID, R);
276 }
277
278 if (std::optional<uint64_t> Hotness = Remark.Hotness) {
279 R.clear();
280 R.push_back(RECORD_REMARK_HOTNESS);
281 R.push_back(*Hotness);
282 Bitstream.EmitRecordWithAbbrev(RecordRemarkHotnessAbbrevID, R);
283 }
284
285 for (const Argument &Arg : Remark.Args) {
286 R.clear();
287 unsigned Key = StrTab.add(Arg.Key).first;
288 unsigned Val = StrTab.add(Arg.Val).first;
289 bool HasDebugLoc = Arg.Loc != std::nullopt;
290 R.push_back(HasDebugLoc ? RECORD_REMARK_ARG_WITH_DEBUGLOC
292 R.push_back(Key);
293 R.push_back(Val);
294 if (HasDebugLoc) {
295 R.push_back(StrTab.add(Arg.Loc->SourceFilePath).first);
296 R.push_back(Arg.Loc->SourceLine);
297 R.push_back(Arg.Loc->SourceColumn);
298 }
299 Bitstream.EmitRecordWithAbbrev(HasDebugLoc
302 R);
303 }
304 Bitstream.ExitBlock();
305}
306
311
317
319
320void BitstreamRemarkSerializer::setup() {
321 if (Helper)
322 return;
324 Helper->setupBlockInfo();
325 Helper->emitMetaBlock();
326}
327
329 if (!Helper)
330 return;
331 Helper->emitLateMetaBlock(*StrTab);
332 Helper = std::nullopt;
333}
334
336 setup();
337 Helper->emitRemark(Remark, *StrTab);
338}
339
340std::unique_ptr<MetaSerializer>
342 StringRef ExternalFilename) {
343 return std::make_unique<BitstreamMetaSerializer>(
345}
346
348 assert(Helper && "BitstreamMetaSerializer emitted multiple times");
349 Helper->setupBlockInfo();
350 Helper->emitMetaBlock(ExternalFilename);
351 Helper = std::nullopt;
352}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void initBlock(unsigned BlockID, BitstreamWriter &Bitstream, SmallVectorImpl< uint64_t > &R, StringRef Str)
static void setRecordName(unsigned RecordID, BitstreamWriter &Bitstream, SmallVectorImpl< uint64_t > &R, StringRef Str)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
Definition BitCodes.h:34
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BLOCKINFO_CODE_BLOCKNAME
@ BLOCKINFO_CODE_SETRECORDNAME
@ BLOCKINFO_CODE_SETBID
constexpr StringLiteral RemarkDebugLocName("Remark debug location")
BitstreamRemarkContainerType
Type of the remark container.
@ RemarksFileExternal
Emit a link to an external remarks file (usually as a section of the object file, to enable discovery...
@ RemarksFile
Emit metadata and remarks into a file RemarksFile: | Meta: | | Container info | | Remark version | Re...
constexpr StringLiteral RemarkArgWithDebugLocName("Argument with debug location")
@ REMARK_BLOCK_ID
One remark entry is represented using a REMARK_BLOCK.
@ META_BLOCK_ID
The metadata block is mandatory.
constexpr uint64_t CurrentContainerVersion
The current version of the remark container.
constexpr StringLiteral MetaExternalFileName("External File")
constexpr StringLiteral MetaRemarkVersionName("Remark version")
Format
The format used for serializing/deserializing remarks.
constexpr StringLiteral MetaContainerInfoName("Container info")
constexpr StringLiteral RemarkHeaderName("Remark header")
constexpr StringLiteral MetaBlockName("Meta")
constexpr StringLiteral RemarkArgWithoutDebugLocName("Argument")
constexpr uint64_t CurrentRemarkVersion
The current version of the remark entry.
Definition Remark.h:29
constexpr StringLiteral RemarkBlockName("Remark")
constexpr StringLiteral ContainerMagic("RMRK")
The magic number used for identifying remark blocks.
constexpr StringLiteral MetaStrTabName("String table")
constexpr StringLiteral RemarkHotnessName("Remark hotness")
This is an optimization pass for GlobalISel generic memory operations.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition ScopeExit.h:59
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2116
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
A key-value pair with a debug location that is used to display the remarks at the right place in the ...
Definition Remark.h:47
std::optional< RemarkLocation > Loc
Definition Remark.h:52
std::optional< BitstreamRemarkSerializerHelper > Helper
void emitMetaBlock(std::optional< StringRef > Filename=std::nullopt)
Emit the main metadata at the beginning of the file.
void setupMetaBlockInfo()
Set up the block info for the metadata block.
BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType, raw_ostream &OS)
SmallVector< uint64_t, 64 > R
Buffer used to construct records and pass to the bitstream writer.
BitstreamRemarkContainerType ContainerType
The type of the container we are serializing.
void setupRemarkBlockInfo()
The block info for the remarks block.
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 setupMetaStrTab()
The strtab in the metadata block.
void emitLateMetaBlock(const StringTable &StrTab)
Emit the remaining metadata at the end of the file.
void emitRemark(const Remark &Remark, StringTable &StrTab)
Emit a remark block. The string table is required.
uint64_t RecordMetaContainerInfoAbbrevID
Abbrev IDs initialized in the block info block.
void finalize() override
Finalize emission of remarks.
std::unique_ptr< MetaSerializer > metaSerializer(raw_ostream &OS, StringRef ExternalFilename) override
The metadata serializer associated to this remark serializer.
std::optional< BitstreamRemarkSerializerHelper > Helper
The file should contain: 1) The block info block that describes how to read the blocks.
BitstreamRemarkSerializer(raw_ostream &OS)
Construct a serializer that will create its own string table.
void emit(const Remark &Remark) override
Emit a remark to the stream.
RemarkSerializer(Format SerializerFormat, raw_ostream &OS)
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:98
Type RemarkType
The type of the remark.
Definition Remark.h:100
StringRef PassName
Name of the pass that triggers the emission of this remark.
Definition Remark.h:103
std::optional< RemarkLocation > Loc
The location in the source file of the remark.
Definition Remark.h:114
std::optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
Definition Remark.h:118
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
Definition Remark.h:108
StringRef FunctionName
Mangled name of the function that triggers the emssion of this remark.
Definition Remark.h:111
SmallVector< Argument, 5 > Args
Arguments collected via the streaming interface.
Definition Remark.h:121
The string table used for serializing remarks.
LLVM_ABI void serialize(raw_ostream &OS) const
Serialize the string table to a stream.
LLVM_ABI std::pair< unsigned, StringRef > add(StringRef Str)
Add a string to the table. It returns an unique ID of the string.