1 //===- unittest/Support/BitstreamRemarksSerializerTest.cpp ----------------===//
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 #include "llvm/Bitcode/BitcodeAnalyzer.h"
10 #include "llvm/Remarks/BitstreamRemarkSerializer.h"
11 #include "llvm/Remarks/Remark.h"
12 #include "llvm/Support/raw_ostream.h"
13 #include "gtest/gtest.h"
17 // We need to supprt Windows paths as well. In order to have paths with the same
18 // length, use a different path according to the platform.
20 #define EXTERNALFILETESTPATH "C:/externalfi"
22 #define EXTERNALFILETESTPATH "/externalfile"
27 static void checkAnalyze(StringRef Input
, StringRef Expected
) {
28 std::string OutputBuf
;
29 raw_string_ostream
OutputOS(OutputBuf
);
30 BCDumpOptions
O(OutputOS
);
31 O
.ShowBinaryBlobs
= true;
32 BitcodeAnalyzer
BA(Input
);
33 EXPECT_FALSE(BA
.analyze(O
)); // Expect no errors.
34 EXPECT_EQ(OutputOS
.str(), Expected
);
37 static void check(remarks::SerializerMode Mode
, const remarks::Remark
&R
,
38 StringRef ExpectedR
, std::optional
<StringRef
> ExpectedMeta
,
39 std::optional
<remarks::StringTable
> StrTab
) {
42 raw_string_ostream
InputOS(InputBuf
);
43 Expected
<std::unique_ptr
<remarks::RemarkSerializer
>> MaybeSerializer
= [&] {
45 return createRemarkSerializer(remarks::Format::Bitstream
, Mode
, InputOS
,
48 return createRemarkSerializer(remarks::Format::Bitstream
, Mode
, InputOS
);
50 EXPECT_FALSE(errorToBool(MaybeSerializer
.takeError()));
51 std::unique_ptr
<remarks::RemarkSerializer
> Serializer
=
52 std::move(*MaybeSerializer
);
55 // Analyze the serialized remark.
56 checkAnalyze(InputOS
.str(), ExpectedR
);
58 // Analyze the serialized metadata if it's not in standalone mode.
61 raw_string_ostream
MetaOS(MetaBuf
);
62 std::unique_ptr
<remarks::MetaSerializer
> MetaSerializer
=
63 Serializer
->metaSerializer(MetaOS
, StringRef(EXTERNALFILETESTPATH
));
64 MetaSerializer
->emit();
65 checkAnalyze(MetaOS
.str(), *ExpectedMeta
);
69 static void check(const remarks::Remark
&R
, StringRef ExpectedR
,
70 StringRef ExpectedMeta
,
71 std::optional
<remarks::StringTable
> StrTab
= std::nullopt
) {
72 return check(remarks::SerializerMode::Separate
, R
, ExpectedR
, ExpectedMeta
,
77 checkStandalone(const remarks::Remark
&R
, StringRef ExpectedR
,
78 std::optional
<remarks::StringTable
> StrTab
= std::nullopt
) {
79 return check(remarks::SerializerMode::Standalone
, R
, ExpectedR
,
80 /*ExpectedMeta=*/std::nullopt
, std::move(StrTab
));
83 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileNoOptionals
) {
85 R
.RemarkType
= remarks::Type::Missed
;
87 R
.RemarkName
= "remark";
88 R
.FunctionName
= "function";
90 "<BLOCKINFO_BLOCK/>\n"
91 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
92 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
93 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
95 "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"
96 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
98 "<BLOCKINFO_BLOCK/>\n"
99 "<Meta BlockID=8 NumWords=14 BlockCodeSize=3>\n"
100 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
101 " <String table codeid=3 abbrevid=5/> blob data = "
102 "'remark\\x00pass\\x00function\\x00'\n"
103 " <External File codeid=4 abbrevid=6/> blob data = "
104 "'" EXTERNALFILETESTPATH
"'\n"
108 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileNoOptionalsSeparateStrTab
) {
109 remarks::StringTable StrTab
;
110 StrTab
.add("function");
112 StrTab
.add("remark");
114 R
.RemarkType
= remarks::Type::Missed
;
116 R
.RemarkName
= "remark";
117 R
.FunctionName
= "function";
119 "<BLOCKINFO_BLOCK/>\n"
120 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
121 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
122 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
124 "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"
125 " <Remark header codeid=5 abbrevid=4 op0=2 op1=2 op2=1 op3=0/>\n"
127 "<BLOCKINFO_BLOCK/>\n"
128 "<Meta BlockID=8 NumWords=14 BlockCodeSize=3>\n"
129 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
130 " <String table codeid=3 abbrevid=5/> blob data = "
131 "'function\\x00pass\\x00remark\\x00'\n"
132 " <External File codeid=4 abbrevid=6/> blob data = "
133 "'" EXTERNALFILETESTPATH
"'\n"
138 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileDebugLoc
) {
140 R
.RemarkType
= remarks::Type::Missed
;
142 R
.RemarkName
= "remark";
143 R
.FunctionName
= "function";
145 R
.Loc
->SourceFilePath
= "path";
146 R
.Loc
->SourceLine
= 99;
147 R
.Loc
->SourceColumn
= 55;
149 "<BLOCKINFO_BLOCK/>\n"
150 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
151 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
152 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
154 "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"
155 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
156 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"
158 "<BLOCKINFO_BLOCK/>\n"
159 "<Meta BlockID=8 NumWords=15 BlockCodeSize=3>\n"
160 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
161 " <String table codeid=3 abbrevid=5/> blob data = "
162 "'remark\\x00pass\\x00function\\x00path\\x00'\n"
163 " <External File codeid=4 abbrevid=6/> blob data = "
164 "'" EXTERNALFILETESTPATH
"'\n"
168 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileHotness
) {
170 R
.RemarkType
= remarks::Type::Missed
;
172 R
.RemarkName
= "remark";
173 R
.FunctionName
= "function";
174 R
.Hotness
.emplace(999999999);
176 "<BLOCKINFO_BLOCK/>\n"
177 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
178 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
179 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
181 "<Remark BlockID=9 NumWords=3 BlockCodeSize=4>\n"
182 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
183 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"
185 "<BLOCKINFO_BLOCK/>\n"
186 "<Meta BlockID=8 NumWords=14 BlockCodeSize=3>\n"
187 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
188 " <String table codeid=3 abbrevid=5/> blob data = "
189 "'remark\\x00pass\\x00function\\x00'\n"
190 " <External File codeid=4 abbrevid=6/> blob data = "
191 "'" EXTERNALFILETESTPATH
"'\n"
195 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileArgNoDebugLoc
) {
197 R
.RemarkType
= remarks::Type::Missed
;
199 R
.RemarkName
= "remark";
200 R
.FunctionName
= "function";
201 R
.Args
.emplace_back();
202 R
.Args
.back().Key
= "key";
203 R
.Args
.back().Val
= "value";
205 "<BLOCKINFO_BLOCK/>\n"
206 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
207 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
208 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
210 "<Remark BlockID=9 NumWords=2 BlockCodeSize=4>\n"
211 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
212 " <Argument codeid=9 abbrevid=8 op0=3 op1=4/>\n"
214 "<BLOCKINFO_BLOCK/>\n"
215 "<Meta BlockID=8 NumWords=16 BlockCodeSize=3>\n"
216 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
217 " <String table codeid=3 abbrevid=5/> blob data = "
218 "'remark\\x00pass\\x00function\\x00key\\x00value\\x00'\n"
219 " <External File codeid=4 abbrevid=6/> blob data = "
220 "'" EXTERNALFILETESTPATH
"'\n"
224 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileArgDebugLoc
) {
226 R
.RemarkType
= remarks::Type::Missed
;
228 R
.RemarkName
= "remark";
229 R
.FunctionName
= "function";
230 R
.Args
.emplace_back();
231 R
.Args
.back().Key
= "key";
232 R
.Args
.back().Val
= "value";
233 R
.Args
.back().Loc
.emplace();
234 R
.Args
.back().Loc
->SourceFilePath
= "path";
235 R
.Args
.back().Loc
->SourceLine
= 99;
236 R
.Args
.back().Loc
->SourceColumn
= 55;
238 "<BLOCKINFO_BLOCK/>\n"
239 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
240 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
241 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
243 "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"
244 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
245 " <Argument with debug location codeid=8 abbrevid=7 op0=3 op1=4 op2=5 "
248 "<BLOCKINFO_BLOCK/>\n"
249 "<Meta BlockID=8 NumWords=17 BlockCodeSize=3>\n"
250 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
251 " <String table codeid=3 abbrevid=5/> blob data = "
252 "'remark\\x00pass\\x00function\\x00key\\x00value\\x00path\\x00'\n"
253 " <External File codeid=4 abbrevid=6/> blob data = "
254 "'" EXTERNALFILETESTPATH
"'\n"
258 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileAll
) {
260 R
.RemarkType
= remarks::Type::Missed
;
262 R
.RemarkName
= "remark";
263 R
.FunctionName
= "function";
265 R
.Loc
->SourceFilePath
= "path";
266 R
.Loc
->SourceLine
= 99;
267 R
.Loc
->SourceColumn
= 55;
268 R
.Hotness
.emplace(999999999);
269 R
.Args
.emplace_back();
270 R
.Args
.back().Key
= "key";
271 R
.Args
.back().Val
= "value";
272 R
.Args
.back().Loc
.emplace();
273 R
.Args
.back().Loc
->SourceFilePath
= "argpath";
274 R
.Args
.back().Loc
->SourceLine
= 11;
275 R
.Args
.back().Loc
->SourceColumn
= 66;
277 "<BLOCKINFO_BLOCK/>\n"
278 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
279 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
280 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
282 "<Remark BlockID=9 NumWords=8 BlockCodeSize=4>\n"
283 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
284 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"
285 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"
286 " <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 "
289 "<BLOCKINFO_BLOCK/>\n"
290 "<Meta BlockID=8 NumWords=19 BlockCodeSize=3>\n"
291 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
292 " <String table codeid=3 abbrevid=5/> blob data = "
293 "'remark\\x00pass\\x00function\\x00path\\x00key\\x00value\\x00argpa"
294 "th\\x00'\n <External File codeid=4 abbrevid=6/> blob data = "
295 "'" EXTERNALFILETESTPATH
"'\n"
299 TEST(BitstreamRemarkSerializer
, Standalone
) {
300 // Pre-populate the string table.
301 remarks::StringTable StrTab
;
303 StrTab
.add("remark");
304 StrTab
.add("function");
308 StrTab
.add("argpath");
310 R
.RemarkType
= remarks::Type::Missed
;
312 R
.RemarkName
= "remark";
313 R
.FunctionName
= "function";
315 R
.Loc
->SourceFilePath
= "path";
316 R
.Loc
->SourceLine
= 99;
317 R
.Loc
->SourceColumn
= 55;
318 R
.Hotness
.emplace(999999999);
319 R
.Args
.emplace_back();
320 R
.Args
.back().Key
= "key";
321 R
.Args
.back().Val
= "value";
322 R
.Args
.back().Loc
.emplace();
323 R
.Args
.back().Loc
->SourceFilePath
= "argpath";
324 R
.Args
.back().Loc
->SourceLine
= 11;
325 R
.Args
.back().Loc
->SourceColumn
= 66;
328 "<BLOCKINFO_BLOCK/>\n"
329 "<Meta BlockID=8 NumWords=15 BlockCodeSize=3>\n"
330 " <Container info codeid=1 abbrevid=4 op0=0 op1=2/>\n"
331 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
332 " <String table codeid=3 abbrevid=6/> blob data = "
333 "'pass\\x00remark\\x00function\\x00path\\x00key\\x00value\\x00argpath\\x0"
336 "<Remark BlockID=9 NumWords=8 BlockCodeSize=4>\n"
337 " <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"
338 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"
339 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"
340 " <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 "