Skip to content

Commit bf51b6c

Browse files
committed
Initial support NonSemantic.Kernel.DebugInfo.100
This patch implements the initial support for the new debug specification NonSemantic.Kernel.DebugInfo.100. It also introduces support for the new debug instruction DISubrange. Spec: KhronosGroup/SPIRV-Registry#186
1 parent 9633373 commit bf51b6c

16 files changed

Lines changed: 226 additions & 96 deletions

include/LLVMSPIRVOpts.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ enum class BIsRepresentation : uint32_t { OpenCL12, OpenCL20, SPIRVFriendlyIR };
8080

8181
enum class FPContractMode : uint32_t { On, Off, Fast };
8282

83-
enum class DebugInfoEIS : uint32_t { SPIRV_Debug, OpenCL_DebugInfo_100 };
83+
enum class DebugInfoEIS : uint32_t {
84+
SPIRV_Debug,
85+
OpenCL_DebugInfo_100,
86+
NonSemantic_Kernel_DebugInfo_100
87+
};
8488

8589
/// \brief Helper class to manage SPIR-V translation
8690
class TranslatorOpts {

lib/SPIRV/LLVMToSPIRVDbgTran.cpp

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgEntryImpl(const MDNode *MDN) {
277277
case dwarf::DW_TAG_array_type:
278278
return transDbgArrayType(cast<DICompositeType>(DIEntry));
279279

280+
case dwarf::DW_TAG_subrange_type:
281+
return transDbgSubrangeType(cast<DISubrange>(DIEntry));
282+
280283
case dwarf::DW_TAG_const_type:
281284
case dwarf::DW_TAG_restrict_type:
282285
case dwarf::DW_TAG_volatile_type:
@@ -560,8 +563,7 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
560563
DINodeArray AR(AT->getElements());
561564
// For N-dimensianal arrays AR.getNumElements() == N
562565
const unsigned N = AR.size();
563-
Ops.resize(ComponentCountIdx + N);
564-
SPIRVWordVec LowerBounds(N);
566+
Ops.resize(SubrangesIdx + N);
565567
for (unsigned I = 0; I < N; ++I) {
566568
DISubrange *SR = cast<DISubrange>(AR[I]);
567569
ConstantInt *Count = SR->getCount().get<ConstantInt *>();
@@ -570,30 +572,73 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
570572
Ops[ComponentCountIdx] = static_cast<SPIRVWord>(Count->getZExtValue());
571573
return BM->addDebugInfo(SPIRVDebug::TypeVector, getVoidTy(), Ops);
572574
}
573-
if (Count) {
574-
Ops[ComponentCountIdx + I] =
575-
SPIRVWriter->transValue(Count, nullptr)->getId();
575+
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) {
576+
Ops[SubrangesIdx + I] = transDbgEntry(SR)->getId();
576577
} else {
577-
if (auto *UpperBound = dyn_cast<MDNode>(SR->getRawUpperBound()))
578-
Ops[ComponentCountIdx + I] = transDbgEntry(UpperBound)->getId();
578+
// According to the OpenCL.DebugInfo.100 specification Count must be a
579+
// Constant or DIVariable. No other operands must be preserved.
580+
if (Count)
581+
Ops[ComponentCountIdx + I] =
582+
SPIRVWriter->transValue(Count, nullptr)->getId();
583+
else if (auto *CountNode =
584+
dyn_cast_or_null<MDNode>(SR->getRawCountNode()))
585+
Ops[ComponentCountIdx + I] = transDbgEntry(CountNode)->getId();
579586
else
580587
Ops[ComponentCountIdx + I] = getDebugInfoNoneId();
581588
}
582-
if (auto *RawLB = SR->getRawLowerBound()) {
583-
if (auto *DIExprLB = dyn_cast<MDNode>(RawLB))
584-
LowerBounds[I] = transDbgEntry(DIExprLB)->getId();
585-
else {
586-
ConstantInt *ConstIntLB = SR->getLowerBound().get<ConstantInt *>();
587-
LowerBounds[I] = SPIRVWriter->transValue(ConstIntLB, nullptr)->getId();
588-
}
589-
} else {
590-
LowerBounds[I] = getDebugInfoNoneId();
591-
}
592589
}
593-
Ops.insert(Ops.end(), LowerBounds.begin(), LowerBounds.end());
594590
return BM->addDebugInfo(SPIRVDebug::TypeArray, getVoidTy(), Ops);
595591
}
596592

