Skip to content

Commit

Permalink
llpc/dbginfo: correctly handle DebugFunction
Browse files Browse the repository at this point in the history
Be honest about the operands of DebugFunction when reading the SPIR-V
and cleanly handle the fact that (unlike in the OpenCL debug info) the
DebugFunction instruction doesn't reference the OpFunction at all.
Setting the LLVM debug metadata can only be done after reading the
DebugFunctionDefinition instruction which links the two.
  • Loading branch information
nhaehnle committed Nov 8, 2023
1 parent 0478fde commit 2a6f20f
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 27 deletions.
149 changes: 149 additions & 0 deletions llpc/test/shaderdb/debug_info/FunctionCall.pipe
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
; RUN: amdllpc -trim-debug-info=false -filetype=asm -o - -gfxip 11.0 %s | FileCheck -check-prefixes=NOTRIM %s

; Just a simple sanity check that the compiler ran through and produced *some* debug info
; NOTRIM: .loc 1 11 0 prologue_end

[CsSpirv]
; Compiled with glslangValidator --target-env vulkan1.3 -gVS
; SPIR-V
; Version: 1.6
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 88
; Schema: 0
OpCapability Shader
OpExtension "SPV_KHR_non_semantic_info"
%2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
%3 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main" %dst %gl_GlobalInvocationID
OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
%1 = OpString "simplified.comp"
%9 = OpString "uint"
%15 = OpString "main"
%18 = OpString "#version 460

layout(set = 0, binding = 0, r32ui) uniform uimage2D dst;

uint BugFunction(uint val0) {
return val0;
}

