[spirv] wrap instructions with OpNoLine (#3229)
The current DXC emits `OpLine` for the first instruction in the location and does not emit the same `OpLine` for the following instructions. However, it does not specify the end of the effectiveness of the `OpLine`, which is technically wrong based on the spec of OpLine and OpNoLine. We have to specify the `OpLine` is not applied to the following instructions when we meet an instruction without the location information.
This commit is contained in:
Родитель
075d3ce9ef
Коммит
8fea615e3c
|
@ -1 +1 @@
|
|||
Subproject commit c43a43c7cc3af55910b9bec2a71e3e8a622443cf
|
||||
Subproject commit 05836bdba63e7debce9fa9feaed42f20cd43af9d
|
|
@ -1 +1 @@
|
|||
Subproject commit 5c64374dd6cbfff1294ec78cdae1bc9de870a07d
|
||||
Subproject commit 82b378d671836b51343b010ca9ec32db14485147
|
|
@ -202,7 +202,8 @@ void EmitVisitor::emitDebugNameForInstruction(uint32_t resultId,
|
|||
}
|
||||
|
||||
void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc,
|
||||
std::vector<uint32_t> *section) {
|
||||
std::vector<uint32_t> *section,
|
||||
bool isDebugScope) {
|
||||
if (!spvOptions.debugInfoLine)
|
||||
return;
|
||||
|
||||
|
@ -217,6 +218,8 @@ void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc,
|
|||
// immediately precede either an OpBranch or OpBranchConditional instruction.
|
||||
if (lastOpWasMergeInst) {
|
||||
lastOpWasMergeInst = false;
|
||||
debugLine = 0;
|
||||
debugColumn = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -233,29 +236,53 @@ void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc,
|
|||
if (op == spv::Op::OpVariable)
|
||||
return;
|
||||
|
||||
// If no SourceLocation is provided, we have to emit OpNoLine to
|
||||
// specify the previous OpLine is not applied to this instruction.
|
||||
if (loc == SourceLocation()) {
|
||||
if (!isDebugScope && (debugLine != 0 || debugColumn != 0)) {
|
||||
curInst.clear();
|
||||
curInst.push_back(static_cast<uint32_t>(spv::Op::OpNoLine));
|
||||
curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
|
||||
section->insert(section->end(), curInst.begin(), curInst.end());
|
||||
}
|
||||
debugLine = 0;
|
||||
debugColumn = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
auto fileId = debugMainFileId;
|
||||
const auto &sm = astContext.getSourceManager();
|
||||
const char *fileName = sm.getPresumedLoc(loc).getFilename();
|
||||
if (fileName)
|
||||
fileId = getOrCreateOpStringId(fileName);
|
||||
|
||||
if (!fileId)
|
||||
return;
|
||||
|
||||
uint32_t line = sm.getPresumedLineNumber(loc);
|
||||
uint32_t column = sm.getPresumedColumnNumber(loc);
|
||||
|
||||
if (!line || !column)
|
||||
return;
|
||||
// If it is a terminator, just reset the last line and column because
|
||||
// a terminator makes the OpLine not effective.
|
||||
bool resetLine = (op >= spv::Op::OpBranch && op <= spv::Op::OpUnreachable) ||
|
||||
op == spv::Op::OpTerminateInvocation;
|
||||
|
||||
if (line == debugLine && column == debugColumn)
|
||||
if (!fileId || !line || !column ||
|
||||
(line == debugLine && column == debugColumn)) {
|
||||
if (resetLine) {
|
||||
debugLine = 0;
|
||||
debugColumn = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
assert(section);
|
||||
|
||||
// We must update these two values to emit the next Opline.
|
||||
debugLine = line;
|
||||
debugColumn = column;
|
||||
if (resetLine) {
|
||||
debugLine = 0;
|
||||
debugColumn = 0;
|
||||
} else {
|
||||
// Keep the last line and column to avoid printing the duplicated OpLine.
|
||||
debugLine = line;
|
||||
debugColumn = column;
|
||||
}
|
||||
|
||||
curInst.clear();
|
||||
curInst.push_back(static_cast<uint32_t>(spv::Op::OpLine));
|
||||
|
@ -312,7 +339,8 @@ void EmitVisitor::initInstruction(SpirvInstruction *inst) {
|
|||
isGlobalVar = var->getStorageClass() != spv::StorageClass::Function;
|
||||
const auto op = inst->getopcode();
|
||||
emitDebugLine(op, inst->getSourceLocation(),
|
||||
isGlobalVar ? &globalVarsBinary : &mainBinary);
|
||||
isGlobalVar ? &globalVarsBinary : &mainBinary,
|
||||
isa<SpirvDebugScope>(inst));
|
||||
|
||||
// Initialize the current instruction for emitting.
|
||||
curInst.clear();
|
||||
|
|
|
@ -312,7 +312,7 @@ private:
|
|||
// Emits an OpLine instruction for the given operation into the given binary
|
||||
// section.
|
||||
void emitDebugLine(spv::Op op, const SourceLocation &loc,
|
||||
std::vector<uint32_t> *section);
|
||||
std::vector<uint32_t> *section, bool isDebugScope = false);
|
||||
|
||||
// Initiates the creation of a new instruction with the given Opcode.
|
||||
void initInstruction(spv::Op, const SourceLocation &);
|
||||
|
|
|
@ -9,16 +9,16 @@
|
|||
// CHECK: [[expr:%\d+]] = OpExtInst %void [[set]] DebugExpression
|
||||
// CHECK: [[color:%\d+]] = OpExtInst %void [[set]] DebugLocalVariable {{%\d+}} {{%\d+}} {{%\d+}} 28 20 {{%\d+}} FlagIsLocal 1
|
||||
|
||||
// CHECK: %color = OpFunctionParameter
|
||||
// CHECK-NEXT: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[color]] %color [[expr]]
|
||||
// CHECK: %condition = OpVariable
|
||||
// CHECK: OpStore %condition %false
|
||||
// CHECK-NEXT: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[condition]] %condition [[expr]]
|
||||
// CHECK: %color = OpFunctionParameter
|
||||
// CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[color]] %color [[expr]]
|
||||
// CHECK: %condition = OpVariable
|
||||
// CHECK: OpStore %condition %false
|
||||
// CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[condition]] %condition [[expr]]
|
||||
|
||||
// CHECK: %x = OpFunctionParameter
|
||||
// CHECK: %y = OpFunctionParameter
|
||||
// CHECK-NEXT: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[x]] %x [[expr]]
|
||||
// CHECK-NEXT: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[y]] %y [[expr]]
|
||||
// CHECK: %x = OpFunctionParameter
|
||||
// CHECK: %y = OpFunctionParameter
|
||||
// CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[x]] %x [[expr]]
|
||||
// CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugDeclare [[y]] %y [[expr]]
|
||||
|
||||
void foo(int x, float y)
|
||||
{
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// Run: %dxc -T ps_6_0 -E main -fspv-debug=rich
|
||||
|
||||
// CHECK: %i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
// CHECK-NEXT: DebugDeclare {{%\d+}} %i
|
||||
// CHECK: %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
// CHECK: %c = OpVariable %_ptr_Function_v4float Function
|
||||
// CHECK: DebugDeclare {{%\d+}} %ps_output
|
||||
// CHECK: DebugDeclare {{%\d+}} %c
|
||||
// CHECK: %i = OpFunctionParameter %_ptr_Function_PS_INPUT
|
||||
// CHECK: DebugDeclare {{%\d+}} %i
|
||||
// CHECK: %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
|
||||
// CHECK: %c = OpVariable %_ptr_Function_v4float Function
|
||||
// CHECK: DebugDeclare {{%\d+}} %ps_output
|
||||
// CHECK: DebugDeclare {{%\d+}} %c
|
||||
|
||||
Texture2D g_tColor;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ VS_OUTPUT main(float4 pos : POSITION,
|
|||
//CHECK: DebugScope [[bb2]]
|
||||
//CHECK-NEXT: OpLine [[file:%\d+]] 32
|
||||
//CHECK-NEXT: OpStore [[var_a:%\w+]] %float_6
|
||||
//CHECK-NEXT: DebugDeclare [[a]] [[var_a]]
|
||||
//CHECK: DebugDeclare [[a]] [[var_a]]
|
||||
float a = 6.0;
|
||||
x += a + b + c;
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ void main() {
|
|||
// CHECK: OpLine [[file]] 57 3
|
||||
// CHECK-NEXT: OpBranch %while_continue
|
||||
// CHECK-NEXT: %while_continue = OpLabel
|
||||
// CHECK-NEXT: OpLine [[file]] 57 3
|
||||
// CHECK-NEXT: OpBranch %while_check
|
||||
// CHECK-NEXT: %while_merge = OpLabel
|
||||
}
|
||||
|
||||
// CHECK: OpLine [[file]] 61 19
|
||||
|
|
Загрузка…
Ссылка в новой задаче