593+
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgSubrangeType(const DISubrange *ST) {
594+
using namespace SPIRVDebug::Operand::TypeSubrange;
595+
SPIRVWordVec Ops(OperandCount);
596+
auto transOperand = [&Ops, this, ST](int Idx) -> void {
597+
Metadata *RawNode = nullptr;
598+
switch (Idx) {
599+
case LowerBoundIdx:
600+
RawNode = ST->getRawLowerBound();
601+
break;
602+
case UpperBoundIdx:
603+
RawNode = ST->getRawUpperBound();
604+
break;
605+
case CountIdx:
606+
RawNode = ST->getRawCountNode();
607+
break;
608+
case StrideIdx:
609+
RawNode = ST->getRawStride();
610+
break;
611+
}
612+
if (!RawNode) {
613+
Ops[Idx] = getDebugInfoNoneId();
614+
return;
615+
} else if (auto *Node = dyn_cast<MDNode>(RawNode)) {
616+
Ops[Idx] = transDbgEntry(Node)->getId();
617+
} else {
618+
ConstantInt *IntNode = nullptr;
619+
switch (Idx) {
620+
case LowerBoundIdx:
621+
IntNode = ST->getLowerBound().get<ConstantInt *>();
622+
break;
623+
case UpperBoundIdx:
624+
IntNode = ST->getUpperBound().get<ConstantInt *>();
625+
break;
626+
case CountIdx:
627+
IntNode = ST->getCount().get<ConstantInt *>();
628+
break;
629+
case StrideIdx:
630+
IntNode = ST->getStride().get<ConstantInt *>();
631+
break;
632+
}
633+
Ops[Idx] = IntNode ? SPIRVWriter->transValue(IntNode, nullptr)->getId()
634+
: getDebugInfoNoneId();
635+
}
636+
};
637+
for (int Idx = CountIdx; Idx < OperandCount; ++Idx)
638+
transOperand(Idx);
639+
return BM->addDebugInfo(SPIRVDebug::TypeSubrange, getVoidTy(), Ops);
640+
}
641+
597642
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgTypeDef(const DIDerivedType *DT) {
598643
using namespace SPIRVDebug::Operand::Typedef;
599644
SPIRVWordVec Ops(OperandCount);

lib/SPIRV/LLVMToSPIRVDbgTran.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class LLVMToSPIRVDbgTran {
105105
SPIRVEntry *transDbgPointerType(const DIDerivedType *PT);
106106
SPIRVEntry *transDbgQualifiedType(const DIDerivedType *QT);
107107
SPIRVEntry *transDbgArrayType(const DICompositeType *AT);
108+
SPIRVEntry *transDbgSubrangeType(const DISubrange *ST);
108109
SPIRVEntry *transDbgTypeDef(const DIDerivedType *D);
109110
SPIRVEntry *transDbgSubroutineType(const DISubroutineType *FT);
110111
SPIRVEntry *transDbgEnumType(const DICompositeType *ET);

lib/SPIRV/SPIRVReader.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,6 +2298,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
22982298
return mapValue(BV, transOCLBuiltinFromExtInst(ExtInst, BB));
22992299
case SPIRVEIS_Debug:
23002300
case SPIRVEIS_OpenCL_DebugInfo_100:
2301+
case SPIRVEIS_NonSemantic_Kernel_DebugInfo_100:
23012302
return mapValue(BV, DbgTran->transDebugIntrinsic(ExtInst, BB));
23022303
default:
23032304
llvm_unreachable("Unknown extended instruction set!");

lib/SPIRV/SPIRVToLLVMDbgTran.cpp

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ SPIRVExtInst *SPIRVToLLVMDbgTran::getDbgInst(const SPIRVId Id) {
9191
if (isa<OpExtInst>(E)) {
9292
SPIRVExtInst *EI = static_cast<SPIRVExtInst *>(E);
9393
if (EI->getExtSetKind() == SPIRV::SPIRVEIS_Debug ||
94-
EI->getExtSetKind() == SPIRV::SPIRVEIS_OpenCL_DebugInfo_100)
94+
EI->getExtSetKind() == SPIRV::SPIRVEIS_OpenCL_DebugInfo_100 ||
95+
EI->getExtSetKind() == SPIRV::SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
9596
return EI;
9697
}
9798
return nullptr;
@@ -199,46 +200,37 @@ SPIRVToLLVMDbgTran::transTypeArray(const SPIRVExtInst *DebugInst) {
199200
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
200201
size_t TotalCount = 1;
201202
SmallVector<llvm::Metadata *, 8> Subscripts;
202-
// Ops looks like: { BaseType, count1|upperBound1, count2|upperBound2, ...,
203-
// countN|upperBoundN, lowerBound1, lowerBound2, ..., lowerBoundN }
204-
for (size_t I = ComponentCountIdx, E = Ops.size() / 2 + 1; I < E; ++I) {
205-
if (auto *LocalVar = getDbgInst<SPIRVDebug::LocalVariable>(Ops[I])) {
206-
auto *UpperBound = transDebugInst<DILocalVariable>(LocalVar);
207-
SPIRVConstant *C = BM->get<SPIRVConstant>(Ops[Ops.size() / 2 + I]);
208-
int64_t ConstantAsInt = static_cast<int64_t>(C->getZExtIntValue());
209-
auto *LowerBound = ConstantAsMetadata::get(
210-
ConstantInt::get(M->getContext(), APInt(64, ConstantAsInt)));
211-
Subscripts.push_back(Builder.getOrCreateSubrange(nullptr, LowerBound,
212-
UpperBound, nullptr));
213-
continue;
203+
if (DebugInst->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
204+
SPIRVDebug::TypeArray)) {
205+
for (size_t I = SubrangesIdx; I < Ops.size(); ++I) {
206+
auto *SR = transDebugInst<DISubrange>(BM->get<SPIRVExtInst>(Ops[I]));
207+
if (auto *Count = SR->getCount().get<ConstantInt *>())
208+
TotalCount *= Count->getZExtValue() > 0 ? Count->getZExtValue() : 0;
209+
Subscripts.push_back(SR);
214210
}
215-
if (auto *ExprUB = getDbgInst<SPIRVDebug::Expression>(Ops[I])) {
216-
auto *UpperBound = transDebugInst<DIExpression>(ExprUB);
217-
auto *ExprLB =
218-
getDbgInst<SPIRVDebug::Expression>(Ops[Ops.size() / 2 + I]);
219-
auto *LowerBound = transDebugInst<DIExpression>(ExprLB);
220-
Subscripts.push_back(Builder.getOrCreateSubrange(nullptr, LowerBound,
221-
UpperBound, nullptr));
222-
continue;
223-
}
224-
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[I])) {
225-
SPIRVConstant *C = BM->get<SPIRVConstant>(Ops[I]);
226-
int64_t Count = static_cast<int64_t>(C->getZExtIntValue());
227-
// If the SPIR-V file was generated by an older version of the translator,
228-
// Ops may not contain the LowerBound
229-
if (Ops.size() / 2 + I < Ops.size()) {
230-
C = BM->get<SPIRVConstant>(Ops[Ops.size() / 2 + I]);
231-
int64_t LowerBound = static_cast<int64_t>(C->getZExtIntValue());
232-
Subscripts.push_back(Builder.getOrCreateSubrange(LowerBound, Count));
233-
} else {
211+
} else {
212+
for (size_t I = ComponentCountIdx, E = Ops.size(); I < E; ++I) {
213+
// Otherwise Count could be a constant or DIVariable
214+
if (auto *LocalVarCount = getDbgInst<SPIRVDebug::LocalVariable>(Ops[I])) {
215+
auto *DILocalVarCount = transDebugInst<DILocalVariable>(LocalVarCount);
216+
Subscripts.push_back(Builder.getOrCreateSubrange(
217+
DILocalVarCount, nullptr, nullptr, nullptr));
218+
} else if (auto *GlobalVarCount =
219+
getDbgInst<SPIRVDebug::GlobalVariable>(Ops[I])) {
220+
auto *DIGlobalVarCount =
221+
transDebugInst<DIGlobalVariable>(GlobalVarCount);
222+
Subscripts.push_back(Builder.getOrCreateSubrange(
223+
DIGlobalVarCount, nullptr, nullptr, nullptr));
224+
} else if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[I])) {
225+
SPIRVConstant *C = BM->get<SPIRVConstant>(Ops[I]);
226+
int64_t Count = static_cast<int64_t>(C->getZExtIntValue());
227+
// Count = -1 means that the array is empty
228+
TotalCount *= Count > 0 ? Count : 0;
234229
auto *CountAsMD = ConstantAsMetadata::get(
235230
ConstantInt::get(M->getContext(), APInt(64, Count)));
236231
Subscripts.push_back(
237232
Builder.getOrCreateSubrange(CountAsMD, nullptr, nullptr, nullptr));
238233
}
239-
// Count = -1 means that the array is empty
240-
TotalCount *= Count > 0 ? static_cast<size_t>(Count) : 0;
241-
continue;
242234
}
243235
}
244236
DINodeArray SubscriptArray = Builder.getOrCreateArray(Subscripts);
@@ -286,6 +278,8 @@ SPIRVToLLVMDbgTran::transTypeComposite(const SPIRVExtInst *DebugInst) {
286278
SPIRVEntry *SizeEntry = BM->getEntry(Ops[SizeIdx]);
287279
if (!(SizeEntry->isExtInst(SPIRVEIS_Debug, SPIRVDebug::DebugInfoNone) ||
288280
SizeEntry->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100,
281+
SPIRVDebug::DebugInfoNone) ||
282+
SizeEntry->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
289283
SPIRVDebug::DebugInfoNone))) {
290284
Size = BM->get<SPIRVConstant>(Ops[SizeIdx])->getZExtIntValue();
291285
}
@@ -341,6 +335,36 @@ SPIRVToLLVMDbgTran::transTypeComposite(const SPIRVExtInst *DebugInst) {
341335
return CT;
342336
}
343337

338+
DISubrange *
339+
SPIRVToLLVMDbgTran::transTypeSubrange(const SPIRVExtInst *DebugInst) {
340+
using namespace SPIRVDebug::Operand::TypeSubrange;
341+
const SPIRVWordVec &Ops = DebugInst->getArguments();
342+
assert(Ops.size() == OperandCount && "Invalid number of operands");
343+
std::vector<Metadata *> TranslatedOps(OperandCount, nullptr);
344+
auto transOperand = [&Ops, &TranslatedOps, this](int Idx) -> void {
345+
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[Idx])) {
346+
if (auto *GlobalVar = getDbgInst<SPIRVDebug::GlobalVariable>(Ops[Idx])) {
347+
TranslatedOps[Idx] =
348+
cast<Metadata>(transDebugInst<DIGlobalVariable>(GlobalVar));
349+
} else if (auto *LocalVar =
350+
getDbgInst<SPIRVDebug::LocalVariable>(Ops[Idx])) {
351+
TranslatedOps[Idx] =
352+
cast<Metadata>(transDebugInst<DILocalVariable>(LocalVar));
353+
} else if (auto *Expr = getDbgInst<SPIRVDebug::Expression>(Ops[Idx])) {
354+
TranslatedOps[Idx] = cast<Metadata>(transDebugInst<DIExpression>(Expr));
355+
} else if (auto *Const = BM->get<SPIRVConstant>(Ops[Idx])) {
356+
int64_t ConstantAsInt = static_cast<int64_t>(Const->getZExtIntValue());
357+
TranslatedOps[Idx] = cast<Metadata>(ConstantAsMetadata::get(
358+
ConstantInt::get(M->getContext(), APInt(64, ConstantAsInt))));
359+
}
360+
}
361+
};
362+
for (int Idx = CountIdx; Idx < OperandCount; ++Idx)
363+
transOperand(Idx);
364+
return Builder.getOrCreateSubrange(TranslatedOps[0], TranslatedOps[1],
365+
TranslatedOps[2], TranslatedOps[3]);
366+
}
367+
344368
DINode *SPIRVToLLVMDbgTran::transTypeMember(const SPIRVExtInst *DebugInst) {
345369
using namespace SPIRVDebug::Operand::TypeMember;
346370
const SPIRVWordVec &Ops = DebugInst->getArguments();
@@ -887,6 +911,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
887911
case SPIRVDebug::TypeArray:
888912
return transTypeArray(DebugInst);
889913

914+
case SPIRVDebug::TypeSubrange:
915+
return transTypeSubrange(DebugInst);
916+
890917
case SPIRVDebug::TypeVector:
891918
return transTypeVector(DebugInst);
892919

lib/SPIRV/SPIRVToLLVMDbgTran.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ class SPIRVToLLVMDbgTran {
7070
template <typename T = MDNode>
7171
T *transDebugInst(const SPIRVExtInst *DebugInst) {
7272
assert((DebugInst->getExtSetKind() == SPIRVEIS_Debug ||
73-
DebugInst->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100) &&
73+
DebugInst->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100 ||
74+
DebugInst->getExtSetKind() ==
75+
SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) &&
7476
"Unexpected extended instruction set");
7577
auto It = DebugInstCache.find(DebugInst);
7678
if (It != DebugInstCache.end())
@@ -113,6 +115,8 @@ class SPIRVToLLVMDbgTran {
113115

114116
DICompositeType *transTypeComposite(const SPIRVExtInst *DebugInst);
115117

118+
DISubrange *transTypeSubrange(const SPIRVExtInst *DebugInst);
119+
116120
DINode *transTypeMember(const SPIRVExtInst *DebugInst);
117121

118122
DINode *transTypeEnum(const SPIRVExtInst *DebugInst);

lib/SPIRV/libSPIRV/SPIRV.debug.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ enum Instruction {
5050
ImportedEntity = 34,
5151
Source = 35,
5252
ModuleINTEL = 36,
53-
InstCount = 37
53+
InstCount = 37,
54+
TypeSubrange = 107
5455
};
5556

5657
enum Flag {
@@ -323,12 +324,23 @@ namespace TypeArray {
323324
enum {
324325
BaseTypeIdx = 0,
325326
ComponentCountIdx = 1,
327+
SubrangesIdx = 1,
326328
MinOperandCount = 2
327329
};
328330
}
329331

330332
namespace TypeVector = TypeArray;
331333

334+
namespace TypeSubrange {
335+
enum {
336+
CountIdx = 0,
337+
LowerBoundIdx = 1,
338+
UpperBoundIdx = 2,
339+
StrideIdx = 3,
340+
OperandCount = 4
341+
};
342+
}
343+
332344
namespace Typedef {
333345
enum {
334346
NameIdx = 0,

lib/SPIRV/libSPIRV/SPIRVEnum.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum SPIRVExtInstSetKind {
7878
SPIRVEIS_OpenCL,
7979
SPIRVEIS_Debug,
8080
SPIRVEIS_OpenCL_DebugInfo_100,
81+
SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
8182
SPIRVEIS_Count,
8283
};
8384

@@ -129,6 +130,8 @@ template <> inline void SPIRVMap<SPIRVExtInstSetKind, std::string>::init() {
129130
add(SPIRVEIS_OpenCL, "OpenCL.std");
130131
add(SPIRVEIS_Debug, "SPIRV.debug");
131132
add(SPIRVEIS_OpenCL_DebugInfo_100, "OpenCL.DebugInfo.100");
133+
add(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
134+
"NonSemantic.Kernel.DebugInfo.100");
132135
}
133136
typedef SPIRVMap<SPIRVExtInstSetKind, std::string> SPIRVBuiltinSetNameMap;
134137

lib/SPIRV/libSPIRV/SPIRVExtInst.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ template <> inline void SPIRVMap<SPIRVDebugExtOpKind, std::string>::init() {
239239
"DebugTemplateTemplateParameter");
240240
add(SPIRVDebug::TypeTemplate, "DebugTemplate");
241241
add(SPIRVDebug::TypePtrToMember, "DebugTypePtrToMember,");
242+
add(SPIRVDebug::TypeSubrange, "DebugTypeSubrange");
242243
add(SPIRVDebug::Inheritance, "DebugInheritance");
243244
add(SPIRVDebug::Function, "DebugFunction");
244245
add(SPIRVDebug::FunctionDecl, "DebugFunctionDecl");

lib/SPIRV/libSPIRV/SPIRVFunction.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,14 @@ bool SPIRVFunction::decodeBB(SPIRVDecoder &Decoder) {
161161
Module->add(Inst);
162162
} else {
163163
if (Inst->isExtInst(SPIRVEIS_Debug, SPIRVDebug::Scope) ||
164-
Inst->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100, SPIRVDebug::Scope)) {
164+
Inst->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100, SPIRVDebug::Scope) ||
165+
Inst->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
166+
SPIRVDebug::Scope)) {
165167
DebugScope = Inst;
166168
} else if (Inst->isExtInst(SPIRVEIS_Debug, SPIRVDebug::NoScope) ||
167169
Inst->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100,
170+
SPIRVDebug::NoScope) ||
171+
Inst->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
168172
SPIRVDebug::NoScope)) {
169173
DebugScope = nullptr;
170174
} else {

0 commit comments

Comments
 (0)