void main() {
uvec4 data = uvec4(BugFunction(0));
imageStore(dst, ivec2(gl_GlobalInvocationID.xy), data);
}
"
%29 = OpString "BugFunction"
%35 = OpString "val0"
%53 = OpString "data"
%62 = OpString "type.2d.image"
%63 = OpString "@type.2d.image"
%68 = OpString "dst"
%76 = OpString "gl_GlobalInvocationID"
%82 = OpString "int"
OpName %main "main"
OpName %BugFunction_u1_ "BugFunction(u1;"
OpName %val0 "val0"
OpName %data "data"
OpName %param "param"
OpName %dst "dst"
OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
OpModuleProcessed "client vulkan100"
OpModuleProcessed "target-env spirv1.6"
OpModuleProcessed "target-env vulkan1.3"
OpModuleProcessed "entry-point main"
OpDecorate %dst DescriptorSet 0
OpDecorate %dst Binding 0
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
%void = OpTypeVoid
%5 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%uint_6 = OpConstant %uint 6
%uint_0 = OpConstant %uint 0
%8 = OpExtInst %void %2 DebugTypeBasic %9 %uint_32 %uint_6 %uint_0
%uint_3 = OpConstant %uint 3
%6 = OpExtInst %void %2 DebugTypeFunction %uint_3 %void
%17 = OpExtInst %void %2 DebugSource %1 %18
%uint_1 = OpConstant %uint 1
%uint_4 = OpConstant %uint 4
%uint_2 = OpConstant %uint 2
%19 = OpExtInst %void %2 DebugCompilationUnit %uint_1 %uint_4 %17 %uint_2
%16 = OpExtInst %void %2 DebugFunction %15 %6 %17 %uint_0 %uint_0 %19 %15 %uint_3 %uint_0
%_ptr_Function_uint = OpTypePointer Function %uint
%25 = OpTypeFunction %uint %_ptr_Function_uint
%26 = OpExtInst %void %2 DebugTypeFunction %uint_3 %8 %8
%30 = OpExtInst %void %2 DebugFunction %29 %26 %17 %uint_0 %uint_0 %19 %29 %uint_3 %uint_0
%34 = OpExtInst %void %2 DebugLocalVariable %35 %8 %17 %uint_0 %uint_0 %30 %uint_4 %uint_1
%37 = OpExtInst %void %2 DebugExpression
%uint_10 = OpConstant %uint 10
%v4uint = OpTypeVector %uint 4
%49 = OpExtInst %void %2 DebugTypeVector %8 %uint_4
%_ptr_Function_v4uint = OpTypePointer Function %v4uint
%52 = OpExtInst %void %2 DebugLocalVariable %53 %49 %17 %uint_10 %uint_0 %16 %uint_4
%uint_11 = OpConstant %uint 11
%60 = OpTypeImage %uint 2D 0 0 0 2 R32ui
%64 = OpExtInst %void %2 DebugInfoNone
%61 = OpExtInst %void %2 DebugTypeComposite %62 %uint_0 %17 %uint_11 %uint_0 %19 %63 %64 %uint_3
%_ptr_UniformConstant_60 = OpTypePointer UniformConstant %60
%dst = OpVariable %_ptr_UniformConstant_60 UniformConstant
%uint_8 = OpConstant %uint 8
%67 = OpExtInst %void %2 DebugGlobalVariable %68 %61 %17 %uint_11 %uint_0 %19 %68 %dst %uint_8
%v3uint = OpTypeVector %uint 3
%72 = OpExtInst %void %2 DebugTypeVector %8 %uint_3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
%75 = OpExtInst %void %2 DebugGlobalVariable %76 %72 %17 %uint_11 %uint_0 %19 %76 %gl_GlobalInvocationID %uint_8
%v2uint = OpTypeVector %uint 2
%78 = OpExtInst %void %2 DebugTypeVector %8 %uint_2
%int = OpTypeInt 32 1
%83 = OpExtInst %void %2 DebugTypeBasic %82 %uint_32 %uint_4 %uint_0
%v2int = OpTypeVector %int 2
%85 = OpExtInst %void %2 DebugTypeVector %83 %uint_2
OpLine %1 9 11
%main = OpFunction %void None %5
%23 = OpLabel
%data = OpVariable %_ptr_Function_v4uint Function
%param = OpVariable %_ptr_Function_uint Function
%44 = OpExtInst %void %2 DebugFunctionDefinition %16 %main
%45 = OpExtInst %void %2 DebugScope %16
%46 = OpExtInst %void %2 DebugLine %17 %uint_10 %uint_10 %uint_0 %uint_0
%54 = OpExtInst %void %2 DebugDeclare %52 %data %37
OpStore %param %uint_0
%56 = OpFunctionCall %uint %BugFunction_u1_ %param
%57 = OpCompositeConstruct %v4uint %56 %56 %56 %56
OpStore %data %57
%58 = OpExtInst %void %2 DebugLine %17 %uint_11 %uint_11 %uint_0 %uint_0
%70 = OpLoad %60 %dst
%79 = OpLoad %v3uint %gl_GlobalInvocationID
%80 = OpVectorShuffle %v2uint %79 %79 0 1
%86 = OpBitcast %v2int %80
%87 = OpLoad %v4uint %data
OpImageWrite %70 %86 %87 ZeroExtend
OpReturn
OpFunctionEnd
OpLine %1 5 27
%BugFunction_u1_ = OpFunction %uint None %25
%val0 = OpFunctionParameter %_ptr_Function_uint
%31 = OpLabel
%32 = OpExtInst %void %2 DebugScope %30
%33 = OpExtInst %void %2 DebugLine %17 %uint_0 %uint_0 %uint_0 %uint_0
%36 = OpExtInst %void %2 DebugDeclare %34 %val0 %37
%38 = OpExtInst %void %2 DebugFunctionDefinition %30 %BugFunction_u1_
%39 = OpExtInst %void %2 DebugScope %30
%40 = OpExtInst %void %2 DebugLine %17 %uint_6 %uint_6 %uint_0 %uint_0
%41 = OpLoad %uint %val0
OpReturnValue %41
OpFunctionEnd

