1 // Copyright (c) 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "source/opt/debug_info_manager.h"
16
17 #include <memory>
18 #include <string>
19 #include <vector>
20
21 #include "effcee/effcee.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "source/opt/build_module.h"
25 #include "source/opt/instruction.h"
26 #include "spirv-tools/libspirv.hpp"
27
28 // Constants for OpenCL.DebugInfo.100 extension instructions.
29
30 static const uint32_t kDebugFunctionOperandFunctionIndex = 13;
31 static const uint32_t kDebugInlinedAtOperandLineIndex = 4;
32 static const uint32_t kDebugInlinedAtOperandScopeIndex = 5;
33 static const uint32_t kDebugInlinedAtOperandInlinedIndex = 6;
34 static const uint32_t kOpLineInOperandFileIndex = 0;
35 static const uint32_t kOpLineInOperandLineIndex = 1;
36 static const uint32_t kOpLineInOperandColumnIndex = 2;
37
38 namespace spvtools {
39 namespace opt {
40 namespace analysis {
41 namespace {
42
TEST(DebugInfoManager,GetDebugInlinedAt)43 TEST(DebugInfoManager, GetDebugInlinedAt) {
44 const std::string text = R"(
45 OpCapability Shader
46 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
47 OpMemoryModel Logical GLSL450
48 OpEntryPoint Fragment %main "main" %in_var_COLOR
49 OpExecutionMode %main OriginUpperLeft
50 %5 = OpString "ps.hlsl"
51 %14 = OpString "#line 1 \"ps.hlsl\"
52 void main(float in_var_color : COLOR) {
53 float color = in_var_color;
54 }
55 "
56 %17 = OpString "float"
57 %21 = OpString "main"
58 %24 = OpString "color"
59 OpName %in_var_COLOR "in.var.COLOR"
60 OpName %main "main"
61 OpDecorate %in_var_COLOR Location 0
62 %uint = OpTypeInt 32 0
63 %uint_32 = OpConstant %uint 32
64 %float = OpTypeFloat 32
65 %_ptr_Input_float = OpTypePointer Input %float
66 %void = OpTypeVoid
67 %27 = OpTypeFunction %void
68 %_ptr_Function_float = OpTypePointer Function %float
69 %in_var_COLOR = OpVariable %_ptr_Input_float Input
70 %13 = OpExtInst %void %1 DebugExpression
71 %15 = OpExtInst %void %1 DebugSource %5 %14
72 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
73 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
74 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
75 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
76 %100 = OpExtInst %void %1 DebugInlinedAt 7 %22
77 %main = OpFunction %void None %27
78 %28 = OpLabel
79 %31 = OpLoad %float %in_var_COLOR
80 OpStore %100 %31
81 OpReturn
82 OpFunctionEnd
83 )";
84
85 std::unique_ptr<IRContext> context =
86 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
87 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
88 DebugInfoManager manager(context.get());
89
90 EXPECT_EQ(manager.GetDebugInlinedAt(150), nullptr);
91 EXPECT_EQ(manager.GetDebugInlinedAt(31), nullptr);
92 EXPECT_EQ(manager.GetDebugInlinedAt(22), nullptr);
93
94 auto* inst = manager.GetDebugInlinedAt(100);
95 EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
96 EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
97 }
98
99 TEST(DebugInfoManager, CreateDebugInlinedAt) {
100 const std::string text = R"(
101 OpCapability Shader
102 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
103 OpMemoryModel Logical GLSL450
104 OpEntryPoint Fragment %main "main" %in_var_COLOR
105 OpExecutionMode %main OriginUpperLeft
106 %5 = OpString "ps.hlsl"
107 %14 = OpString "#line 1 \"ps.hlsl\"
108 void main(float in_var_color : COLOR) {
109 float color = in_var_color;
110 }
111 "
112 %17 = OpString "float"
113 %21 = OpString "main"
114 %24 = OpString "color"
115 OpName %in_var_COLOR "in.var.COLOR"
116 OpName %main "main"
117 OpDecorate %in_var_COLOR Location 0
118 %uint = OpTypeInt 32 0
119 %uint_32 = OpConstant %uint 32
120 %float = OpTypeFloat 32
121 %_ptr_Input_float = OpTypePointer Input %float
122 %void = OpTypeVoid
123 %27 = OpTypeFunction %void
124 %_ptr_Function_float = OpTypePointer Function %float
125 %in_var_COLOR = OpVariable %_ptr_Input_float Input
126 %13 = OpExtInst %void %1 DebugExpression
127 %15 = OpExtInst %void %1 DebugSource %5 %14
128 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
129 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
130 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
131 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
132 %100 = OpExtInst %void %1 DebugInlinedAt 7 %22
133 %main = OpFunction %void None %27
134 %28 = OpLabel
135 %31 = OpLoad %float %in_var_COLOR
136 OpStore %100 %31
137 OpReturn
138 OpFunctionEnd
139 )";
140
141 DebugScope scope(22U, 0U);
142
143 std::unique_ptr<IRContext> context =
144 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
145 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
146 DebugInfoManager manager(context.get());
147
148 uint32_t inlined_at_id = manager.CreateDebugInlinedAt(nullptr, scope);
149 auto* inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
150 EXPECT_NE(inlined_at, nullptr);
151 EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
152 1);
153 EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
154 22);
155 EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
156
157 const uint32_t line_number = 77U;
158 Instruction line(context.get(), SpvOpLine);
159 line.SetInOperands({
160 {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}},
161 {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}},
162 {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0U}},
163 });
164
165 inlined_at_id = manager.CreateDebugInlinedAt(&line, scope);
166 inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
167 EXPECT_NE(inlined_at, nullptr);
168 EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
169 line_number);
170 EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
171 22);
172 EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
173
174 scope.SetInlinedAt(100U);
175 inlined_at_id = manager.CreateDebugInlinedAt(&line, scope);
176 inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
177 EXPECT_NE(inlined_at, nullptr);
178 EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
179 line_number);
180 EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
181 22);
182 EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandInlinedIndex + 1);
183 EXPECT_EQ(
184 inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandInlinedIndex),
185 100U);
186 }
187
188 TEST(DebugInfoManager, GetDebugInfoNone) {
189 const std::string text = R"(
190 OpCapability Shader
191 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
192 OpMemoryModel Logical GLSL450
193 OpEntryPoint Fragment %main "main" %in_var_COLOR
194 OpExecutionMode %main OriginUpperLeft
195 %5 = OpString "ps.hlsl"
196 %14 = OpString "#line 1 \"ps.hlsl\"
197 void main(float in_var_color : COLOR) {
198 float color = in_var_color;
199 }
200 "
201 %17 = OpString "float"
202 %21 = OpString "main"
203 %24 = OpString "color"
204 OpName %in_var_COLOR "in.var.COLOR"
205 OpName %main "main"
206 OpDecorate %in_var_COLOR Location 0
207 %uint = OpTypeInt 32 0
208 %uint_32 = OpConstant %uint 32
209 %float = OpTypeFloat 32
210 %_ptr_Input_float = OpTypePointer Input %float
211 %void = OpTypeVoid
212 %27 = OpTypeFunction %void
213 %_ptr_Function_float = OpTypePointer Function %float
214 %in_var_COLOR = OpVariable %_ptr_Input_float Input
215 %13 = OpExtInst %void %1 DebugExpression
216 %15 = OpExtInst %void %1 DebugSource %5 %14
217 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
218 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
219 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
220 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
221 %12 = OpExtInst %void %1 DebugInfoNone
222 %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
223 %main = OpFunction %void None %27
224 %28 = OpLabel
225 %100 = OpVariable %_ptr_Function_float Function
226 %31 = OpLoad %float %in_var_COLOR
227 OpStore %100 %31
228 %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
229 OpReturn
230 OpFunctionEnd
231 )";
232
233 std::unique_ptr<IRContext> context =
234 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
235 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
236 DebugInfoManager manager(context.get());
237
238 Instruction* debug_info_none_inst = manager.GetDebugInfoNone();
239 EXPECT_NE(debug_info_none_inst, nullptr);
240 EXPECT_EQ(debug_info_none_inst->GetOpenCL100DebugOpcode(),
241 OpenCLDebugInfo100DebugInfoNone);
242 EXPECT_EQ(debug_info_none_inst->PreviousNode(), nullptr);
243 }
244
245 TEST(DebugInfoManager, CreateDebugInfoNone) {
246 const std::string text = R"(
247 OpCapability Shader
248 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
249 OpMemoryModel Logical GLSL450
250 OpEntryPoint Fragment %main "main" %in_var_COLOR
251 OpExecutionMode %main OriginUpperLeft
252 %5 = OpString "ps.hlsl"
253 %14 = OpString "#line 1 \"ps.hlsl\"
254 void main(float in_var_color : COLOR) {
255 float color = in_var_color;
256 }
257 "
258 %17 = OpString "float"
259 %21 = OpString "main"
260 %24 = OpString "color"
261 OpName %in_var_COLOR "in.var.COLOR"
262 OpName %main "main"
263 OpDecorate %in_var_COLOR Location 0
264 %uint = OpTypeInt 32 0
265 %uint_32 = OpConstant %uint 32
266 %float = OpTypeFloat 32
267 %_ptr_Input_float = OpTypePointer Input %float
268 %void = OpTypeVoid
269 %27 = OpTypeFunction %void
270 %_ptr_Function_float = OpTypePointer Function %float
271 %in_var_COLOR = OpVariable %_ptr_Input_float Input
272 %13 = OpExtInst %void %1 DebugExpression
273 %15 = OpExtInst %void %1 DebugSource %5 %14
274 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
275 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
276 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
277 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
278 %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
279 %main = OpFunction %void None %27
280 %28 = OpLabel
281 %100 = OpVariable %_ptr_Function_float Function
282 %31 = OpLoad %float %in_var_COLOR
283 OpStore %100 %31
284 %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
285 OpReturn
286 OpFunctionEnd
287 )";
288
289 std::unique_ptr<IRContext> context =
290 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
291 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
292 DebugInfoManager manager(context.get());
293
294 Instruction* debug_info_none_inst = manager.GetDebugInfoNone();
295 EXPECT_NE(debug_info_none_inst, nullptr);
296 EXPECT_EQ(debug_info_none_inst->GetOpenCL100DebugOpcode(),
297 OpenCLDebugInfo100DebugInfoNone);
298 EXPECT_EQ(debug_info_none_inst->PreviousNode(), nullptr);
299 }
300
301 TEST(DebugInfoManager, GetDebugFunction) {
302 const std::string text = R"(
303 OpCapability Shader
304 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
305 OpMemoryModel Logical GLSL450
306 OpEntryPoint Fragment %200 "200" %in_var_COLOR
307 OpExecutionMode %200 OriginUpperLeft
308 %5 = OpString "ps.hlsl"
309 %14 = OpString "#line 1 \"ps.hlsl\"
310 void 200(float in_var_color : COLOR) {
311 float color = in_var_color;
312 }
313 "
314 %17 = OpString "float"
315 %21 = OpString "200"
316 %24 = OpString "color"
317 OpName %in_var_COLOR "in.var.COLOR"
318 OpName %200 "200"
319 OpDecorate %in_var_COLOR Location 0
320 %uint = OpTypeInt 32 0
321 %uint_32 = OpConstant %uint 32
322 %float = OpTypeFloat 32
323 %_ptr_Input_float = OpTypePointer Input %float
324 %void = OpTypeVoid
325 %27 = OpTypeFunction %void
326 %_ptr_Function_float = OpTypePointer Function %float
327 %in_var_COLOR = OpVariable %_ptr_Input_float Input
328 %13 = OpExtInst %void %1 DebugExpression
329 %15 = OpExtInst %void %1 DebugSource %5 %14
330 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
331 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
332 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
333 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %200
334 %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
335 %200 = OpFunction %void None %27
336 %28 = OpLabel
337 %100 = OpVariable %_ptr_Function_float Function
338 %31 = OpLoad %float %in_var_COLOR
339 OpStore %100 %31
340 %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
341 OpReturn
342 OpFunctionEnd
343 )";
344
345 std::unique_ptr<IRContext> context =
346 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
347 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
348 DebugInfoManager manager(context.get());
349
350 EXPECT_EQ(manager.GetDebugFunction(100), nullptr);
351 EXPECT_EQ(manager.GetDebugFunction(150), nullptr);
352
353 Instruction* dbg_fn = manager.GetDebugFunction(200);
354
355 EXPECT_EQ(dbg_fn->GetOpenCL100DebugOpcode(), OpenCLDebugInfo100DebugFunction);
356 EXPECT_EQ(dbg_fn->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex),
357 200);
358 }
359
360 TEST(DebugInfoManager, GetDebugFunction_InlinedAway) {
361 // struct PS_INPUT
362 // {
363 // float4 iColor : COLOR;
364 // };
365 //
366 // struct PS_OUTPUT
367 // {
368 // float4 oColor : SV_Target0;
369 // };
370 //
371 // float4 foo(float4 ic)
372 // {
373 // float4 c = ic / 2.0;
374 // return c;
375 // }
376 //
377 // PS_OUTPUT MainPs(PS_INPUT i)
378 // {
379 // PS_OUTPUT ps_output;
380 // float4 ic = i.iColor;
381 // ps_output.oColor = foo(ic);
382 // return ps_output;
383 // }
384 const std::string text = R"(
385 OpCapability Shader
386 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
387 OpMemoryModel Logical GLSL450
388 OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR %out_var_SV_Target0
389 OpExecutionMode %MainPs OriginUpperLeft
390 %15 = OpString "foo2.frag"
391 %19 = OpString "PS_OUTPUT"
392 %23 = OpString "float"
393 %26 = OpString "oColor"
394 %28 = OpString "PS_INPUT"
395 %31 = OpString "iColor"
396 %33 = OpString "foo"
397 %37 = OpString "c"
398 %39 = OpString "ic"
399 %42 = OpString "src.MainPs"
400 %47 = OpString "ps_output"
401 %50 = OpString "i"
402 OpName %in_var_COLOR "in.var.COLOR"
403 OpName %out_var_SV_Target0 "out.var.SV_Target0"
404 OpName %MainPs "MainPs"
405 OpDecorate %in_var_COLOR Location 0
406 OpDecorate %out_var_SV_Target0 Location 0
407 %int = OpTypeInt 32 1
408 %int_0 = OpConstant %int 0
409 %float = OpTypeFloat 32
410 %v4float = OpTypeVector %float 4
411 %uint = OpTypeInt 32 0
412 %uint_32 = OpConstant %uint 32
413 %_ptr_Input_v4float = OpTypePointer Input %v4float
414 %_ptr_Output_v4float = OpTypePointer Output %v4float
415 %void = OpTypeVoid
416 %uint_128 = OpConstant %uint 128
417 %uint_0 = OpConstant %uint 0
418 %52 = OpTypeFunction %void
419 %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
420 %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
421 %float_0_5 = OpConstant %float 0.5
422 %130 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5
423 %115 = OpExtInst %void %1 DebugInfoNone
424 %49 = OpExtInst %void %1 DebugExpression
425 %17 = OpExtInst %void %1 DebugSource %15
426 %18 = OpExtInst %void %1 DebugCompilationUnit 1 4 %17 HLSL
427 %21 = OpExtInst %void %1 DebugTypeComposite %19 Structure %17 6 1 %18 %19 %uint_128 FlagIsProtected|FlagIsPrivate %22
428 %24 = OpExtInst %void %1 DebugTypeBasic %23 %uint_32 Float
429 %25 = OpExtInst %void %1 DebugTypeVector %24 4
430 %22 = OpExtInst %void %1 DebugTypeMember %26 %25 %17 8 5 %21 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
431 %29 = OpExtInst %void %1 DebugTypeComposite %28 Structure %17 1 1 %18 %28 %uint_128 FlagIsProtected|FlagIsPrivate %30
432 %30 = OpExtInst %void %1 DebugTypeMember %31 %25 %17 3 5 %29 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
433 %32 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %25 %25
434 %34 = OpExtInst %void %1 DebugFunction %33 %32 %17 11 1 %18 %33 FlagIsProtected|FlagIsPrivate 12 %115
435 %36 = OpExtInst %void %1 DebugLexicalBlock %17 12 1 %34
436 %38 = OpExtInst %void %1 DebugLocalVariable %37 %25 %17 13 12 %36 FlagIsLocal
437 %41 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %21 %29
438 %43 = OpExtInst %void %1 DebugFunction %42 %41 %17 17 1 %18 %42 FlagIsProtected|FlagIsPrivate 18 %115
439 %45 = OpExtInst %void %1 DebugLexicalBlock %17 18 1 %43
440 %46 = OpExtInst %void %1 DebugLocalVariable %39 %25 %17 20 12 %45 FlagIsLocal
441 %48 = OpExtInst %void %1 DebugLocalVariable %47 %21 %17 19 15 %45 FlagIsLocal
442 %107 = OpExtInst %void %1 DebugInlinedAt 21 %45
443 %MainPs = OpFunction %void None %52
444 %53 = OpLabel
445 %57 = OpLoad %v4float %in_var_COLOR
446 %131 = OpExtInst %void %1 DebugScope %45
447 OpLine %15 20 12
448 %117 = OpExtInst %void %1 DebugValue %46 %57 %49
449 %132 = OpExtInst %void %1 DebugScope %36 %107
450 OpLine %15 13 19
451 %112 = OpFMul %v4float %57 %130
452 OpLine %15 13 12
453 %116 = OpExtInst %void %1 DebugValue %38 %112 %49
454 %133 = OpExtInst %void %1 DebugScope %45
455 %128 = OpExtInst %void %1 DebugValue %48 %112 %49 %int_0
456 %134 = OpExtInst %void %1 DebugNoScope
457 OpStore %out_var_SV_Target0 %112
458 OpReturn
459 OpFunctionEnd
460 )";
461
462 std::unique_ptr<IRContext> context =
463 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
464 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
465 DebugInfoManager manager(context.get());
466
467 EXPECT_EQ(manager.GetDebugFunction(115), nullptr);
468 }
469
470 TEST(DebugInfoManager, CloneDebugInlinedAt) {
471 const std::string text = R"(
472 OpCapability Shader
473 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
474 OpMemoryModel Logical GLSL450
475 OpEntryPoint Fragment %main "main" %in_var_COLOR
476 OpExecutionMode %main OriginUpperLeft
477 %5 = OpString "ps.hlsl"
478 %14 = OpString "#line 1 \"ps.hlsl\"
479 void main(float in_var_color : COLOR) {
480 float color = in_var_color;
481 }
482 "
483 %17 = OpString "float"
484 %21 = OpString "main"
485 %24 = OpString "color"
486 OpName %in_var_COLOR "in.var.COLOR"
487 OpName %main "main"
488 OpDecorate %in_var_COLOR Location 0
489 %uint = OpTypeInt 32 0
490 %uint_32 = OpConstant %uint 32
491 %float = OpTypeFloat 32
492 %_ptr_Input_float = OpTypePointer Input %float
493 %void = OpTypeVoid
494 %27 = OpTypeFunction %void
495 %_ptr_Function_float = OpTypePointer Function %float
496 %in_var_COLOR = OpVariable %_ptr_Input_float Input
497 %13 = OpExtInst %void %1 DebugExpression
498 %15 = OpExtInst %void %1 DebugSource %5 %14
499 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
500 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
501 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
502 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
503 %100 = OpExtInst %void %1 DebugInlinedAt 7 %22
504 %main = OpFunction %void None %27
505 %28 = OpLabel
506 %31 = OpLoad %float %in_var_COLOR
507 OpStore %100 %31
508 OpReturn
509 OpFunctionEnd
510 )";
511
512 std::unique_ptr<IRContext> context =
513 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
514 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
515 DebugInfoManager manager(context.get());
516
517 EXPECT_EQ(manager.CloneDebugInlinedAt(150), nullptr);
518 EXPECT_EQ(manager.CloneDebugInlinedAt(22), nullptr);
519
520 auto* inst = manager.CloneDebugInlinedAt(100);
521 EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
522 EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
523 EXPECT_EQ(inst->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
524
525 Instruction* before_100 = nullptr;
526 for (auto it = context->module()->ext_inst_debuginfo_begin();
527 it != context->module()->ext_inst_debuginfo_end(); ++it) {
528 if (it->result_id() == 100) break;
529 before_100 = &*it;
530 }
531 EXPECT_NE(inst, before_100);
532
533 inst = manager.CloneDebugInlinedAt(100, manager.GetDebugInlinedAt(100));
534 EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
535 EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
536 EXPECT_EQ(inst->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
537
538 before_100 = nullptr;
539 for (auto it = context->module()->ext_inst_debuginfo_begin();
540 it != context->module()->ext_inst_debuginfo_end(); ++it) {
541 if (it->result_id() == 100) break;
542 before_100 = &*it;
543 }
544 EXPECT_EQ(inst, before_100);
545 }
546
547 TEST(DebugInfoManager, KillDebugDeclares) {
548 const std::string text = R"(
549 OpCapability Shader
550 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
551 OpMemoryModel Logical GLSL450
552 OpEntryPoint Fragment %main "main" %in_var_COLOR
553 OpExecutionMode %main OriginUpperLeft
554 %5 = OpString "ps.hlsl"
555 %14 = OpString "#line 1 \"ps.hlsl\"
556 void main(float in_var_color : COLOR) {
557 float color = in_var_color;
558 }
559 "
560 %17 = OpString "float"
561 %21 = OpString "main"
562 %24 = OpString "color"
563 OpName %in_var_COLOR "in.var.COLOR"
564 OpName %main "main"
565 OpDecorate %in_var_COLOR Location 0
566 %uint = OpTypeInt 32 0
567 %uint_32 = OpConstant %uint 32
568 %float = OpTypeFloat 32
569 %_ptr_Input_float = OpTypePointer Input %float
570 %void = OpTypeVoid
571 %27 = OpTypeFunction %void
572 %_ptr_Function_float = OpTypePointer Function %float
573 %in_var_COLOR = OpVariable %_ptr_Input_float Input
574 %13 = OpExtInst %void %1 DebugExpression
575 %15 = OpExtInst %void %1 DebugSource %5 %14
576 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
577 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
578 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
579 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
580 %12 = OpExtInst %void %1 DebugInfoNone
581 %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
582 %main = OpFunction %void None %27
583 %28 = OpLabel
584 %100 = OpVariable %_ptr_Function_float Function
585 %31 = OpLoad %float %in_var_COLOR
586 OpStore %100 %31
587 %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
588 %37 = OpExtInst %void %1 DebugDeclare %25 %100 %13
589 %38 = OpExtInst %void %1 DebugDeclare %25 %100 %13
590 OpReturn
591 OpFunctionEnd
592 )";
593
594 std::unique_ptr<IRContext> context =
595 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
596 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
597 auto* dbg_info_mgr = context->get_debug_info_mgr();
598 auto* def_use_mgr = context->get_def_use_mgr();
599
600 EXPECT_TRUE(dbg_info_mgr->IsVariableDebugDeclared(100));
601 EXPECT_EQ(def_use_mgr->GetDef(36)->GetOpenCL100DebugOpcode(),
602 OpenCLDebugInfo100DebugDeclare);
603 EXPECT_EQ(def_use_mgr->GetDef(37)->GetOpenCL100DebugOpcode(),
604 OpenCLDebugInfo100DebugDeclare);
605 EXPECT_EQ(def_use_mgr->GetDef(38)->GetOpenCL100DebugOpcode(),
606 OpenCLDebugInfo100DebugDeclare);
607
608 dbg_info_mgr->KillDebugDeclares(100);
609 EXPECT_EQ(def_use_mgr->GetDef(36), nullptr);
610 EXPECT_EQ(def_use_mgr->GetDef(37), nullptr);
611 EXPECT_EQ(def_use_mgr->GetDef(38), nullptr);
612 EXPECT_FALSE(dbg_info_mgr->IsVariableDebugDeclared(100));
613 }
614
615 TEST(DebugInfoManager, AddDebugValueForDecl) {
616 const std::string text = R"(
617 OpCapability Shader
618 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
619 OpMemoryModel Logical GLSL450
620 OpEntryPoint Fragment %main "main" %in_var_COLOR
621 OpExecutionMode %main OriginUpperLeft
622 %5 = OpString "ps.hlsl"
623 %14 = OpString "#line 1 \"ps.hlsl\"
624 void main(float in_var_color : COLOR) {
625 float color = in_var_color;
626 }
627 "
628 %17 = OpString "float"
629 %21 = OpString "main"
630 %24 = OpString "color"
631 OpName %in_var_COLOR "in.var.COLOR"
632 OpName %main "main"
633 OpDecorate %in_var_COLOR Location 0
634 %uint = OpTypeInt 32 0
635 %uint_32 = OpConstant %uint 32
636 %float = OpTypeFloat 32
637 %_ptr_Input_float = OpTypePointer Input %float
638 %void = OpTypeVoid
639 %27 = OpTypeFunction %void
640 %_ptr_Function_float = OpTypePointer Function %float
641 %in_var_COLOR = OpVariable %_ptr_Input_float Input
642 %13 = OpExtInst %void %1 DebugExpression
643 %15 = OpExtInst %void %1 DebugSource %5 %14
644 %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
645 %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
646 %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
647 %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
648 %12 = OpExtInst %void %1 DebugInfoNone
649 %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
650 %main = OpFunction %void None %27
651 %28 = OpLabel
652 %100 = OpVariable %_ptr_Function_float Function
653 %31 = OpLoad %float %in_var_COLOR
654 %101 = OpExtInst %void %1 DebugScope %22
655 OpLine %5 13 7
656 OpStore %100 %31
657 OpNoLine
658 %102 = OpExtInst %void %1 DebugNoScope
659 %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
660 OpReturn
661 OpFunctionEnd
662 )";
663
664 std::unique_ptr<IRContext> context =
665 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
666 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
667 auto* def_use_mgr = context->get_def_use_mgr();
668 auto* dbg_decl = def_use_mgr->GetDef(36);
669 EXPECT_EQ(dbg_decl->GetOpenCL100DebugOpcode(),
670 OpenCLDebugInfo100DebugDeclare);
671
672 auto* dbg_info_mgr = context->get_debug_info_mgr();
673 Instruction* store = dbg_decl->PreviousNode();
674 auto* dbg_value =
675 dbg_info_mgr->AddDebugValueForDecl(dbg_decl, 100, dbg_decl, store);
676
677 EXPECT_EQ(dbg_value->GetOpenCL100DebugOpcode(), OpenCLDebugInfo100DebugValue);
678 EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
679 kOpLineInOperandFileIndex),
680 5);
681 EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
682 kOpLineInOperandLineIndex),
683 13);
684 EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
685 kOpLineInOperandColumnIndex),
686 7);
687 }
688
689 } // namespace
690 } // namespace analysis
691 } // namespace opt
692 } // namespace spvtools
693