mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-27 01:21:25 +00:00
Add DebugValue for invisible store in single_store_elim (#4002)
The front-end language compiler would simply emit DebugDeclare for
a variable when it is declared, which is effective through the variable's
scope. Since DebugDeclare only maps an OpVariable to a local variable,
the information can be removed when an optimization pass uses the
loaded value of the variable. DebugValue can be used to specify the
value of a variable. For each value update or phi instruction of a variable,
we can add DebugValue to help debugger inspect the variable at any
point of the program execution.
For example,
float a = 3;
... (complicated cfg) ...
foo(a); // <-- variable inspection: debugger can find DebugValue of `float a` in the nearest dominant
For the code with complicated CFG e.g., for-loop, if-statement, we
need help of ssa-rewrite to analyze the effective value of each variable
in each basic block.
If the value update of the variable happens only once and it dominates
all its uses, local-single-store-elim pass conducts the same value update
with ssa-rewrite and we have to let it add DebugValue for the value assignment.
One main issue is that we have to add DebugValue only when the value
update of a variable is visible to DebugDeclare. For example,
```
{ // scope1
%stack = OpVariable %ptr_int %int_3
{ // scope2
DebugDeclare %foo %stack <-- local variable "foo" in high-level language source code is declared as OpVariable "%stack"
// add DebugValue "foo = 3"
...
Store %stack %int_7 <-- foo = 7, add DebugValue "foo = 7"
...
// debugger can inspect the value of "foo"
}
Store %stack %int_11 <-- out of "scope2" i.e., scope of "foo". DO NOT add DebugValue "foo = 11"
}
```
However, the initalization of a variable is an exception.
For example, an argument passing of an inlined function must be done out of
the function's scope, but we must add a DebugValue for it.
```
// in HLSL
bar(float arg) { ... }
...
float foo = 3;
bar(foo);
// in SPIR-V
%arg = OpVariable
OpStore %arg %foo <-- Argument passing. Out of "float arg" scope, but we must add DebugValue for "float arg"
... body of function bar(float arg) ...
```
This PR handles the except case in local-single-store-elim pass. It adds
DebugValue for a store that is considered as an initialization.
The same exception handling code for ssa-rewrite is done by this commit: df4198e50e
.
This commit is contained in:
parent
c74d5523bb
commit
c2b2b57885
@ -384,7 +384,8 @@ bool DebugInfoManager::IsVariableDebugDeclared(uint32_t variable_id) {
|
||||
return dbg_decl_itr != var_id_to_dbg_decl_.end();
|
||||
}
|
||||
|
||||
void DebugInfoManager::KillDebugDeclares(uint32_t variable_id) {
|
||||
bool DebugInfoManager::KillDebugDeclares(uint32_t variable_id) {
|
||||
bool modified = false;
|
||||
auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id);
|
||||
if (dbg_decl_itr != var_id_to_dbg_decl_.end()) {
|
||||
// We intentionally copy the list of DebugDeclare instructions because
|
||||
@ -394,9 +395,11 @@ void DebugInfoManager::KillDebugDeclares(uint32_t variable_id) {
|
||||
|
||||
for (auto* dbg_decl : copy_dbg_decls) {
|
||||
context()->KillInst(dbg_decl);
|
||||
modified = true;
|
||||
}
|
||||
var_id_to_dbg_decl_.erase(dbg_decl_itr);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
uint32_t DebugInfoManager::GetParentScope(uint32_t child_scope) {
|
||||
@ -514,16 +517,18 @@ Instruction* DebugInfoManager::AddDebugValueWithIndex(
|
||||
return added_dbg_value;
|
||||
}
|
||||
|
||||
void DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
bool DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
Instruction* scope_and_line, uint32_t variable_id, uint32_t value_id,
|
||||
Instruction* insert_pos,
|
||||
std::unordered_set<Instruction*>* invisible_decls) {
|
||||
auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id);
|
||||
if (dbg_decl_itr == var_id_to_dbg_decl_.end()) return;
|
||||
assert(scope_and_line != nullptr);
|
||||
|
||||
auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id);
|
||||
if (dbg_decl_itr == var_id_to_dbg_decl_.end()) return false;
|
||||
|
||||
bool modified = false;
|
||||
for (auto* dbg_decl_or_val : dbg_decl_itr->second) {
|
||||
if (scope_and_line &&
|
||||
!IsDeclareVisibleToInstr(dbg_decl_or_val, scope_and_line)) {
|
||||
if (!IsDeclareVisibleToInstr(dbg_decl_or_val, scope_and_line)) {
|
||||
if (invisible_decls) invisible_decls->insert(dbg_decl_or_val);
|
||||
continue;
|
||||
}
|
||||
@ -547,10 +552,11 @@ void DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
kDebugValueOperandLocalVariableIndex),
|
||||
value_id, 0, index_id, insert_before);
|
||||
assert(added_dbg_value != nullptr);
|
||||
added_dbg_value->UpdateDebugInfoFrom(scope_and_line ? scope_and_line
|
||||
: dbg_decl_or_val);
|
||||
added_dbg_value->UpdateDebugInfoFrom(scope_and_line);
|
||||
AnalyzeDebugInst(added_dbg_value);
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool DebugInfoManager::AddDebugValueForDecl(Instruction* dbg_decl,
|
||||
|
@ -138,14 +138,15 @@ class DebugInfoManager {
|
||||
bool IsVariableDebugDeclared(uint32_t variable_id);
|
||||
|
||||
// Kills all debug declaration instructions with Deref whose 'Local Variable'
|
||||
// operand is |variable_id|.
|
||||
void KillDebugDeclares(uint32_t variable_id);
|
||||
// operand is |variable_id|. Returns whether it kills an instruction or not.
|
||||
bool KillDebugDeclares(uint32_t variable_id);
|
||||
|
||||
// Generates a DebugValue instruction with value |value_id| for every local
|
||||
// variable that is in the scope of |scope_and_line| and whose memory is
|
||||
// |variable_id| and inserts it after the instruction |insert_pos|.
|
||||
// |invisible_decls| returns DebugDeclares invisible to |scope_and_line|.
|
||||
void AddDebugValueIfVarDeclIsVisible(
|
||||
// Returns whether a DebugValue is added or not. |invisible_decls| returns
|
||||
// DebugDeclares invisible to |scope_and_line|.
|
||||
bool AddDebugValueIfVarDeclIsVisible(
|
||||
Instruction* scope_and_line, uint32_t variable_id, uint32_t value_id,
|
||||
Instruction* insert_pos,
|
||||
std::unordered_set<Instruction*>* invisible_decls);
|
||||
|
@ -148,16 +148,41 @@ bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
|
||||
context()->get_type_mgr()->GetType(var_inst->type_id());
|
||||
const analysis::Type* store_type = var_type->AsPointer()->pointee_type();
|
||||
if (!(store_type->AsStruct() || store_type->AsArray())) {
|
||||
context()->get_debug_info_mgr()->AddDebugValueIfVarDeclIsVisible(
|
||||
nullptr, var_id, store_inst->GetSingleWordInOperand(1), store_inst,
|
||||
nullptr);
|
||||
context()->get_debug_info_mgr()->KillDebugDeclares(var_id);
|
||||
modified |= RewriteDebugDeclares(store_inst, var_id);
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool LocalSingleStoreElimPass::RewriteDebugDeclares(Instruction* store_inst,
|
||||
uint32_t var_id) {
|
||||
std::unordered_set<Instruction*> invisible_decls;
|
||||
uint32_t value_id = store_inst->GetSingleWordInOperand(1);
|
||||
bool modified =
|
||||
context()->get_debug_info_mgr()->AddDebugValueIfVarDeclIsVisible(
|
||||
store_inst, var_id, value_id, store_inst, &invisible_decls);
|
||||
|
||||
// For cases like the argument passing for an inlined function, the value
|
||||
// assignment is out of DebugDeclare's scope, but we have to preserve the
|
||||
// value assignment information using DebugValue. Generally, we need
|
||||
// ssa-rewrite analysis to decide a proper value assignment but at this point
|
||||
// we confirm that |var_id| has a single store. We can safely add DebugValue.
|
||||
if (!invisible_decls.empty()) {
|
||||
BasicBlock* store_block = context()->get_instr_block(store_inst);
|
||||
DominatorAnalysis* dominator_analysis =
|
||||
context()->GetDominatorAnalysis(store_block->GetParent());
|
||||
for (auto* decl : invisible_decls) {
|
||||
if (dominator_analysis->Dominates(store_inst, decl)) {
|
||||
context()->get_debug_info_mgr()->AddDebugValueForDecl(decl, value_id);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
modified |= context()->get_debug_info_mgr()->KillDebugDeclares(var_id);
|
||||
return modified;
|
||||
}
|
||||
|
||||
Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses(
|
||||
Instruction* var_inst, const std::vector<Instruction*>& users) const {
|
||||
// Make sure there is exactly 1 store.
|
||||
|
@ -94,6 +94,10 @@ class LocalSingleStoreElimPass : public Pass {
|
||||
bool RewriteLoads(Instruction* store_inst,
|
||||
const std::vector<Instruction*>& uses, bool* all_rewritten);
|
||||
|
||||
// Replaces DebugDeclares of |var_id| with DebugValues using the value
|
||||
// assignment of |store_inst|.
|
||||
bool RewriteDebugDeclares(Instruction* store_inst, uint32_t var_id);
|
||||
|
||||
// Extensions supported by this pass.
|
||||
std::unordered_set<std::string> extensions_allowlist_;
|
||||
};
|
||||
|
@ -1211,6 +1211,237 @@ TEST_F(LocalSingleStoreElimTest, DebugValueTest) {
|
||||
SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, UseStoreLineInfoForDebugValueLine) {
|
||||
// When the store is in the scope of OpenCL.DebugInfo.100 DebugDeclare,
|
||||
// the OpLine of the added OpenCL.DebugInfo.100 DebugValue must be the
|
||||
// same with the OpLine of the store.
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
|
||||
%7 = OpString "simple.hlsl"
|
||||
%8 = OpString "float"
|
||||
%9 = OpString "VS_OUTPUT"
|
||||
%10 = OpString "color"
|
||||
%11 = OpString "pos"
|
||||
%12 = OpString "main"
|
||||
%13 = OpString ""
|
||||
%14 = OpString "vout"
|
||||
OpName %in_var_POSITION "in.var.POSITION"
|
||||
OpName %in_var_COLOR "in.var.COLOR"
|
||||
OpName %out_var_COLOR "out.var.COLOR"
|
||||
OpName %main "main"
|
||||
OpName %VS_OUTPUT "VS_OUTPUT"
|
||||
OpMemberName %VS_OUTPUT 0 "pos"
|
||||
OpMemberName %VS_OUTPUT 1 "color"
|
||||
OpDecorate %gl_Position BuiltIn Position
|
||||
OpDecorate %in_var_POSITION Location 0
|
||||
OpDecorate %in_var_COLOR Location 1
|
||||
OpDecorate %out_var_COLOR Location 0
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_32 = OpConstant %uint 32
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_ptr_Input_v4float = OpTypePointer Input %v4float
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%void = OpTypeVoid
|
||||
%uint_256 = OpConstant %uint 256
|
||||
%uint_128 = OpConstant %uint 128
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%36 = OpTypeFunction %void
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%VS_OUTPUT = OpTypeStruct %v4float %v4float
|
||||
%_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
|
||||
%in_var_POSITION = OpVariable %_ptr_Input_v4float Input
|
||||
%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
|
||||
%gl_Position = OpVariable %_ptr_Output_v4float Output
|
||||
%out_var_COLOR = OpVariable %_ptr_Output_v4float Output
|
||||
%85 = OpExtInst %void %1 DebugOperation Deref
|
||||
%81 = OpExtInst %void %1 DebugInfoNone
|
||||
%52 = OpExtInst %void %1 DebugExpression
|
||||
%40 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
|
||||
%41 = OpExtInst %void %1 DebugTypeVector %40 4
|
||||
%42 = OpExtInst %void %1 DebugSource %7
|
||||
%43 = OpExtInst %void %1 DebugCompilationUnit 1 4 %42 HLSL
|
||||
%44 = OpExtInst %void %1 DebugTypeComposite %9 Structure %42 1 8 %43 %9 %uint_256 FlagIsProtected|FlagIsPrivate %45 %46
|
||||
%46 = OpExtInst %void %1 DebugTypeMember %10 %41 %42 3 10 %44 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
|
||||
%45 = OpExtInst %void %1 DebugTypeMember %11 %41 %42 2 10 %44 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
|
||||
%47 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %44 %41 %41
|
||||
%48 = OpExtInst %void %1 DebugFunction %12 %47 %42 6 1 %43 %13 FlagIsProtected|FlagIsPrivate 7 %81
|
||||
%49 = OpExtInst %void %1 DebugLexicalBlock %42 7 38 %48
|
||||
%50 = OpExtInst %void %1 DebugLocalVariable %14 %44 %42 8 13 %49 FlagIsLocal
|
||||
%84 = OpExtInst %void %1 DebugExpression %85
|
||||
%main = OpFunction %void None %36
|
||||
%54 = OpLabel
|
||||
%91 = OpExtInst %void %1 DebugScope %49
|
||||
OpLine %7 7 23
|
||||
%83 = OpVariable %_ptr_Function_v4float Function
|
||||
OpLine %7 8 13
|
||||
%87 = OpExtInst %void %1 DebugValue %50 %83 %84 %int_1
|
||||
OpLine %7 7 23
|
||||
%82 = OpVariable %_ptr_Function_v4float Function
|
||||
OpLine %7 8 13
|
||||
%86 = OpExtInst %void %1 DebugValue %50 %82 %84 %int_0
|
||||
OpNoLine
|
||||
%92 = OpExtInst %void %1 DebugNoScope
|
||||
%55 = OpLoad %v4float %in_var_POSITION
|
||||
%56 = OpLoad %v4float %in_var_COLOR
|
||||
;CHECK: [[pos:%\w+]] = OpLoad %v4float %in_var_POSITION
|
||||
;CHECK: [[color:%\w+]] = OpLoad %v4float %in_var_COLOR
|
||||
|
||||
%94 = OpExtInst %void %1 DebugScope %49
|
||||
OpLine %7 9 3
|
||||
OpStore %82 %55
|
||||
;CHECK: OpLine [[file:%\w+]] 9 3
|
||||
;CHECK: OpStore {{%\w+}} [[pos]]
|
||||
;CHECK: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[vout:%\w+]] [[pos]] [[empty_expr:%\w+]] %int_0
|
||||
;CHECK: OpLine [[file]] 10 3
|
||||
;CHECK: OpStore {{%\w+}} [[color]]
|
||||
;CHECK: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[vout]] [[color]] [[empty_expr]] %int_1
|
||||
|
||||
OpLine %7 10 3
|
||||
OpStore %83 %56
|
||||
OpLine %7 11 10
|
||||
%90 = OpCompositeConstruct %VS_OUTPUT %55 %56
|
||||
OpNoLine
|
||||
%95 = OpExtInst %void %1 DebugNoScope
|
||||
%58 = OpCompositeExtract %v4float %90 0
|
||||
OpStore %gl_Position %58
|
||||
%59 = OpCompositeExtract %v4float %90 1
|
||||
OpStore %out_var_COLOR %59
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, AddDebugValueforStoreOutOfDebugDeclareScope) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
|
||||
%7 = OpString "simple.hlsl"
|
||||
%8 = OpString "float"
|
||||
%9 = OpString "VS_OUTPUT"
|
||||
%10 = OpString "color"
|
||||
%11 = OpString "pos"
|
||||
%12 = OpString "main"
|
||||
%13 = OpString ""
|
||||
%14 = OpString "vout"
|
||||
OpName %in_var_POSITION "in.var.POSITION"
|
||||
OpName %in_var_COLOR "in.var.COLOR"
|
||||
OpName %out_var_COLOR "out.var.COLOR"
|
||||
OpName %main "main"
|
||||
OpName %VS_OUTPUT "VS_OUTPUT"
|
||||
OpMemberName %VS_OUTPUT 0 "pos"
|
||||
OpMemberName %VS_OUTPUT 1 "color"
|
||||
OpDecorate %gl_Position BuiltIn Position
|
||||
OpDecorate %in_var_POSITION Location 0
|
||||
OpDecorate %in_var_COLOR Location 1
|
||||
OpDecorate %out_var_COLOR Location 0
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_32 = OpConstant %uint 32
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_ptr_Input_v4float = OpTypePointer Input %v4float
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%void = OpTypeVoid
|
||||
%uint_256 = OpConstant %uint 256
|
||||
%uint_128 = OpConstant %uint 128
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%36 = OpTypeFunction %void
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%VS_OUTPUT = OpTypeStruct %v4float %v4float
|
||||
%_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
|
||||
%in_var_POSITION = OpVariable %_ptr_Input_v4float Input
|
||||
%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
|
||||
%gl_Position = OpVariable %_ptr_Output_v4float Output
|
||||
%out_var_COLOR = OpVariable %_ptr_Output_v4float Output
|
||||
%85 = OpExtInst %void %1 DebugOperation Deref
|
||||
%81 = OpExtInst %void %1 DebugInfoNone
|
||||
%52 = OpExtInst %void %1 DebugExpression
|
||||
%40 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
|
||||
%41 = OpExtInst %void %1 DebugTypeVector %40 4
|
||||
%42 = OpExtInst %void %1 DebugSource %7
|
||||
%43 = OpExtInst %void %1 DebugCompilationUnit 1 4 %42 HLSL
|
||||
%44 = OpExtInst %void %1 DebugTypeComposite %9 Structure %42 1 8 %43 %9 %uint_256 FlagIsProtected|FlagIsPrivate %45 %46
|
||||
%46 = OpExtInst %void %1 DebugTypeMember %10 %41 %42 3 10 %44 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
|
||||
%45 = OpExtInst %void %1 DebugTypeMember %11 %41 %42 2 10 %44 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
|
||||
%47 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %44 %41 %41
|
||||
%48 = OpExtInst %void %1 DebugFunction %12 %47 %42 6 1 %43 %13 FlagIsProtected|FlagIsPrivate 7 %81
|
||||
%49 = OpExtInst %void %1 DebugLexicalBlock %42 7 38 %48
|
||||
%50 = OpExtInst %void %1 DebugLocalVariable %14 %44 %42 8 13 %49 FlagIsLocal
|
||||
%51 = OpExtInst %void %1 DebugLocalVariable %10 %41 %42 7 23 %48 FlagIsLocal 2
|
||||
%53 = OpExtInst %void %1 DebugLocalVariable %11 %41 %42 6 23 %48 FlagIsLocal 1
|
||||
;CHECK: [[dbg_color:%\w+]] = OpExtInst %void {{%\w+}} DebugLocalVariable {{%\w+}} {{%\w+}} {{%\w+}} 7 23 {{%\w+}} FlagIsLocal 2
|
||||
;CHECK: [[dbg_pos:%\w+]] = OpExtInst %void {{%\w+}} DebugLocalVariable {{%\w+}} {{%\w+}} {{%\w+}} 6 23 {{%\w+}} FlagIsLocal 1
|
||||
|
||||
%84 = OpExtInst %void %1 DebugExpression %85
|
||||
%main = OpFunction %void None %36
|
||||
%54 = OpLabel
|
||||
%91 = OpExtInst %void %1 DebugScope %49
|
||||
OpLine %7 7 23
|
||||
%83 = OpVariable %_ptr_Function_v4float Function
|
||||
OpLine %7 8 13
|
||||
%87 = OpExtInst %void %1 DebugValue %50 %83 %84 %int_1
|
||||
OpLine %7 7 23
|
||||
%82 = OpVariable %_ptr_Function_v4float Function
|
||||
OpLine %7 8 13
|
||||
%86 = OpExtInst %void %1 DebugValue %50 %82 %84 %int_0
|
||||
OpNoLine
|
||||
%92 = OpExtInst %void %1 DebugNoScope
|
||||
%param_var_pos = OpVariable %_ptr_Function_v4float Function
|
||||
%param_var_color = OpVariable %_ptr_Function_v4float Function
|
||||
%55 = OpLoad %v4float %in_var_POSITION
|
||||
OpStore %param_var_pos %55
|
||||
%56 = OpLoad %v4float %in_var_COLOR
|
||||
;CHECK: DebugNoScope
|
||||
;CHECK-NOT: OpLine
|
||||
;CHECK: [[pos:%\w+]] = OpLoad %v4float %in_var_POSITION
|
||||
;CHECK: [[color:%\w+]] = OpLoad %v4float %in_var_COLOR
|
||||
|
||||
OpStore %param_var_color %56
|
||||
%93 = OpExtInst %void %1 DebugScope %48
|
||||
OpLine %7 6 23
|
||||
%73 = OpExtInst %void %1 DebugDeclare %53 %param_var_pos %52
|
||||
OpLine %7 7 23
|
||||
%74 = OpExtInst %void %1 DebugDeclare %51 %param_var_color %52
|
||||
;CHECK: OpLine [[file:%\w+]] 6 23
|
||||
;CHECK-NEXT: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[dbg_pos]] [[pos]] [[empty_expr:%\w+]]
|
||||
;CHECK: OpLine [[file]] 7 23
|
||||
;CHECK-NEXT: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue [[dbg_color]] [[color]] [[empty_expr]]
|
||||
|
||||
%94 = OpExtInst %void %1 DebugScope %49
|
||||
OpLine %7 9 3
|
||||
OpStore %82 %55
|
||||
OpLine %7 10 3
|
||||
OpStore %83 %56
|
||||
OpLine %7 11 10
|
||||
%90 = OpCompositeConstruct %VS_OUTPUT %55 %56
|
||||
OpNoLine
|
||||
%95 = OpExtInst %void %1 DebugNoScope
|
||||
%58 = OpCompositeExtract %v4float %90 0
|
||||
OpStore %gl_Position %58
|
||||
%59 = OpCompositeExtract %v4float %90 1
|
||||
OpStore %out_var_COLOR %59
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false);
|
||||
}
|
||||
|
||||
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
||||
//
|
||||
// Other types
|
||||
|
Loading…
Reference in New Issue
Block a user