Skip to content

Commit 093430c

Browse files
vmaksimoagainull
authored andcommitted
Support translation of DebugFunctionDefinition instruction (intel#1961)
DebugFunction does not have an Function Id operand in NonSemantic.Shader debug info specification. It's been replaced by the whole new DebugFunctionDefinition instruction to avoid forward references. This instruction must appear in the entry basic block of an OpFunction. Specification: https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.Shader.DebugInfo.100.asciidoc#DebugFunctionDefinition Original commit: KhronosGroup/SPIRV-LLVM-Translator@55ce223
1 parent f562958 commit 093430c

File tree

10 files changed

+121
-25
lines changed

10 files changed

+121
-25
lines changed

llvm-spirv/lib/SPIRV/LLVMToSPIRVDbgTran.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgFunction(const DISubprogram *Func) {
11351135
transformToConstant(Ops, {LineIdx, ColumnIdx, FlagsIdx});
11361136

11371137
SPIRVEntry *DebugFunc = nullptr;
1138+
SPIRVValue *FuncDef = nullptr;
11381139
if (!Func->isDefinition()) {
11391140
DebugFunc =
11401141
BM->addDebugInfo(SPIRVDebug::FunctionDeclaration, getVoidTy(), Ops);
@@ -1152,9 +1153,14 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgFunction(const DISubprogram *Func) {
11521153
SPIRVValue *SPIRVFunc = SPIRVWriter->getTranslatedValue(&F);
11531154
assert(SPIRVFunc && "All function must be already translated");
11541155
Ops[FunctionIdIdx] = SPIRVFunc->getId();
1156+
FuncDef = SPIRVFunc;
11551157
break;
11561158
}
11571159
}
1160+
// For NonSemantic.Shader.DebugInfo we store Function Id index as a
1161+
// separate DebugFunctionDefinition instruction.
1162+
if (isNonSemanticDebugInfo())
1163+
Ops.pop_back();
11581164

11591165
if (DISubprogram *FuncDecl = Func->getDeclaration())
11601166
Ops.push_back(transDbgEntry(FuncDecl)->getId());
@@ -1181,9 +1187,30 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgFunction(const DISubprogram *Func) {
11811187
if (DITemplateParameterArray TPA = Func->getTemplateParams()) {
11821188
DebugFunc = transDbgTemplateParams(TPA, DebugFunc);
11831189
}
1190+
1191+
if (isNonSemanticDebugInfo())
1192+
transDbgFuncDefinition(FuncDef, DebugFunc);
1193+
11841194
return DebugFunc;
11851195
}
11861196

1197+
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgFuncDefinition(SPIRVValue *FuncDef,
1198+
SPIRVEntry *DbgFunc) {
1199+
if (!isNonSemanticDebugInfo() || !FuncDef)
1200+
return nullptr;
1201+
1202+
using namespace SPIRVDebug::Operand::FunctionDefinition;
1203+
SPIRVWordVec Ops(OperandCount);
1204+
Ops[FunctionIdx] = DbgFunc->getId();
1205+
Ops[DefinitionIdx] = FuncDef->getId();
1206+
SPIRVFunction *F = static_cast<SPIRVFunction *>(FuncDef);
1207+
SPIRVBasicBlock *BB = F->getNumBasicBlock() ? F->getBasicBlock(0) : nullptr;
1208+
SPIRVId ExtSetId = BM->getExtInstSetId(BM->getDebugInfoEIS());
1209+
1210+
return BM->addExtInst(getVoidTy(), ExtSetId, SPIRVDebug::FunctionDefinition,
1211+
Ops, BB, BB->getInst(0));
1212+
}
1213+
11871214
// Location information
11881215

11891216
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgScope(const DIScope *S) {

llvm-spirv/lib/SPIRV/LLVMToSPIRVDbgTran.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class LLVMToSPIRVDbgTran {
134134
SPIRVEntry *transDbgGlobalVariable(const DIGlobalVariable *GV);
135135
SPIRVEntry *transDbgFunction(const DISubprogram *Func);
136136

137+
SPIRVEntry *transDbgFuncDefinition(SPIRVValue *SPVFunc, SPIRVEntry *DbgFunc);
138+
137139
// Location information
138140
SPIRVEntry *transDbgScope(const DIScope *S);
139141
SPIRVEntry *transDebugLoc(const DebugLoc &Loc, SPIRVBasicBlock *BB,

llvm-spirv/lib/SPIRV/SPIRVToLLVMDbgTran.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,11 @@ DINode *SPIRVToLLVMDbgTran::transFunction(const SPIRVExtInst *DebugInst) {
753753

754754
// Function declaration descriptor
755755
DISubprogram *FD = nullptr;
756-
if (Ops.size() > DeclarationIdx) {
756+
if (isNonSemanticDebugInfo(DebugInst->getExtSetKind()) &&
757+
Ops.size() > DeclarationNonSemIdx) {
758+
FD = transDebugInst<DISubprogram>(
759+
BM->get<SPIRVExtInst>(Ops[DeclarationNonSemIdx]));
760+
} else if (Ops.size() > DeclarationIdx) {
757761
FD = transDebugInst<DISubprogram>(
758762
BM->get<SPIRVExtInst>(Ops[DeclarationIdx]));
759763
}
@@ -778,7 +782,7 @@ DINode *SPIRVToLLVMDbgTran::transFunction(const SPIRVExtInst *DebugInst) {
778782
// Create targetFuncName mostly for Fortran trampoline function if it is
779783
// the case
780784
StringRef TargetFunction;
781-
if (Ops.size() > TargetFunctionNameIdx) {
785+
if (Ops.size() > MinOperandCount) {
782786
TargetFunction = getString(Ops[TargetFunctionNameIdx]);
783787
}
784788
DIS = getDIBuilder(DebugInst).createFunction(
@@ -788,19 +792,40 @@ DINode *SPIRVToLLVMDbgTran::transFunction(const SPIRVExtInst *DebugInst) {
788792
/*Annotations*/ nullptr, TargetFunction);
789793
}
790794
DebugInstCache[DebugInst] = DIS;
791-
SPIRVId RealFuncId = Ops[FunctionIdIdx];
792-
FuncMap[RealFuncId] = DIS;
793795

794-
// Function.
795-
SPIRVEntry *E = BM->getEntry(Ops[FunctionIdIdx]);
796+
// At this point, we don't have info about the function definition for
797+
// NonSemantic.Shader debug info. If function definition is present, it'll be
798+
// translated later within the function scope.
799+
// For "default" debug info we do translate function body here.
800+
if (!isNonSemanticDebugInfo(DebugInst->getExtSetKind()))
801+
transFunctionBody(DIS, Ops[FunctionIdIdx]);
802+
803+
return DIS;
804+
}
805+
806+
void SPIRVToLLVMDbgTran::transFunctionBody(DISubprogram *DIS, SPIRVId FuncId) {
807+
FuncMap[FuncId] = DIS;
808+
809+
SPIRVEntry *E = BM->getEntry(FuncId);
796810
if (E->getOpCode() == OpFunction) {
797811
SPIRVFunction *BF = static_cast<SPIRVFunction *>(E);
798812
llvm::Function *F = SPIRVReader->transFunction(BF);
799813
assert(F && "Translation of function failed!");
800814
if (!F->hasMetadata("dbg"))
801815
F->setMetadata("dbg", DIS);
802816
}
803-
return DIS;
817+
}
818+
819+
DINode *
820+
SPIRVToLLVMDbgTran::transFunctionDefinition(const SPIRVExtInst *DebugInst) {
821+
using namespace SPIRVDebug::Operand::FunctionDefinition;
822+
const SPIRVWordVec &Ops = DebugInst->getArguments();
823+
824+
SPIRVExtInst *Func = BM->get<SPIRVExtInst>(Ops[FunctionIdx]);
825+
DISubprogram *LLVMFunc = cast<DISubprogram>(DebugInstCache[Func]);
826+
827+
transFunctionBody(LLVMFunc, Ops[DefinitionIdx]);
828+
return nullptr;
804829
}
805830

806831
DINode *SPIRVToLLVMDbgTran::transFunctionDecl(const SPIRVExtInst *DebugInst) {
@@ -1195,6 +1220,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
11951220
case SPIRVDebug::FunctionDeclaration:
11961221
return transFunctionDecl(DebugInst);
11971222

1223+
case SPIRVDebug::FunctionDefinition:
1224+
return transFunctionDefinition(DebugInst);
1225+
11981226
case SPIRVDebug::GlobalVariable:
11991227
return transGlobalVariable(DebugInst);
12001228

@@ -1264,6 +1292,7 @@ SPIRVToLLVMDbgTran::transDebugIntrinsic(const SPIRVExtInst *DebugInst,
12641292
switch (DebugInst->getExtOp()) {
12651293
case SPIRVDebug::Scope:
12661294
case SPIRVDebug::NoScope:
1295+
case SPIRVDebug::FunctionDefinition:
12671296
return nullptr;
12681297
case SPIRVDebug::Declare: {
12691298
using namespace SPIRVDebug::Operand::DebugDeclare;

llvm-spirv/lib/SPIRV/SPIRVToLLVMDbgTran.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ class SPIRVToLLVMDbgTran {
142142
DINode *transLexicalBlockDiscriminator(const SPIRVExtInst *DebugInst);
143143

144144
DINode *transFunction(const SPIRVExtInst *DebugInst);
145+
DINode *transFunctionDefinition(const SPIRVExtInst *DebugInst);
146+
void transFunctionBody(DISubprogram *DIS, SPIRVId FuncId);
145147

146148
DINode *transFunctionDecl(const SPIRVExtInst *DebugInst);
147149

llvm-spirv/lib/SPIRV/libSPIRV/SPIRV.debug.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum Instruction {
5454
Source = 35,
5555
ModuleINTEL = 36,
5656
InstCount = 37,
57+
FunctionDefinition = 101,
5758
Module = 200,
5859
TypeSubrange = 201,
5960
TypeArrayDynamic = 202,
@@ -543,12 +544,22 @@ enum {
543544
FlagsIdx = 7,
544545
ScopeLineIdx = 8,
545546
FunctionIdIdx = 9,
547+
DeclarationNonSemIdx = 9,
546548
DeclarationIdx = 10,
547-
TargetFunctionNameIdx = 11,
549+
// Only for NonSemantic.Schader.DebugInfo.200
550+
TargetFunctionNameIdx = 10,
548551
MinOperandCount = 10
549552
};
550553
}
551554

555+
namespace FunctionDefinition {
556+
enum {
557+
FunctionIdx = 0,
558+
DefinitionIdx = 1,
559+
OperandCount = 2
560+
};
561+
}
562+
552563
namespace LexicalBlock {
553564
enum {
554565
SourceIdx = 0,

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVExtInst.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ template <> inline void SPIRVMap<SPIRVDebugExtOpKind, std::string>::init() {
261261
add(SPIRVDebug::Module, "DebugModule");
262262
add(SPIRVDebug::Expression, "DebugExpression");
263263
add(SPIRVDebug::Operation, "DebugOperation");
264+
add(SPIRVDebug::FunctionDefinition, "DebugFunctionDefinition");
264265
}
265266
SPIRV_DEF_NAMEMAP(SPIRVDebugExtOpKind, SPIRVDebugExtOpMap)
266267

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,17 @@ spv_ostream &operator<<(spv_ostream &O, SPIRVModule &M) {
19121912
O << SPIRVNL() << MI.AsmTargetVec << MI.AsmVec;
19131913
}
19141914

1915+
// At this point we know that FunctionDefinition could have been included both
1916+
// into DebugInstVec and into basick block of function from FuncVec.
1917+
// By spec we should only have this instruction to be present inside the
1918+
// function body, so removing it from the DebugInstVec to avoid duplication.
1919+
MI.DebugInstVec.erase(
1920+
std::remove_if(MI.DebugInstVec.begin(), MI.DebugInstVec.end(),
1921+
[](SPIRVExtInst *I) {
1922+
return I->getExtOp() == SPIRVDebug::FunctionDefinition;
1923+
}),
1924+
MI.DebugInstVec.end());
1925+
19151926
O << SPIRVNL() << MI.DebugInstVec << MI.AuxDataInstVec << SPIRVNL()
19161927
<< MI.FuncVec;
19171928
return O;

llvm-spirv/test/DebugInfo/NonSemantic/DebugFunction.cl

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,15 @@
44
// - Parent operand of DebugFunction is DebugCompilationUnit, not an OpString,
55
// even if in LLVM IR it points to a DIFile instead of DICompileUnit.
66

7-
// RUN: %clang_cc1 %s -cl-std=clc++ -emit-llvm-bc -triple spir -debug-info-kind=line-tables-only -O0 -o - | llvm-spirv -o %t.spv
8-
// RUN: llvm-spirv %t.spv --spirv-debug-info-version=nonsemantic-shader-100 -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
7+
// RUN: %clang_cc1 %s -cl-std=clc++ -emit-llvm-bc -triple spir -debug-info-kind=line-tables-only -O0 -o %t.bc
8+
// RUN: llvm-spirv %t.bc --spirv-debug-info-version=nonsemantic-shader-100 -o %t.spv
9+
// RUN: llvm-spirv %t.spv -to-text -o %t.spt
10+
// RUN: FileCheck %s --input-file %t.spt --check-prefix=CHECK-SPIRV
11+
12+
// RUN: llvm-spirv %t.bc --spirv-debug-info-version=nonsemantic-shader-200 -o %t.spv
13+
// RUN: llvm-spirv %t.spv -to-text -o %t.spt
14+
// RUN: FileCheck %s --input-file %t.spt --check-prefix=CHECK-SPIRV
15+
916
// RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
1017

1118
float foo(int i) {
@@ -18,11 +25,17 @@ void kernel k() {
1825
// CHECK-SPIRV: String [[foo:[0-9]+]] "foo"
1926
// CHECK-SPIRV: String [[k:[0-9]+]] "k"
2027
// CHECK-SPIRV: [[CU:[0-9]+]] {{[0-9]+}} DebugCompilationUnit
21-
// CHECK-SPIRV: DebugFunction [[foo]] {{.*}} [[CU]] {{.*}} [[foo_id:[0-9]+]] {{[0-9]+}} {{$}}
22-
// CHECK-SPIRV: DebugFunction [[k]] {{.*}} [[CU]] {{.*}} [[k_id:[0-9]+]] {{[0-9]+}} {{$}}
28+
// CHECK-SPIRV: [[#FuncFoo:]] [[#]] DebugFunction [[foo]] {{.*}} [[CU]]
29+
// CHECK-SPIRV: [[#FuncK:]] [[#]] DebugFunction [[k]] {{.*}} [[CU]]
30+
// CHECK-SPIRV-NOT: DebugFunctionDefinition
31+
32+
// CHECK-SPIRV: Function {{[0-9]+}} [[#foo_id:]]
33+
// CHECK-SPIRV: DebugFunctionDefinition [[#FuncFoo]] [[#foo_id]]
34+
// CHECK-LLVM: define spir_func float @_Z3fooi(i32 %i) #{{[0-9]+}} !dbg ![[#foo_id:]] {
2335

24-
// CHECK-SPIRV: Function {{[0-9]+}} [[foo_id]]
25-
// CHECK-LLVM: define spir_func float @_Z3fooi(i32 %i) #{{[0-9]+}} !dbg !{{[0-9]+}} {
36+
// CHECK-SPIRV: Function {{[0-9]+}} [[#k_id:]]
37+
// CHECK-SPIRV: DebugFunctionDefinition [[#FuncK]] [[#k_id]]
38+
// CHECK-LLVM: define spir_kernel void @k() #{{[0-9]+}} !dbg ![[#k_id:]]
2639

27-
// CHECK-SPIRV: Function {{[0-9]+}} [[k_id]]
28-
// CHECK-LLVM: define spir_kernel void @k() #{{[0-9]+}} !dbg !{{[0-9]+}}
40+
// CHECK-LLVM: ![[#foo_id]] = distinct !DISubprogram(name: "foo"
41+
// CHECK-LLVM: ![[#k_id]] = distinct !DISubprogram(name: "k"

llvm-spirv/test/DebugInfo/NonSemantic/Shader200/DebugInfoTargetFunction.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
; CHECK-SPIRV-DAG: String [[#TargetFunc:]] "_Z3foov"
1313

1414
; CHECK-SPIRV-DAG: ExtInst [[#]] [[#DebugNone:]] [[#]] DebugInfoNone
15-
; CHECK-SPIRV-DAG: ExtInst [[#]] [[#]] [[#]] DebugFunction [[#Func]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#DebugNone]] [[#TargetFunc]]
15+
; CHECK-SPIRV-DAG: ExtInst [[#]] [[#]] [[#]] DebugFunction [[#Func]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#DebugNone]] [[#TargetFunc]]
1616

1717
; CHECK-LLVM: define spir_func void @_Z11foo_wrapperv() {{.*}} !dbg ![[#DbgSubProg:]] {
1818
; CHECK-LLVM: ![[#DbgSubProg]] = distinct !DISubprogram(name: "foo_wrapper", linkageName: "_Z11foo_wrapperv", scope: null, file: ![[#]], line: 3, type: ![[#]], scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: ![[#]], templateParams: ![[#]], retainedNodes: ![[#]], targetFuncName: "_Z3foov")

llvm-spirv/test/DebugInfo/NonSemantic/Shader200/FortranComplex.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
; CHECK-SPIRV-200-DAG: ExtInst [[#]] [[#]] [[#Import]] DebugLocalVariable [[#]] [[#Type]]
3333
; CHECK-SPIRV-200-DAG: ExtInst [[#]] [[#]] [[#Import]] DebugLocalVariable [[#]] [[#Type]]
3434

35-
; CHECK-LLVM-200: ![[#]] = !DILocalVariable(name: "a", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type:]])
36-
; CHECK-LLVM-200: ![[#Type]] = !DIBasicType(name: "COMPLEX*8", size: 64, encoding: DW_ATE_complex_float)
37-
; CHECK-LLVM-200: ![[#]] = !DILocalVariable(name: "b", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
38-
; CHECK-LLVM-200: ![[#]] = !DILocalVariable(name: "c", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
35+
; CHECK-LLVM-200-DAG: ![[#]] = !DILocalVariable(name: "a", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type:]])
36+
; CHECK-LLVM-200-DAG: ![[#Type]] = !DIBasicType(name: "COMPLEX*8", size: 64, encoding: DW_ATE_complex_float)
37+
; CHECK-LLVM-200-DAG: ![[#]] = !DILocalVariable(name: "b", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
38+
; CHECK-LLVM-200-DAG: ![[#]] = !DILocalVariable(name: "c", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
3939

4040
; CHECK-SPIRV-100-DAG: ExtInstImport [[#Import:]] "NonSemantic.Shader.DebugInfo.100
4141
; CHECK-SPIRV-100-DAG: String [[#Name:]] "COMPLEX*8"
@@ -46,10 +46,10 @@
4646
; CHECK-SPIRV-100-DAG: ExtInst [[#]] [[#]] [[#Import]] DebugLocalVariable [[#]] [[#Type]]
4747
; CHECK-SPIRV-100-DAG: ExtInst [[#]] [[#]] [[#Import]] DebugLocalVariable [[#]] [[#Type]]
4848

49-
; CHECK-LLVM-100: ![[#]] = !DILocalVariable(name: "a", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type:]])
50-
; CHECK-LLVM-100: ![[#Type]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "COMPLEX*8")
51-
; CHECK-LLVM-100: ![[#]] = !DILocalVariable(name: "b", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
52-
; CHECK-LLVM-100: ![[#]] = !DILocalVariable(name: "c", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
49+
; CHECK-LLVM-100-DAG: ![[#]] = !DILocalVariable(name: "a", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type:]])
50+
; CHECK-LLVM-100-DAG: ![[#Type]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "COMPLEX*8")
51+
; CHECK-LLVM-100-DAG: ![[#]] = !DILocalVariable(name: "b", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
52+
; CHECK-LLVM-100-DAG: ![[#]] = !DILocalVariable(name: "c", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#Type]])
5353

5454
; ModuleID = 'test.f90'
5555
source_filename = "test.f90"

0 commit comments

Comments
 (0)