[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:
Jaebaek Seo 2020-11-02 14:11:29 -05:00 коммит произвёл GitHub
Родитель 075d3ce9ef
Коммит 8fea615e3c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 59 добавлений и 31 удалений

2
external/SPIRV-Headers поставляемый

@ -1 +1 @@
Subproject commit c43a43c7cc3af55910b9bec2a71e3e8a622443cf
Subproject commit 05836bdba63e7debce9fa9feaed42f20cd43af9d

2
external/SPIRV-Tools поставляемый

@ -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