From fb27bbf3077f92cc1a8a55777bce2810a94079cf Mon Sep 17 00:00:00 2001 From: Jeremy Hayes Date: Fri, 9 Sep 2022 11:56:35 -0600 Subject: Fix DebugInlinedAt Line operand (#4928) Line instructions may be OpLine or DebugLine. This commit adds support for DebugLine. --- source/opt/debug_info_manager.cpp | 20 ++++++++- test/opt/inline_test.cpp | 89 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/source/opt/debug_info_manager.cpp b/source/opt/debug_info_manager.cpp index cef095fbf..f0a78a5ff 100644 --- a/source/opt/debug_info_manager.cpp +++ b/source/opt/debug_info_manager.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 Google LLC +// Copyright (c) 2020-2022 Google LLC +// Copyright (c) 2022 LunarG Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +25,8 @@ static const uint32_t kOpLineOperandLineIndex = 1; static const uint32_t kLineOperandIndexDebugFunction = 7; static const uint32_t kLineOperandIndexDebugLexicalBlock = 5; +static const uint32_t kLineOperandIndexDebugLine = 5; +static const uint32_t kConstanstOperandIndexLiteral = 2; static const uint32_t kDebugFunctionOperandFunctionIndex = 13; static const uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4; static const uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5; @@ -210,7 +213,20 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line, break; } } else { - line_number = line->GetSingleWordOperand(kOpLineOperandLineIndex); + if (line->opcode() == SpvOpLine) { + line_number = line->GetSingleWordOperand(kOpLineOperandLineIndex); + } else if (line->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugLine) { + auto const line_number_id = + line->GetSingleWordOperand(kLineOperandIndexDebugLine); + auto const line_number_inst = + context()->get_def_use_mgr()->GetDef(line_number_id); + line_number = + line_number_inst->GetSingleWordOperand(kConstanstOperandIndexLiteral); + } else { + assert(false && + "Unreachable. A line instruction must be OpLine or DebugLine"); + } // If we need the line number as an ID, generate that constant now. // If Constant or DefUse managers are invalid, generate constant diff --git a/test/opt/inline_test.cpp b/test/opt/inline_test.cpp index d804f7cc1..7854965e8 100644 --- a/test/opt/inline_test.cpp +++ b/test/opt/inline_test.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017 Valve Corporation -// Copyright (c) 2017 LunarG Inc. +// Copyright (c) 2017-2022 Valve Corporation +// Copyright (c) 2017-2022 LunarG Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -4337,6 +4337,91 @@ OpFunctionEnd SinglePassRunAndMatch(text, true); } +TEST_F(InlineTest, CreateDebugInlinedAtFromDebugLine) { + const std::string text = R"(OpCapability Shader +; CHECK: OpExtInst %void %1 DebugInlinedAt %uint_6_0 +OpExtension "SPV_KHR_non_semantic_info" +%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" +OpExecutionMode %main OriginUpperLeft +%3 = OpString "debuginlinedat.frag" +%8 = OpString "int" +%15 = OpString "int function1() { + return 1; +} + +void main() { + function1(); +} +" +%20 = OpString "function1" +%21 = OpString "" +%26 = OpString "main" +OpName %main "main" +OpName %src_main "src.main" +OpName %bb_entry "bb.entry" +OpName %function1 "function1" +OpName %bb_entry_0 "bb.entry" +%int = OpTypeInt 32 1 +%int_1 = OpConstant %int 1 +%uint = OpTypeInt 32 0 +%uint_32 = OpConstant %uint 32 +%void = OpTypeVoid +%uint_4 = OpConstant %uint 4 +%uint_0 = OpConstant %uint 0 +%uint_3 = OpConstant %uint 3 +%uint_1 = OpConstant %uint 1 +%uint_5 = OpConstant %uint 5 +%uint_17 = OpConstant %uint 17 +%uint_13 = OpConstant %uint 13 +%30 = OpTypeFunction %void +%uint_7 = OpConstant %uint 7 +%uint_6 = OpConstant %uint 6 +%uint_2 = OpConstant %uint 2 +%uint_12 = OpConstant %uint 12 +%48 = OpTypeFunction %int +%uint_9 = OpConstant %uint 9 +%10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0 +%13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10 +%16 = OpExtInst %void %1 DebugSource %3 %15 +%17 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %16 %uint_5 +%22 = OpExtInst %void %1 DebugFunction %20 %13 %16 %uint_1 %uint_1 %17 %21 %uint_3 %uint_1 +%23 = OpExtInst %void %1 DebugLexicalBlock %16 %uint_1 %uint_17 %22 +%25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void +%27 = OpExtInst %void %1 DebugFunction %26 %25 %16 %uint_5 %uint_1 %17 %21 %uint_3 %uint_5 +%28 = OpExtInst %void %1 DebugLexicalBlock %16 %uint_5 %uint_13 %27 +%main = OpFunction %void None %30 +%31 = OpLabel +%32 = OpFunctionCall %void %src_main +%34 = OpExtInst %void %1 DebugLine %16 %uint_7 %uint_7 %uint_1 %uint_1 +OpReturn +OpFunctionEnd +%src_main = OpFunction %void None %30 +%bb_entry = OpLabel +%37 = OpExtInst %void %1 DebugScope %27 +%38 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main +%39 = OpExtInst %void %1 DebugScope %28 +%40 = OpExtInst %void %1 DebugLine %16 %uint_6 %uint_6 %uint_2 %uint_12 +%44 = OpFunctionCall %int %function1 +%46 = OpExtInst %void %1 DebugScope %27 +%47 = OpExtInst %void %1 DebugLine %16 %uint_7 %uint_7 %uint_1 %uint_1 +OpReturn +OpFunctionEnd +%function1 = OpFunction %int None %48 +%bb_entry_0 = OpLabel +%50 = OpExtInst %void %1 DebugScope %22 +%51 = OpExtInst %void %1 DebugFunctionDefinition %22 %function1 +%52 = OpExtInst %void %1 DebugScope %23 +%53 = OpExtInst %void %1 DebugLine %16 %uint_2 %uint_2 %uint_2 %uint_9 +OpReturnValue %int_1 +OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_2); + SinglePassRunAndMatch(text, true); +} + // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Empty modules -- cgit v1.2.3