Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / unittests / OptRemarks / OptRemarksParsingTest.cpp
blobbaadffefddea277ec68c10a5910b9e2913611367
1 //===- unittest/Support/OptRemarksParsingTest.cpp - OptTable tests --------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm-c/OptRemarks.h"
10 #include "gtest/gtest.h"
12 using namespace llvm;
14 template <size_t N> bool tryParse(const char (&Buf)[N]) {
15 LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
16 LLVMOptRemarkEntry *Remark = nullptr;
17 while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
18 EXPECT_TRUE(Remark == nullptr); // Only one remark per test.
19 Remark = NewRemark;
21 EXPECT_TRUE(Remark != nullptr); // We need *exactly* one remark per test.
22 bool HasError = LLVMOptRemarkParserHasError(Parser);
23 LLVMOptRemarkParserDispose(Parser);
24 return !HasError;
27 template <size_t N>
28 bool parseExpectError(const char (&Buf)[N], const char *Error) {
29 LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
30 LLVMOptRemarkEntry *Remark = nullptr;
31 while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
32 EXPECT_FALSE(NewRemark);
34 EXPECT_TRUE(Remark == nullptr); // We are parsing only one malformed remark.
35 EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
36 bool MatchesError =
37 StringRef(LLVMOptRemarkParserGetErrorMessage(Parser)).contains(Error);
38 LLVMOptRemarkParserDispose(Parser);
40 return MatchesError;
43 TEST(OptRemarks, OptRemarksParsingEmpty) {
44 StringRef Buf = "\n"
45 "\n";
46 LLVMOptRemarkParserRef Parser =
47 LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
48 LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser);
49 EXPECT_TRUE(NewRemark == nullptr); // No remark expected.
50 EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
51 EXPECT_TRUE(StringRef(LLVMOptRemarkParserGetErrorMessage(Parser))
52 .contains("document root is not of mapping type."));
53 LLVMOptRemarkParserDispose(Parser);
56 TEST(OptRemarks, OptRemarksParsingGood) {
57 EXPECT_TRUE(tryParse("\n"
58 "--- !Missed\n"
59 "Pass: inline\n"
60 "Name: NoDefinition\n"
61 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
62 "Function: foo\n"
63 "Args:\n"
64 " - Callee: bar\n"
65 " - String: ' will not be inlined into '\n"
66 " - Caller: foo\n"
67 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
68 " - String: ' because its definition is unavailable'\n"
69 ""));
71 // No debug loc should also pass.
72 EXPECT_TRUE(tryParse("\n"
73 "--- !Missed\n"
74 "Pass: inline\n"
75 "Name: NoDefinition\n"
76 "Function: foo\n"
77 "Args:\n"
78 " - Callee: bar\n"
79 " - String: ' will not be inlined into '\n"
80 " - Caller: foo\n"
81 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
82 " - String: ' because its definition is unavailable'\n"
83 ""));
85 // No args is also ok.
86 EXPECT_TRUE(tryParse("\n"
87 "--- !Missed\n"
88 "Pass: inline\n"
89 "Name: NoDefinition\n"
90 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
91 "Function: foo\n"
92 ""));
94 // Different order.
95 EXPECT_TRUE(tryParse("\n"
96 "--- !Missed\n"
97 "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
98 "Function: foo\n"
99 "Name: NoDefinition\n"
100 "Args:\n"
101 " - Callee: bar\n"
102 " - String: ' will not be inlined into '\n"
103 " - Caller: foo\n"
104 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
105 " - String: ' because its definition is unavailable'\n"
106 "Pass: inline\n"
107 ""));
110 // Mandatory common part of a remark.
111 #define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
112 // Test all the types.
113 TEST(OptRemarks, OptRemarksParsingTypes) {
114 // Type: Passed
115 EXPECT_TRUE(tryParse("--- !Passed" COMMON_REMARK));
116 // Type: Missed
117 EXPECT_TRUE(tryParse("--- !Missed" COMMON_REMARK));
118 // Type: Analysis
119 EXPECT_TRUE(tryParse("--- !Analysis" COMMON_REMARK));
120 // Type: AnalysisFPCompute
121 EXPECT_TRUE(tryParse("--- !AnalysisFPCompute" COMMON_REMARK));
122 // Type: AnalysisAliasing
123 EXPECT_TRUE(tryParse("--- !AnalysisAliasing" COMMON_REMARK));
124 // Type: Failure
125 EXPECT_TRUE(tryParse("--- !Failure" COMMON_REMARK));
127 #undef COMMON_REMARK
129 TEST(OptRemarks, OptRemarksParsingMissingFields) {
130 // No type.
131 EXPECT_TRUE(parseExpectError("\n"
132 "---\n"
133 "Pass: inline\n"
134 "Name: NoDefinition\n"
135 "Function: foo\n"
137 "error: Type, Pass, Name or Function missing."));
138 // No pass.
139 EXPECT_TRUE(parseExpectError("\n"
140 "--- !Missed\n"
141 "Name: NoDefinition\n"
142 "Function: foo\n"
144 "error: Type, Pass, Name or Function missing."));
145 // No name.
146 EXPECT_TRUE(parseExpectError("\n"
147 "--- !Missed\n"
148 "Pass: inline\n"
149 "Function: foo\n"
151 "error: Type, Pass, Name or Function missing."));
152 // No function.
153 EXPECT_TRUE(parseExpectError("\n"
154 "--- !Missed\n"
155 "Pass: inline\n"
156 "Name: NoDefinition\n"
158 "error: Type, Pass, Name or Function missing."));
159 // Debug loc but no file.
160 EXPECT_TRUE(parseExpectError("\n"
161 "--- !Missed\n"
162 "Pass: inline\n"
163 "Name: NoDefinition\n"
164 "Function: foo\n"
165 "DebugLoc: { Line: 3, Column: 12 }\n"
167 "DebugLoc node incomplete."));
168 // Debug loc but no line.
169 EXPECT_TRUE(parseExpectError("\n"
170 "--- !Missed\n"
171 "Pass: inline\n"
172 "Name: NoDefinition\n"
173 "Function: foo\n"
174 "DebugLoc: { File: file.c, Column: 12 }\n"
176 "DebugLoc node incomplete."));
177 // Debug loc but no column.
178 EXPECT_TRUE(parseExpectError("\n"
179 "--- !Missed\n"
180 "Pass: inline\n"
181 "Name: NoDefinition\n"
182 "Function: foo\n"
183 "DebugLoc: { File: file.c, Line: 3 }\n"
185 "DebugLoc node incomplete."));
188 TEST(OptRemarks, OptRemarksParsingWrongTypes) {
189 // Wrong debug loc type.
190 EXPECT_TRUE(parseExpectError("\n"
191 "--- !Missed\n"
192 "Pass: inline\n"
193 "Name: NoDefinition\n"
194 "Function: foo\n"
195 "DebugLoc: foo\n"
197 "expected a value of mapping type."));
198 // Wrong line type.
199 EXPECT_TRUE(parseExpectError("\n"
200 "--- !Missed\n"
201 "Pass: inline\n"
202 "Name: NoDefinition\n"
203 "Function: foo\n"
204 "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
206 "expected a value of integer type."));
207 // Wrong column type.
208 EXPECT_TRUE(parseExpectError("\n"
209 "--- !Missed\n"
210 "Pass: inline\n"
211 "Name: NoDefinition\n"
212 "Function: foo\n"
213 "DebugLoc: { File: file.c, Line: 3, Column: c }\n"
215 "expected a value of integer type."));
216 // Wrong args type.
217 EXPECT_TRUE(parseExpectError("\n"
218 "--- !Missed\n"
219 "Pass: inline\n"
220 "Name: NoDefinition\n"
221 "Function: foo\n"
222 "Args: foo\n"
224 "wrong value type for key."));
225 // Wrong key type.
226 EXPECT_TRUE(parseExpectError("\n"
227 "--- !Missed\n"
228 "{ A: a }: inline\n"
229 "Name: NoDefinition\n"
230 "Function: foo\n"
232 "key is not a string."));
233 // Debug loc with unknown entry.
234 EXPECT_TRUE(parseExpectError("\n"
235 "--- !Missed\n"
236 "Pass: inline\n"
237 "Name: NoDefinition\n"
238 "Function: foo\n"
239 "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
241 "unknown entry in DebugLoc map."));
242 // Unknown entry.
243 EXPECT_TRUE(parseExpectError("\n"
244 "--- !Missed\n"
245 "Unknown: inline\n"
247 "unknown key."));
248 // Not a scalar.
249 EXPECT_TRUE(parseExpectError("\n"
250 "--- !Missed\n"
251 "Pass: { File: a, Line: 1, Column: 2 }\n"
252 "Name: NoDefinition\n"
253 "Function: foo\n"
255 "expected a value of scalar type."));
256 // Not a string file in debug loc.
257 EXPECT_TRUE(parseExpectError("\n"
258 "--- !Missed\n"
259 "Pass: inline\n"
260 "Name: NoDefinition\n"
261 "Function: foo\n"
262 "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
264 "expected a value of scalar type."));
265 // Not a integer column in debug loc.
266 EXPECT_TRUE(parseExpectError("\n"
267 "--- !Missed\n"
268 "Pass: inline\n"
269 "Name: NoDefinition\n"
270 "Function: foo\n"
271 "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
273 "expected a value of scalar type."));
274 // Not a integer line in debug loc.
275 EXPECT_TRUE(parseExpectError("\n"
276 "--- !Missed\n"
277 "Pass: inline\n"
278 "Name: NoDefinition\n"
279 "Function: foo\n"
280 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
282 "expected a value of scalar type."));
283 // Not a mapping type value for args.
284 EXPECT_TRUE(parseExpectError("\n"
285 "--- !Missed\n"
286 "Pass: inline\n"
287 "Name: NoDefinition\n"
288 "Function: foo\n"
289 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
291 "expected a value of scalar type."));
294 TEST(OptRemarks, OptRemarksParsingWrongArgs) {
295 // Multiple debug locs per arg.
296 EXPECT_TRUE(
297 parseExpectError("\n"
298 "--- !Missed\n"
299 "Pass: inline\n"
300 "Name: NoDefinition\n"
301 "Function: foo\n"
302 "Args:\n"
303 " - Str: string\n"
304 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
305 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
307 "only one DebugLoc entry is allowed per argument."));
308 // Multiple strings per arg.
309 EXPECT_TRUE(
310 parseExpectError("\n"
311 "--- !Missed\n"
312 "Pass: inline\n"
313 "Name: NoDefinition\n"
314 "Function: foo\n"
315 "Args:\n"
316 " - Str: string\n"
317 " Str2: string\n"
318 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
320 "only one string entry is allowed per argument."));
321 // No arg value.
322 EXPECT_TRUE(parseExpectError("\n"
323 "--- !Missed\n"
324 "Pass: inline\n"
325 "Name: NoDefinition\n"
326 "Function: foo\n"
327 "Args:\n"
328 " - Callee: ''\n"
329 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
331 "argument value is missing."));
332 // No arg value.
333 EXPECT_TRUE(parseExpectError("\n"
334 "--- !Missed\n"
335 "Pass: inline\n"
336 "Name: NoDefinition\n"
337 "Function: foo\n"
338 "Args:\n"
339 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
341 "argument key is missing."));
345 TEST(OptRemarks, OptRemarksGoodStruct) {
346 StringRef Buf = "\n"
347 "--- !Missed\n"
348 "Pass: inline\n"
349 "Name: NoDefinition\n"
350 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
351 "Function: foo\n"
352 "Args:\n"
353 " - Callee: bar\n"
354 " - String: ' will not be inlined into '\n"
355 " - Caller: foo\n"
356 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
357 " - String: ' because its definition is unavailable'\n"
358 "\n";
360 LLVMOptRemarkParserRef Parser =
361 LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
362 LLVMOptRemarkEntry *Remark = LLVMOptRemarkParserGetNext(Parser);
363 EXPECT_FALSE(Remark == nullptr);
364 EXPECT_EQ(StringRef(Remark->RemarkType.Str, 7), "!Missed");
365 EXPECT_EQ(Remark->RemarkType.Len, 7U);
366 EXPECT_EQ(StringRef(Remark->PassName.Str, 6), "inline");
367 EXPECT_EQ(Remark->PassName.Len, 6U);
368 EXPECT_EQ(StringRef(Remark->RemarkName.Str, 12), "NoDefinition");
369 EXPECT_EQ(Remark->RemarkName.Len, 12U);
370 EXPECT_EQ(StringRef(Remark->FunctionName.Str, 3), "foo");
371 EXPECT_EQ(Remark->FunctionName.Len, 3U);
372 EXPECT_EQ(StringRef(Remark->DebugLoc.SourceFile.Str, 6), "file.c");
373 EXPECT_EQ(Remark->DebugLoc.SourceFile.Len, 6U);
374 EXPECT_EQ(Remark->DebugLoc.SourceLineNumber, 3U);
375 EXPECT_EQ(Remark->DebugLoc.SourceColumnNumber, 12U);
376 EXPECT_EQ(Remark->Hotness, 0U);
377 EXPECT_EQ(Remark->NumArgs, 4U);
378 // Arg 0
380 LLVMOptRemarkArg &Arg = Remark->Args[0];
381 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Callee");
382 EXPECT_EQ(Arg.Key.Len, 6U);
383 EXPECT_EQ(StringRef(Arg.Value.Str, 3), "bar");
384 EXPECT_EQ(Arg.Value.Len, 3U);
385 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
386 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
387 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
388 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
390 // Arg 1
392 LLVMOptRemarkArg &Arg = Remark->Args[1];
393 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
394 EXPECT_EQ(Arg.Key.Len, 6U);
395 EXPECT_EQ(StringRef(Arg.Value.Str, 26), " will not be inlined into ");
396 EXPECT_EQ(Arg.Value.Len, 26U);
397 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
398 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
399 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
400 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
402 // Arg 2
404 LLVMOptRemarkArg &Arg = Remark->Args[2];
405 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Caller");
406 EXPECT_EQ(Arg.Key.Len, 6U);
407 EXPECT_EQ(StringRef(Arg.Value.Str, 3), "foo");
408 EXPECT_EQ(Arg.Value.Len, 3U);
409 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 6), "file.c");
410 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 6U);
411 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 2U);
412 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
414 // Arg 3
416 LLVMOptRemarkArg &Arg = Remark->Args[3];
417 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
418 EXPECT_EQ(Arg.Key.Len, 6U);
419 EXPECT_EQ(StringRef(Arg.Value.Str, 38),
420 " because its definition is unavailable");
421 EXPECT_EQ(Arg.Value.Len, 38U);
422 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
423 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
424 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
425 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
428 EXPECT_EQ(LLVMOptRemarkParserGetNext(Parser), nullptr);
430 EXPECT_FALSE(LLVMOptRemarkParserHasError(Parser));
431 LLVMOptRemarkParserDispose(Parser);