1 //===-- BitstreamRemarkSerializer.h - Bitstream serializer ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file provides an implementation of the serializer using the LLVM
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_REMARKS_BITSTREAM_REMARK_SERIALIZER_H
15 #define LLVM_REMARKS_BITSTREAM_REMARK_SERIALIZER_H
17 #include "llvm/Bitstream/BitstreamWriter.h"
18 #include "llvm/Remarks/BitstreamRemarkContainer.h"
19 #include "llvm/Remarks/RemarkSerializer.h"
20 #include "llvm/Support/raw_ostream.h"
25 /// Serialize the remarks to LLVM bitstream.
26 /// This class provides ways to emit remarks in the LLVM bitstream format and
27 /// its associated metadata.
29 /// * The separate model:
30 /// Separate meta: | Container info
34 /// Separate remarks: | Container info
41 /// * The standalone model: | Container info
49 struct BitstreamRemarkSerializerHelper
{
50 /// Buffer used for encoding the bitstream before writing it to the final
52 SmallVector
<char, 1024> Encoded
;
53 /// Buffer used to construct records and pass to the bitstream writer.
54 SmallVector
<uint64_t, 64> R
;
55 /// The Bitstream writer.
56 BitstreamWriter Bitstream
;
57 /// The type of the container we are serializing.
58 BitstreamRemarkContainerType ContainerType
;
60 /// Abbrev IDs initialized in the block info block.
61 /// Note: depending on the container type, some IDs might be uninitialized.
62 /// Warning: When adding more abbrev IDs, make sure to update the
63 /// BlockCodeSize (in the call to EnterSubblock).
64 uint64_t RecordMetaContainerInfoAbbrevID
= 0;
65 uint64_t RecordMetaRemarkVersionAbbrevID
= 0;
66 uint64_t RecordMetaStrTabAbbrevID
= 0;
67 uint64_t RecordMetaExternalFileAbbrevID
= 0;
68 uint64_t RecordRemarkHeaderAbbrevID
= 0;
69 uint64_t RecordRemarkDebugLocAbbrevID
= 0;
70 uint64_t RecordRemarkHotnessAbbrevID
= 0;
71 uint64_t RecordRemarkArgWithDebugLocAbbrevID
= 0;
72 uint64_t RecordRemarkArgWithoutDebugLocAbbrevID
= 0;
74 BitstreamRemarkSerializerHelper(BitstreamRemarkContainerType ContainerType
);
76 // Disable copy and move: Bitstream points to Encoded, which needs special
77 // handling during copy/move, but moving the vectors is probably useless
79 BitstreamRemarkSerializerHelper(const BitstreamRemarkSerializerHelper
&) =
81 BitstreamRemarkSerializerHelper
&
82 operator=(const BitstreamRemarkSerializerHelper
&) = delete;
83 BitstreamRemarkSerializerHelper(BitstreamRemarkSerializerHelper
&&) = delete;
84 BitstreamRemarkSerializerHelper
&
85 operator=(BitstreamRemarkSerializerHelper
&&) = delete;
87 /// Set up the necessary block info entries according to the container type.
88 void setupBlockInfo();
90 /// Set up the block info for the metadata block.
91 void setupMetaBlockInfo();
92 /// The remark version in the metadata block.
93 void setupMetaRemarkVersion();
94 void emitMetaRemarkVersion(uint64_t RemarkVersion
);
95 /// The strtab in the metadata block.
96 void setupMetaStrTab();
97 void emitMetaStrTab(const StringTable
&StrTab
);
98 /// The external file in the metadata block.
99 void setupMetaExternalFile();
100 void emitMetaExternalFile(StringRef Filename
);
102 /// The block info for the remarks block.
103 void setupRemarkBlockInfo();
105 /// Emit the metadata for the remarks.
106 void emitMetaBlock(uint64_t ContainerVersion
,
107 Optional
<uint64_t> RemarkVersion
,
108 Optional
<const StringTable
*> StrTab
= None
,
109 Optional
<StringRef
> Filename
= None
);
111 /// Emit a remark block. The string table is required.
112 void emitRemarkBlock(const Remark
&Remark
, StringTable
&StrTab
);
113 /// Finalize the writing to \p OS.
114 void flushToStream(raw_ostream
&OS
);
115 /// Finalize the writing to a buffer.
116 /// The contents of the buffer remain valid for the lifetime of the object.
117 /// Any call to any other function in this class will invalidate the buffer.
118 StringRef
getBuffer();
121 /// Implementation of the remark serializer using LLVM bitstream.
122 struct BitstreamRemarkSerializer
: public RemarkSerializer
{
123 /// The file should contain:
124 /// 1) The block info block that describes how to read the blocks.
125 /// 2) The metadata block that contains various information about the remarks
127 /// 3) A number of remark blocks.
129 /// We need to set up 1) and 2) first, so that we can emit 3) after. This flag
130 /// is used to emit the first two blocks only once.
131 bool DidSetUp
= false;
132 /// The helper to emit bitstream.
133 BitstreamRemarkSerializerHelper Helper
;
135 /// Construct a serializer that will create its own string table.
136 BitstreamRemarkSerializer(raw_ostream
&OS
, SerializerMode Mode
);
137 /// Construct a serializer with a pre-filled string table.
138 BitstreamRemarkSerializer(raw_ostream
&OS
, SerializerMode Mode
,
141 /// Emit a remark to the stream. This also emits the metadata associated to
142 /// the remarks based on the SerializerMode specified at construction.
143 /// This writes the serialized output to the provided stream.
144 void emit(const Remark
&Remark
) override
;
145 /// The metadata serializer associated to this remark serializer. Based on the
146 /// container type of the current serializer, the container type of the
147 /// metadata serializer will change.
148 std::unique_ptr
<MetaSerializer
>
149 metaSerializer(raw_ostream
&OS
,
150 Optional
<StringRef
> ExternalFilename
= None
) override
;
153 /// Serializer of metadata for bitstream remarks.
154 struct BitstreamMetaSerializer
: public MetaSerializer
{
155 /// This class can be used with [1] a pre-constructed
156 /// BitstreamRemarkSerializerHelper, or with [2] one that is owned by the meta
157 /// serializer. In case of [1], we need to be able to store a reference to the
158 /// object, while in case of [2] we need to store the whole object.
159 Optional
<BitstreamRemarkSerializerHelper
> TmpHelper
;
160 /// The actual helper, that can point to \p TmpHelper or to an external helper
162 BitstreamRemarkSerializerHelper
*Helper
= nullptr;
164 Optional
<const StringTable
*> StrTab
;
165 Optional
<StringRef
> ExternalFilename
;
167 /// Create a new meta serializer based on \p ContainerType.
168 BitstreamMetaSerializer(raw_ostream
&OS
,
169 BitstreamRemarkContainerType ContainerType
,
170 Optional
<const StringTable
*> StrTab
= None
,
171 Optional
<StringRef
> ExternalFilename
= None
)
172 : MetaSerializer(OS
), TmpHelper(None
), Helper(nullptr), StrTab(StrTab
),
173 ExternalFilename(ExternalFilename
) {
174 TmpHelper
.emplace(ContainerType
);
175 Helper
= &*TmpHelper
;
178 /// Create a new meta serializer based on a previously built \p Helper.
179 BitstreamMetaSerializer(raw_ostream
&OS
,
180 BitstreamRemarkSerializerHelper
&Helper
,
181 Optional
<const StringTable
*> StrTab
= None
,
182 Optional
<StringRef
> ExternalFilename
= None
)
183 : MetaSerializer(OS
), TmpHelper(None
), Helper(&Helper
), StrTab(StrTab
),
184 ExternalFilename(ExternalFilename
) {}
186 void emit() override
;
189 } // end namespace remarks
190 } // end namespace llvm
192 #endif /* LLVM_REMARKS_BITSTREAM_REMARK_SERIALIZER_H */