mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-25 21:10:04 +00:00
001604bd4a
Do this if Constant or DefUse managers are invalid. Using the ConstantManager attempts to regenerate the DefUseManager which is not valid during inlining.
809 lines
32 KiB
C++
809 lines
32 KiB
C++
// Copyright (c) 2020 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "source/opt/debug_info_manager.h"
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "effcee/effcee.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
#include "source/opt/build_module.h"
|
|
#include "source/opt/instruction.h"
|
|
#include "spirv-tools/libspirv.hpp"
|
|
|
|
// Constants for OpenCL.DebugInfo.100 extension instructions.
|
|
|
|
static const uint32_t kDebugFunctionOperandFunctionIndex = 13;
|
|
static const uint32_t kDebugInlinedAtOperandLineIndex = 4;
|
|
static const uint32_t kDebugInlinedAtOperandScopeIndex = 5;
|
|
static const uint32_t kDebugInlinedAtOperandInlinedIndex = 6;
|
|
static const uint32_t kOpLineInOperandFileIndex = 0;
|
|
static const uint32_t kOpLineInOperandLineIndex = 1;
|
|
static const uint32_t kOpLineInOperandColumnIndex = 2;
|
|
|
|
namespace spvtools {
|
|
namespace opt {
|
|
namespace analysis {
|
|
namespace {
|
|
|
|
TEST(DebugInfoManager, GetDebugInlinedAt) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%100 = OpExtInst %void %1 DebugInlinedAt 7 %22
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
EXPECT_EQ(manager.GetDebugInlinedAt(150), nullptr);
|
|
EXPECT_EQ(manager.GetDebugInlinedAt(31), nullptr);
|
|
EXPECT_EQ(manager.GetDebugInlinedAt(22), nullptr);
|
|
|
|
auto* inst = manager.GetDebugInlinedAt(100);
|
|
EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
|
|
EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
|
|
}
|
|
|
|
TEST(DebugInfoManager, CreateDebugInlinedAt) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%100 = OpExtInst %void %1 DebugInlinedAt 7 %22
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
DebugScope scope(22U, 0U);
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
uint32_t inlined_at_id = manager.CreateDebugInlinedAt(nullptr, scope);
|
|
auto* inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
|
|
EXPECT_NE(inlined_at, nullptr);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
|
|
1);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
|
|
22);
|
|
EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
|
|
|
|
const uint32_t line_number = 77U;
|
|
Instruction line(context.get(), SpvOpLine);
|
|
line.SetInOperands({
|
|
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}},
|
|
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}},
|
|
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0U}},
|
|
});
|
|
|
|
inlined_at_id = manager.CreateDebugInlinedAt(&line, scope);
|
|
inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
|
|
EXPECT_NE(inlined_at, nullptr);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
|
|
line_number);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
|
|
22);
|
|
EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
|
|
|
|
scope.SetInlinedAt(100U);
|
|
inlined_at_id = manager.CreateDebugInlinedAt(&line, scope);
|
|
inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
|
|
EXPECT_NE(inlined_at, nullptr);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
|
|
line_number);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
|
|
22);
|
|
EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandInlinedIndex + 1);
|
|
EXPECT_EQ(
|
|
inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandInlinedIndex),
|
|
100U);
|
|
}
|
|
|
|
TEST(DebugInfoManager, CreateDebugInlinedAtWithConstantManager) {
|
|
// Show that CreateDebugInlinedAt will use the Constant manager to generate
|
|
// its line operand if the Constant and DefUse managers are valid. This is
|
|
// proven by checking that the id for the line operand 7 is the same as the
|
|
// existing constant 7.
|
|
//
|
|
// int function1() {
|
|
// return 1;
|
|
// }
|
|
//
|
|
// void main() {
|
|
// function1();
|
|
// }
|
|
const std::string text = R"(OpCapability Shader
|
|
OpExtension "SPV_KHR_non_semantic_info"
|
|
%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main"
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%3 = OpString "parent3.hlsl"
|
|
%8 = OpString "int"
|
|
%19 = OpString "function1"
|
|
%20 = 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_2 = OpConstant %uint 2
|
|
%uint_17 = OpConstant %uint 17
|
|
%uint_6 = OpConstant %uint 6
|
|
%uint_13 = OpConstant %uint 13
|
|
%100 = OpConstant %uint 7
|
|
%31 = OpTypeFunction %void
|
|
%42 = OpTypeFunction %int
|
|
%10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0
|
|
%13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10
|
|
%15 = OpExtInst %void %1 DebugSource %3
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %15 %uint_5
|
|
%21 = OpExtInst %void %1 DebugFunction %19 %13 %15 %uint_2 %uint_1 %16 %20 %uint_3 %uint_2
|
|
%23 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_2 %uint_17 %21
|
|
%25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void
|
|
%27 = OpExtInst %void %1 DebugFunction %26 %25 %15 %uint_6 %uint_1 %16 %20 %uint_3 %uint_6
|
|
%29 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_6 %uint_13 %27
|
|
%main = OpFunction %void None %31
|
|
%32 = OpLabel
|
|
%33 = OpFunctionCall %void %src_main
|
|
OpLine %3 8 1
|
|
OpReturn
|
|
OpFunctionEnd
|
|
OpLine %3 6 1
|
|
%src_main = OpFunction %void None %31
|
|
OpNoLine
|
|
%bb_entry = OpLabel
|
|
%47 = OpExtInst %void %1 DebugScope %27
|
|
%37 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main
|
|
%48 = OpExtInst %void %1 DebugScope %29
|
|
OpLine %3 7 3
|
|
%39 = OpFunctionCall %int %function1
|
|
%49 = OpExtInst %void %1 DebugScope %27
|
|
OpLine %3 8 1
|
|
OpReturn
|
|
%50 = OpExtInst %void %1 DebugNoScope
|
|
OpFunctionEnd
|
|
OpLine %3 2 1
|
|
%function1 = OpFunction %int None %42
|
|
OpNoLine
|
|
%bb_entry_0 = OpLabel
|
|
%51 = OpExtInst %void %1 DebugScope %21
|
|
%45 = OpExtInst %void %1 DebugFunctionDefinition %21 %function1
|
|
%52 = OpExtInst %void %1 DebugScope %23
|
|
OpLine %3 3 3
|
|
OpReturnValue %int_1
|
|
%53 = OpExtInst %void %1 DebugNoScope
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
|
|
const uint32_t line_number = 7U;
|
|
Instruction line(context.get(), SpvOpLine);
|
|
line.SetInOperands({
|
|
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}},
|
|
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}},
|
|
{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0U}},
|
|
});
|
|
|
|
DebugScope scope(29U, 0U);
|
|
|
|
auto db_manager = context.get()->get_debug_info_mgr();
|
|
auto du_manager = context.get()->get_def_use_mgr();
|
|
auto c_manager = context.get()->get_constant_mgr();
|
|
|
|
(void)du_manager;
|
|
(void)c_manager;
|
|
|
|
uint32_t inlined_at_id = db_manager->CreateDebugInlinedAt(&line, scope);
|
|
auto* inlined_at = db_manager->GetDebugInlinedAt(inlined_at_id);
|
|
EXPECT_NE(inlined_at, nullptr);
|
|
EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
|
|
100);
|
|
}
|
|
|
|
TEST(DebugInfoManager, GetDebugInfoNone) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%12 = OpExtInst %void %1 DebugInfoNone
|
|
%25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%100 = OpVariable %_ptr_Function_float Function
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
%36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
Instruction* debug_info_none_inst = manager.GetDebugInfoNone();
|
|
EXPECT_NE(debug_info_none_inst, nullptr);
|
|
EXPECT_EQ(debug_info_none_inst->GetOpenCL100DebugOpcode(),
|
|
OpenCLDebugInfo100DebugInfoNone);
|
|
EXPECT_EQ(debug_info_none_inst->PreviousNode(), nullptr);
|
|
}
|
|
|
|
TEST(DebugInfoManager, CreateDebugInfoNone) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%100 = OpVariable %_ptr_Function_float Function
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
%36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
Instruction* debug_info_none_inst = manager.GetDebugInfoNone();
|
|
EXPECT_NE(debug_info_none_inst, nullptr);
|
|
EXPECT_EQ(debug_info_none_inst->GetOpenCL100DebugOpcode(),
|
|
OpenCLDebugInfo100DebugInfoNone);
|
|
EXPECT_EQ(debug_info_none_inst->PreviousNode(), nullptr);
|
|
}
|
|
|
|
TEST(DebugInfoManager, GetDebugFunction) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %200 "200" %in_var_COLOR
|
|
OpExecutionMode %200 OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void 200(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "200"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %200 "200"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %200
|
|
%25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
|
|
%200 = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%100 = OpVariable %_ptr_Function_float Function
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
%36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
EXPECT_EQ(manager.GetDebugFunction(100), nullptr);
|
|
EXPECT_EQ(manager.GetDebugFunction(150), nullptr);
|
|
|
|
Instruction* dbg_fn = manager.GetDebugFunction(200);
|
|
|
|
EXPECT_EQ(dbg_fn->GetOpenCL100DebugOpcode(), OpenCLDebugInfo100DebugFunction);
|
|
EXPECT_EQ(dbg_fn->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex),
|
|
200);
|
|
}
|
|
|
|
TEST(DebugInfoManager, GetDebugFunction_InlinedAway) {
|
|
// struct PS_INPUT
|
|
// {
|
|
// float4 iColor : COLOR;
|
|
// };
|
|
//
|
|
// struct PS_OUTPUT
|
|
// {
|
|
// float4 oColor : SV_Target0;
|
|
// };
|
|
//
|
|
// float4 foo(float4 ic)
|
|
// {
|
|
// float4 c = ic / 2.0;
|
|
// return c;
|
|
// }
|
|
//
|
|
// PS_OUTPUT MainPs(PS_INPUT i)
|
|
// {
|
|
// PS_OUTPUT ps_output;
|
|
// float4 ic = i.iColor;
|
|
// ps_output.oColor = foo(ic);
|
|
// return ps_output;
|
|
// }
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR %out_var_SV_Target0
|
|
OpExecutionMode %MainPs OriginUpperLeft
|
|
%15 = OpString "foo2.frag"
|
|
%19 = OpString "PS_OUTPUT"
|
|
%23 = OpString "float"
|
|
%26 = OpString "oColor"
|
|
%28 = OpString "PS_INPUT"
|
|
%31 = OpString "iColor"
|
|
%33 = OpString "foo"
|
|
%37 = OpString "c"
|
|
%39 = OpString "ic"
|
|
%42 = OpString "src.MainPs"
|
|
%47 = OpString "ps_output"
|
|
%50 = OpString "i"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %out_var_SV_Target0 "out.var.SV_Target0"
|
|
OpName %MainPs "MainPs"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
OpDecorate %out_var_SV_Target0 Location 0
|
|
%int = OpTypeInt 32 1
|
|
%int_0 = OpConstant %int 0
|
|
%float = OpTypeFloat 32
|
|
%v4float = OpTypeVector %float 4
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%_ptr_Input_v4float = OpTypePointer Input %v4float
|
|
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
|
%void = OpTypeVoid
|
|
%uint_128 = OpConstant %uint 128
|
|
%uint_0 = OpConstant %uint 0
|
|
%52 = OpTypeFunction %void
|
|
%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
|
|
%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
|
|
%float_0_5 = OpConstant %float 0.5
|
|
%130 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5
|
|
%115 = OpExtInst %void %1 DebugInfoNone
|
|
%49 = OpExtInst %void %1 DebugExpression
|
|
%17 = OpExtInst %void %1 DebugSource %15
|
|
%18 = OpExtInst %void %1 DebugCompilationUnit 1 4 %17 HLSL
|
|
%21 = OpExtInst %void %1 DebugTypeComposite %19 Structure %17 6 1 %18 %19 %uint_128 FlagIsProtected|FlagIsPrivate %22
|
|
%24 = OpExtInst %void %1 DebugTypeBasic %23 %uint_32 Float
|
|
%25 = OpExtInst %void %1 DebugTypeVector %24 4
|
|
%22 = OpExtInst %void %1 DebugTypeMember %26 %25 %17 8 5 %21 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
|
|
%29 = OpExtInst %void %1 DebugTypeComposite %28 Structure %17 1 1 %18 %28 %uint_128 FlagIsProtected|FlagIsPrivate %30
|
|
%30 = OpExtInst %void %1 DebugTypeMember %31 %25 %17 3 5 %29 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
|
|
%32 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %25 %25
|
|
%34 = OpExtInst %void %1 DebugFunction %33 %32 %17 11 1 %18 %33 FlagIsProtected|FlagIsPrivate 12 %115
|
|
%36 = OpExtInst %void %1 DebugLexicalBlock %17 12 1 %34
|
|
%38 = OpExtInst %void %1 DebugLocalVariable %37 %25 %17 13 12 %36 FlagIsLocal
|
|
%41 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %21 %29
|
|
%43 = OpExtInst %void %1 DebugFunction %42 %41 %17 17 1 %18 %42 FlagIsProtected|FlagIsPrivate 18 %115
|
|
%45 = OpExtInst %void %1 DebugLexicalBlock %17 18 1 %43
|
|
%46 = OpExtInst %void %1 DebugLocalVariable %39 %25 %17 20 12 %45 FlagIsLocal
|
|
%48 = OpExtInst %void %1 DebugLocalVariable %47 %21 %17 19 15 %45 FlagIsLocal
|
|
%107 = OpExtInst %void %1 DebugInlinedAt 21 %45
|
|
%MainPs = OpFunction %void None %52
|
|
%53 = OpLabel
|
|
%57 = OpLoad %v4float %in_var_COLOR
|
|
%131 = OpExtInst %void %1 DebugScope %45
|
|
OpLine %15 20 12
|
|
%117 = OpExtInst %void %1 DebugValue %46 %57 %49
|
|
%132 = OpExtInst %void %1 DebugScope %36 %107
|
|
OpLine %15 13 19
|
|
%112 = OpFMul %v4float %57 %130
|
|
OpLine %15 13 12
|
|
%116 = OpExtInst %void %1 DebugValue %38 %112 %49
|
|
%133 = OpExtInst %void %1 DebugScope %45
|
|
%128 = OpExtInst %void %1 DebugValue %48 %112 %49 %int_0
|
|
%134 = OpExtInst %void %1 DebugNoScope
|
|
OpStore %out_var_SV_Target0 %112
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
EXPECT_EQ(manager.GetDebugFunction(115), nullptr);
|
|
}
|
|
|
|
TEST(DebugInfoManager, CloneDebugInlinedAt) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%100 = OpExtInst %void %1 DebugInlinedAt 7 %22
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
DebugInfoManager manager(context.get());
|
|
|
|
EXPECT_EQ(manager.CloneDebugInlinedAt(150), nullptr);
|
|
EXPECT_EQ(manager.CloneDebugInlinedAt(22), nullptr);
|
|
|
|
auto* inst = manager.CloneDebugInlinedAt(100);
|
|
EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
|
|
EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
|
|
EXPECT_EQ(inst->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
|
|
|
|
Instruction* before_100 = nullptr;
|
|
for (auto it = context->module()->ext_inst_debuginfo_begin();
|
|
it != context->module()->ext_inst_debuginfo_end(); ++it) {
|
|
if (it->result_id() == 100) break;
|
|
before_100 = &*it;
|
|
}
|
|
EXPECT_NE(inst, before_100);
|
|
|
|
inst = manager.CloneDebugInlinedAt(100, manager.GetDebugInlinedAt(100));
|
|
EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
|
|
EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
|
|
EXPECT_EQ(inst->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
|
|
|
|
before_100 = nullptr;
|
|
for (auto it = context->module()->ext_inst_debuginfo_begin();
|
|
it != context->module()->ext_inst_debuginfo_end(); ++it) {
|
|
if (it->result_id() == 100) break;
|
|
before_100 = &*it;
|
|
}
|
|
EXPECT_EQ(inst, before_100);
|
|
}
|
|
|
|
TEST(DebugInfoManager, KillDebugDeclares) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%12 = OpExtInst %void %1 DebugInfoNone
|
|
%25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%100 = OpVariable %_ptr_Function_float Function
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
OpStore %100 %31
|
|
%36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
%37 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
%38 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
auto* dbg_info_mgr = context->get_debug_info_mgr();
|
|
auto* def_use_mgr = context->get_def_use_mgr();
|
|
|
|
EXPECT_TRUE(dbg_info_mgr->IsVariableDebugDeclared(100));
|
|
EXPECT_EQ(def_use_mgr->GetDef(36)->GetOpenCL100DebugOpcode(),
|
|
OpenCLDebugInfo100DebugDeclare);
|
|
EXPECT_EQ(def_use_mgr->GetDef(37)->GetOpenCL100DebugOpcode(),
|
|
OpenCLDebugInfo100DebugDeclare);
|
|
EXPECT_EQ(def_use_mgr->GetDef(38)->GetOpenCL100DebugOpcode(),
|
|
OpenCLDebugInfo100DebugDeclare);
|
|
|
|
dbg_info_mgr->KillDebugDeclares(100);
|
|
EXPECT_EQ(def_use_mgr->GetDef(36), nullptr);
|
|
EXPECT_EQ(def_use_mgr->GetDef(37), nullptr);
|
|
EXPECT_EQ(def_use_mgr->GetDef(38), nullptr);
|
|
EXPECT_FALSE(dbg_info_mgr->IsVariableDebugDeclared(100));
|
|
}
|
|
|
|
TEST(DebugInfoManager, AddDebugValueForDecl) {
|
|
const std::string text = R"(
|
|
OpCapability Shader
|
|
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %in_var_COLOR
|
|
OpExecutionMode %main OriginUpperLeft
|
|
%5 = OpString "ps.hlsl"
|
|
%14 = OpString "#line 1 \"ps.hlsl\"
|
|
void main(float in_var_color : COLOR) {
|
|
float color = in_var_color;
|
|
}
|
|
"
|
|
%17 = OpString "float"
|
|
%21 = OpString "main"
|
|
%24 = OpString "color"
|
|
OpName %in_var_COLOR "in.var.COLOR"
|
|
OpName %main "main"
|
|
OpDecorate %in_var_COLOR Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_32 = OpConstant %uint 32
|
|
%float = OpTypeFloat 32
|
|
%_ptr_Input_float = OpTypePointer Input %float
|
|
%void = OpTypeVoid
|
|
%27 = OpTypeFunction %void
|
|
%_ptr_Function_float = OpTypePointer Function %float
|
|
%in_var_COLOR = OpVariable %_ptr_Input_float Input
|
|
%13 = OpExtInst %void %1 DebugExpression
|
|
%15 = OpExtInst %void %1 DebugSource %5 %14
|
|
%16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
|
|
%18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
|
|
%20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
|
|
%22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
|
|
%12 = OpExtInst %void %1 DebugInfoNone
|
|
%25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
|
|
%main = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%100 = OpVariable %_ptr_Function_float Function
|
|
%31 = OpLoad %float %in_var_COLOR
|
|
%101 = OpExtInst %void %1 DebugScope %22
|
|
OpLine %5 13 7
|
|
OpStore %100 %31
|
|
OpNoLine
|
|
%102 = OpExtInst %void %1 DebugNoScope
|
|
%36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
|
|
std::unique_ptr<IRContext> context =
|
|
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
|
|
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
|
auto* def_use_mgr = context->get_def_use_mgr();
|
|
auto* dbg_decl = def_use_mgr->GetDef(36);
|
|
EXPECT_EQ(dbg_decl->GetOpenCL100DebugOpcode(),
|
|
OpenCLDebugInfo100DebugDeclare);
|
|
|
|
auto* dbg_info_mgr = context->get_debug_info_mgr();
|
|
Instruction* store = dbg_decl->PreviousNode();
|
|
auto* dbg_value =
|
|
dbg_info_mgr->AddDebugValueForDecl(dbg_decl, 100, dbg_decl, store);
|
|
|
|
EXPECT_EQ(dbg_value->GetOpenCL100DebugOpcode(), OpenCLDebugInfo100DebugValue);
|
|
EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
|
|
kOpLineInOperandFileIndex),
|
|
5);
|
|
EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
|
|
kOpLineInOperandLineIndex),
|
|
13);
|
|
EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
|
|
kOpLineInOperandColumnIndex),
|
|
7);
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace analysis
|
|
} // namespace opt
|
|
} // namespace spvtools
|