1 | //===-- BitstreamRemarkSerializer.h - Bitstream serializer ------*- 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 an implementation of the serializer using the LLVM |
10 | // Bitstream format. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H |
15 | #define |
16 | |
17 | #include "llvm/Bitstream/BitstreamWriter.h" |
18 | #include "llvm/Remarks/BitstreamRemarkContainer.h" |
19 | #include "llvm/Remarks/RemarkSerializer.h" |
20 | #include <optional> |
21 | |
22 | namespace llvm { |
23 | namespace remarks { |
24 | |
25 | struct ; |
26 | |
27 | /// Serialize the remarks to LLVM bitstream. |
28 | /// This class provides ways to emit remarks in the LLVM bitstream format and |
29 | /// its associated metadata. |
30 | /// |
31 | /// * The separate model: |
32 | /// Separate meta: | Container info |
33 | /// | String table |
34 | /// | External file |
35 | /// |
36 | /// Separate remarks: | Container info |
37 | /// | Remark version |
38 | /// | Remark0 |
39 | /// | Remark1 |
40 | /// | Remark2 |
41 | /// | ... |
42 | /// |
43 | /// * The standalone model: | Container info |
44 | /// | String table |
45 | /// | Remark version |
46 | /// | Remark0 |
47 | /// | Remark1 |
48 | /// | Remark2 |
49 | /// | ... |
50 | /// |
51 | struct { |
52 | /// Buffer used for encoding the bitstream before writing it to the final |
53 | /// stream. |
54 | SmallVector<char, 1024> ; |
55 | /// Buffer used to construct records and pass to the bitstream writer. |
56 | SmallVector<uint64_t, 64> ; |
57 | /// The Bitstream writer. |
58 | BitstreamWriter ; |
59 | /// The type of the container we are serializing. |
60 | BitstreamRemarkContainerType ; |
61 | |
62 | /// Abbrev IDs initialized in the block info block. |
63 | /// Note: depending on the container type, some IDs might be uninitialized. |
64 | /// Warning: When adding more abbrev IDs, make sure to update the |
65 | /// BlockCodeSize (in the call to EnterSubblock). |
66 | uint64_t = 0; |
67 | uint64_t = 0; |
68 | uint64_t = 0; |
69 | uint64_t = 0; |
70 | uint64_t = 0; |
71 | uint64_t = 0; |
72 | uint64_t = 0; |
73 | uint64_t = 0; |
74 | uint64_t = 0; |
75 | |
76 | (BitstreamRemarkContainerType ContainerType); |
77 | |
78 | // Disable copy and move: Bitstream points to Encoded, which needs special |
79 | // handling during copy/move, but moving the vectors is probably useless |
80 | // anyway. |
81 | (const BitstreamRemarkSerializerHelper &) = |
82 | delete; |
83 | BitstreamRemarkSerializerHelper & |
84 | (const BitstreamRemarkSerializerHelper &) = delete; |
85 | (BitstreamRemarkSerializerHelper &&) = delete; |
86 | BitstreamRemarkSerializerHelper & |
87 | (BitstreamRemarkSerializerHelper &&) = delete; |
88 | |
89 | /// Set up the necessary block info entries according to the container type. |
90 | void (); |
91 | |
92 | /// Set up the block info for the metadata block. |
93 | void (); |
94 | /// The remark version in the metadata block. |
95 | void (); |
96 | void (uint64_t ); |
97 | /// The strtab in the metadata block. |
98 | void (); |
99 | void (const StringTable &StrTab); |
100 | /// The external file in the metadata block. |
101 | void (); |
102 | void (StringRef Filename); |
103 | |
104 | /// The block info for the remarks block. |
105 | void (); |
106 | |
107 | /// Emit the metadata for the remarks. |
108 | void (uint64_t ContainerVersion, |
109 | std::optional<uint64_t> , |
110 | std::optional<const StringTable *> StrTab = std::nullopt, |
111 | std::optional<StringRef> Filename = std::nullopt); |
112 | |
113 | /// Emit a remark block. The string table is required. |
114 | void (const Remark &, StringTable &StrTab); |
115 | /// Finalize the writing to \p OS. |
116 | void (raw_ostream &OS); |
117 | /// Finalize the writing to a buffer. |
118 | /// The contents of the buffer remain valid for the lifetime of the object. |
119 | /// Any call to any other function in this class will invalidate the buffer. |
120 | StringRef (); |
121 | }; |
122 | |
123 | /// Implementation of the remark serializer using LLVM bitstream. |
124 | struct : public RemarkSerializer { |
125 | /// The file should contain: |
126 | /// 1) The block info block that describes how to read the blocks. |
127 | /// 2) The metadata block that contains various information about the remarks |
128 | /// in the file. |
129 | /// 3) A number of remark blocks. |
130 | |
131 | /// We need to set up 1) and 2) first, so that we can emit 3) after. This flag |
132 | /// is used to emit the first two blocks only once. |
133 | bool = false; |
134 | /// The helper to emit bitstream. |
135 | BitstreamRemarkSerializerHelper ; |
136 | |
137 | /// Construct a serializer that will create its own string table. |
138 | (raw_ostream &OS, SerializerMode Mode); |
139 | /// Construct a serializer with a pre-filled string table. |
140 | (raw_ostream &OS, SerializerMode Mode, |
141 | StringTable StrTab); |
142 | |
143 | /// Emit a remark to the stream. This also emits the metadata associated to |
144 | /// the remarks based on the SerializerMode specified at construction. |
145 | /// This writes the serialized output to the provided stream. |
146 | void (const Remark &) override; |
147 | /// The metadata serializer associated to this remark serializer. Based on the |
148 | /// container type of the current serializer, the container type of the |
149 | /// metadata serializer will change. |
150 | std::unique_ptr<MetaSerializer> ( |
151 | raw_ostream &OS, |
152 | std::optional<StringRef> ExternalFilename = std::nullopt) override; |
153 | |
154 | static bool (const RemarkSerializer *S) { |
155 | return S->SerializerFormat == Format::Bitstream; |
156 | } |
157 | }; |
158 | |
159 | /// Serializer of metadata for bitstream remarks. |
160 | struct : public MetaSerializer { |
161 | /// This class can be used with [1] a pre-constructed |
162 | /// BitstreamRemarkSerializerHelper, or with [2] one that is owned by the meta |
163 | /// serializer. In case of [1], we need to be able to store a reference to the |
164 | /// object, while in case of [2] we need to store the whole object. |
165 | std::optional<BitstreamRemarkSerializerHelper> ; |
166 | /// The actual helper, that can point to \p TmpHelper or to an external helper |
167 | /// object. |
168 | BitstreamRemarkSerializerHelper * = nullptr; |
169 | |
170 | std::optional<const StringTable *> ; |
171 | std::optional<StringRef> ; |
172 | |
173 | /// Create a new meta serializer based on \p ContainerType. |
174 | ( |
175 | raw_ostream &OS, BitstreamRemarkContainerType ContainerType, |
176 | std::optional<const StringTable *> StrTab = std::nullopt, |
177 | std::optional<StringRef> ExternalFilename = std::nullopt) |
178 | : MetaSerializer(OS), TmpHelper(std::nullopt), Helper(nullptr), |
179 | StrTab(StrTab), ExternalFilename(ExternalFilename) { |
180 | TmpHelper.emplace(args&: ContainerType); |
181 | Helper = &*TmpHelper; |
182 | } |
183 | |
184 | /// Create a new meta serializer based on a previously built \p Helper. |
185 | ( |
186 | raw_ostream &OS, BitstreamRemarkSerializerHelper &Helper, |
187 | std::optional<const StringTable *> StrTab = std::nullopt, |
188 | std::optional<StringRef> ExternalFilename = std::nullopt) |
189 | : MetaSerializer(OS), TmpHelper(std::nullopt), Helper(&Helper), |
190 | StrTab(StrTab), ExternalFilename(ExternalFilename) {} |
191 | |
192 | void () override; |
193 | }; |
194 | |
195 | } // end namespace remarks |
196 | } // end namespace llvm |
197 | |
198 | #endif // LLVM_REMARKS_BITSTREAMREMARKSERIALIZER_H |
199 | |