[CsInfo]
entryPoint = main
userDataNode[0].visibility = 0xffffffff
userDataNode[0].type = DescriptorTableVaPtr
userDataNode[0].offsetInDwords = 0
userDataNode[0].sizeInDwords = 1
userDataNode[0].next[0].type = DescriptorImage
userDataNode[0].next[0].offsetInDwords = 0
userDataNode[0].next[0].sizeInDwords = 8
userDataNode[0].next[0].set = 0x00000000
userDataNode[0].next[0].binding = 0
28 changes: 9 additions & 19 deletions llpc/translator/lib/SPIRV/SPIRVToLLVMDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,19 +503,6 @@ DINode *SPIRVToLLVMDbgTran::transFunction(const SPIRVExtInst *DebugInst) {
DISubprogram *DIS =
Builder.createFunction(Scope, Name, LinkageName, File, LineNo, Ty, ScopeLine, Flags, SPFlags, TParamsArray, FD);
DebugInstCache[DebugInst] = DIS;
SPIRVId RealFuncId = Ops[FunctionIdIdx];
FuncMap[RealFuncId] = DIS;

// Function.
SPIRVEntry *E = BM->getEntry(Ops[FunctionIdIdx]);
if (E->getOpCode() == OpFunction) {
SPIRVFunction *BF = static_cast<SPIRVFunction *>(E);
llvm::Function *F = SPIRVReader->transFunction(BF);
assert(F && "Translation of function failed!");
if (!F->hasMetadata())
F->setMetadata("dbg", DIS);
F->setSubprogram(DIS);
}
return DIS;
}

Expand Down Expand Up @@ -879,12 +866,15 @@ Instruction *SPIRVToLLVMDbgTran::transDebugIntrinsic(const SPIRVExtInst *DebugIn
case SPIRVDebug::NoScope:
return nullptr;
case SPIRVDebug::FunctionDefinition: {
using namespace SPIRVDebug::Operand::Function;
SPIRVExtInst *funcExt = BM->get<SPIRVExtInst>(Ops[0]);
std::vector<SPIRVWord> &args = funcExt->getArguments();
assert(args.size() > FunctionIdIdx);
args[FunctionIdIdx] = Ops[1];
transDebugInst<DISubprogram>(funcExt);
SPIRVExtInst *dbgDef = BM->get<SPIRVExtInst>(Ops[0]);
SPIRVFunction *opDef = BM->get<SPIRVFunction>(Ops[1]);
DISubprogram *DIS = transDebugInst<DISubprogram>(dbgDef);

FuncMap[opDef->getId()] = DIS;

llvm::Function *F = SPIRVReader->transFunction(opDef);
assert(F && "Translation of function failed!");
F->setSubprogram(DIS);
return nullptr;
}

Expand Down
5 changes: 2 additions & 3 deletions llpc/translator/lib/SPIRV/libSPIRV/SPIRV.debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,8 @@ enum {
LinkageNameIdx = 6,
FlagsIdx = 7,
ScopeLineIdx = 8,
FunctionIdIdx = 9,
DeclarationIdx = 10,
MinOperandCount = 10
DeclarationIdx = 9,
MinOperandCount = 9
};
}

Expand Down
5 changes: 0 additions & 5 deletions llpc/translator/lib/SPIRV/libSPIRV/SPIRVInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1560,11 +1560,6 @@ class SPIRVExtInst : public SPIRVFunctionCallGeneric<OpExtInst, 5> {
SPIRVLine *line = Module->add(new SPIRVLine(Module, Args[0], dbgLn, dbgCol));
Module->setCurrentLine(line);
}
// NonSemanticShaderDebugInfo100DebugFunction has one less argument than
// OpenCL.DebugInfo.100 DebugFunction
else if (ExtOpDebug == NonSemanticShaderDebugInfo100DebugFunction) {
Args.push_back(0);
}
}
}
void validate() const override {
Expand Down

0 comments on commit 2a6f20f

Please sign in to comment.