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/Support/raw_ostream.h"
12 #include "gtest/gtest.h"
15 // We need to supprt Windows paths as well. In order to have paths with the same
16 // length, use a different path according to the platform.
18 #define EXTERNALFILETESTPATH "C:/externalfi"
20 #define EXTERNALFILETESTPATH "/externalfile"
25 static void checkAnalyze(StringRef Input
, StringRef Expected
) {
26 std::string OutputBuf
;
27 raw_string_ostream
OutputOS(OutputBuf
);
28 BCDumpOptions
O(OutputOS
);
29 O
.ShowBinaryBlobs
= true;
30 BitcodeAnalyzer
BA(Input
);
31 EXPECT_FALSE(BA
.analyze(O
)); // Expect no errors.
32 EXPECT_EQ(OutputOS
.str(), Expected
);
35 static void check(remarks::SerializerMode Mode
, const remarks::Remark
&R
,
36 StringRef ExpectedR
, Optional
<StringRef
> ExpectedMeta
,
37 Optional
<remarks::StringTable
> StrTab
) {
40 raw_string_ostream
InputOS(InputBuf
);
41 Expected
<std::unique_ptr
<remarks::RemarkSerializer
>> MaybeSerializer
= [&] {
43 return createRemarkSerializer(remarks::Format::Bitstream
, Mode
, InputOS
,
46 return createRemarkSerializer(remarks::Format::Bitstream
, Mode
, InputOS
);
48 EXPECT_FALSE(errorToBool(MaybeSerializer
.takeError()));
49 std::unique_ptr
<remarks::RemarkSerializer
> Serializer
=
50 std::move(*MaybeSerializer
);
53 // Analyze the serialized remark.
54 checkAnalyze(InputOS
.str(), ExpectedR
);
56 // Analyze the serialized metadata if it's not in standalone mode.
59 raw_string_ostream
MetaOS(MetaBuf
);
60 std::unique_ptr
<remarks::MetaSerializer
> MetaSerializer
=
61 Serializer
->metaSerializer(MetaOS
, StringRef(EXTERNALFILETESTPATH
));
62 MetaSerializer
->emit();
63 checkAnalyze(MetaOS
.str(), *ExpectedMeta
);
67 static void check(const remarks::Remark
&R
, StringRef ExpectedR
,
68 StringRef ExpectedMeta
,
69 Optional
<remarks::StringTable
> StrTab
= None
) {
70 return check(remarks::SerializerMode::Separate
, R
, ExpectedR
, ExpectedMeta
,
74 static void checkStandalone(const remarks::Remark
&R
, StringRef ExpectedR
,
75 Optional
<remarks::StringTable
> StrTab
= None
) {
76 return check(remarks::SerializerMode::Standalone
, R
, ExpectedR
,
77 /*ExpectedMeta=*/None
, std::move(StrTab
));
80 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileNoOptionals
) {
82 R
.RemarkType
= remarks::Type::Missed
;
84 R
.RemarkName
= "remark";
85 R
.FunctionName
= "function";
87 "<BLOCKINFO_BLOCK/>\n"
88 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
89 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
90 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
92 "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"
93 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
95 "<BLOCKINFO_BLOCK/>\n"
96 "<Meta BlockID=8 NumWords=14 BlockCodeSize=3>\n"
97 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
98 " <String table codeid=3 abbrevid=5/> blob data = "
99 "'remark\\x00pass\\x00function\\x00'\n"
100 " <External File codeid=4 abbrevid=6/> blob data = "
101 "'" EXTERNALFILETESTPATH
"'\n"
105 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileNoOptionalsSeparateStrTab
) {
106 remarks::StringTable StrTab
;
107 StrTab
.add("function");
109 StrTab
.add("remark");
111 R
.RemarkType
= remarks::Type::Missed
;
113 R
.RemarkName
= "remark";
114 R
.FunctionName
= "function";
116 "<BLOCKINFO_BLOCK/>\n"
117 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
118 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
119 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
121 "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"
122 " <Remark header codeid=5 abbrevid=4 op0=2 op1=2 op2=1 op3=0/>\n"
124 "<BLOCKINFO_BLOCK/>\n"
125 "<Meta BlockID=8 NumWords=14 BlockCodeSize=3>\n"
126 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
127 " <String table codeid=3 abbrevid=5/> blob data = "
128 "'function\\x00pass\\x00remark\\x00'\n"
129 " <External File codeid=4 abbrevid=6/> blob data = "
130 "'" EXTERNALFILETESTPATH
"'\n"
135 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileDebugLoc
) {
137 R
.RemarkType
= remarks::Type::Missed
;
139 R
.RemarkName
= "remark";
140 R
.FunctionName
= "function";
142 R
.Loc
->SourceFilePath
= "path";
143 R
.Loc
->SourceLine
= 99;
144 R
.Loc
->SourceColumn
= 55;
146 "<BLOCKINFO_BLOCK/>\n"
147 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
148 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
149 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
151 "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"
152 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
153 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"
155 "<BLOCKINFO_BLOCK/>\n"
156 "<Meta BlockID=8 NumWords=15 BlockCodeSize=3>\n"
157 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
158 " <String table codeid=3 abbrevid=5/> blob data = "
159 "'remark\\x00pass\\x00function\\x00path\\x00'\n"
160 " <External File codeid=4 abbrevid=6/> blob data = "
161 "'" EXTERNALFILETESTPATH
"'\n"
165 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileHotness
) {
167 R
.RemarkType
= remarks::Type::Missed
;
169 R
.RemarkName
= "remark";
170 R
.FunctionName
= "function";
171 R
.Hotness
.emplace(999999999);
173 "<BLOCKINFO_BLOCK/>\n"
174 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
175 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
176 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
178 "<Remark BlockID=9 NumWords=3 BlockCodeSize=4>\n"
179 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
180 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"
182 "<BLOCKINFO_BLOCK/>\n"
183 "<Meta BlockID=8 NumWords=14 BlockCodeSize=3>\n"
184 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
185 " <String table codeid=3 abbrevid=5/> blob data = "
186 "'remark\\x00pass\\x00function\\x00'\n"
187 " <External File codeid=4 abbrevid=6/> blob data = "
188 "'" EXTERNALFILETESTPATH
"'\n"
192 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileArgNoDebugLoc
) {
194 R
.RemarkType
= remarks::Type::Missed
;
196 R
.RemarkName
= "remark";
197 R
.FunctionName
= "function";
198 R
.Args
.emplace_back();
199 R
.Args
.back().Key
= "key";
200 R
.Args
.back().Val
= "value";
202 "<BLOCKINFO_BLOCK/>\n"
203 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
204 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
205 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
207 "<Remark BlockID=9 NumWords=2 BlockCodeSize=4>\n"
208 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
209 " <Argument codeid=9 abbrevid=8 op0=3 op1=4/>\n"
211 "<BLOCKINFO_BLOCK/>\n"
212 "<Meta BlockID=8 NumWords=16 BlockCodeSize=3>\n"
213 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
214 " <String table codeid=3 abbrevid=5/> blob data = "
215 "'remark\\x00pass\\x00function\\x00key\\x00value\\x00'\n"
216 " <External File codeid=4 abbrevid=6/> blob data = "
217 "'" EXTERNALFILETESTPATH
"'\n"
221 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileArgDebugLoc
) {
223 R
.RemarkType
= remarks::Type::Missed
;
225 R
.RemarkName
= "remark";
226 R
.FunctionName
= "function";
227 R
.Args
.emplace_back();
228 R
.Args
.back().Key
= "key";
229 R
.Args
.back().Val
= "value";
230 R
.Args
.back().Loc
.emplace();
231 R
.Args
.back().Loc
->SourceFilePath
= "path";
232 R
.Args
.back().Loc
->SourceLine
= 99;
233 R
.Args
.back().Loc
->SourceColumn
= 55;
235 "<BLOCKINFO_BLOCK/>\n"
236 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
237 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
238 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
240 "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"
241 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
242 " <Argument with debug location codeid=8 abbrevid=7 op0=3 op1=4 op2=5 "
245 "<BLOCKINFO_BLOCK/>\n"
246 "<Meta BlockID=8 NumWords=17 BlockCodeSize=3>\n"
247 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
248 " <String table codeid=3 abbrevid=5/> blob data = "
249 "'remark\\x00pass\\x00function\\x00key\\x00value\\x00path\\x00'\n"
250 " <External File codeid=4 abbrevid=6/> blob data = "
251 "'" EXTERNALFILETESTPATH
"'\n"
255 TEST(BitstreamRemarkSerializer
, SeparateRemarkFileAll
) {
257 R
.RemarkType
= remarks::Type::Missed
;
259 R
.RemarkName
= "remark";
260 R
.FunctionName
= "function";
262 R
.Loc
->SourceFilePath
= "path";
263 R
.Loc
->SourceLine
= 99;
264 R
.Loc
->SourceColumn
= 55;
265 R
.Hotness
.emplace(999999999);
266 R
.Args
.emplace_back();
267 R
.Args
.back().Key
= "key";
268 R
.Args
.back().Val
= "value";
269 R
.Args
.back().Loc
.emplace();
270 R
.Args
.back().Loc
->SourceFilePath
= "argpath";
271 R
.Args
.back().Loc
->SourceLine
= 11;
272 R
.Args
.back().Loc
->SourceColumn
= 66;
274 "<BLOCKINFO_BLOCK/>\n"
275 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"
276 " <Container info codeid=1 abbrevid=4 op0=0 op1=1/>\n"
277 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
279 "<Remark BlockID=9 NumWords=8 BlockCodeSize=4>\n"
280 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"
281 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"
282 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"
283 " <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 "
286 "<BLOCKINFO_BLOCK/>\n"
287 "<Meta BlockID=8 NumWords=19 BlockCodeSize=3>\n"
288 " <Container info codeid=1 abbrevid=4 op0=0 op1=0/>\n"
289 " <String table codeid=3 abbrevid=5/> blob data = "
290 "'remark\\x00pass\\x00function\\x00path\\x00key\\x00value\\x00argpa"
291 "th\\x00'\n <External File codeid=4 abbrevid=6/> blob data = "
292 "'" EXTERNALFILETESTPATH
"'\n"
296 TEST(BitstreamRemarkSerializer
, Standalone
) {
297 // Pre-populate the string table.
298 remarks::StringTable StrTab
;
300 StrTab
.add("remark");
301 StrTab
.add("function");
305 StrTab
.add("argpath");
307 R
.RemarkType
= remarks::Type::Missed
;
309 R
.RemarkName
= "remark";
310 R
.FunctionName
= "function";
312 R
.Loc
->SourceFilePath
= "path";
313 R
.Loc
->SourceLine
= 99;
314 R
.Loc
->SourceColumn
= 55;
315 R
.Hotness
.emplace(999999999);
316 R
.Args
.emplace_back();
317 R
.Args
.back().Key
= "key";
318 R
.Args
.back().Val
= "value";
319 R
.Args
.back().Loc
.emplace();
320 R
.Args
.back().Loc
->SourceFilePath
= "argpath";
321 R
.Args
.back().Loc
->SourceLine
= 11;
322 R
.Args
.back().Loc
->SourceColumn
= 66;
325 "<BLOCKINFO_BLOCK/>\n"
326 "<Meta BlockID=8 NumWords=15 BlockCodeSize=3>\n"
327 " <Container info codeid=1 abbrevid=4 op0=0 op1=2/>\n"
328 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"
329 " <String table codeid=3 abbrevid=6/> blob data = "
330 "'pass\\x00remark\\x00function\\x00path\\x00key\\x00value\\x00argpath\\x0"
333 "<Remark BlockID=9 NumWords=8 BlockCodeSize=4>\n"
334 " <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"
335 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"
336 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"
337 " <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 "