Skip to content

Commit

Permalink
[Backport to 16] Initial support NonSemantic.Kernel.DebugInfo.100 (Kh…
Browse files Browse the repository at this point in the history
…ronosGroup#1846)

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
  • Loading branch information
vmaksimo authored and mateuszchudyk committed Sep 29, 2023
1 parent bda29b7 commit 8e8ef50
Show file tree
Hide file tree
Showing 16 changed files with 340 additions and 8 deletions.
6 changes: 5 additions & 1 deletion include/LLVMSPIRVOpts.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ enum class BIsRepresentation : uint32_t { OpenCL12, OpenCL20, SPIRVFriendlyIR };

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

enum class DebugInfoEIS : uint32_t { SPIRV_Debug, OpenCL_DebugInfo_100 };
enum class DebugInfoEIS : uint32_t {
SPIRV_Debug,
OpenCL_DebugInfo_100,
NonSemantic_Kernel_DebugInfo_100
};

/// \brief Helper class to manage SPIR-V translation
class TranslatorOpts {
Expand Down
88 changes: 88 additions & 0 deletions lib/SPIRV/LLVMToSPIRVDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,12 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgEntryImpl(const MDNode *MDN) {
case dwarf::DW_TAG_array_type:
return transDbgArrayType(cast<DICompositeType>(DIEntry));

case dwarf::DW_TAG_subrange_type:
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
return transDbgSubrangeType(cast<DISubrange>(DIEntry));
else
return getDebugInfoNone();

case dwarf::DW_TAG_const_type:
case dwarf::DW_TAG_restrict_type:
case dwarf::DW_TAG_volatile_type:
Expand Down Expand Up @@ -552,6 +558,14 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgQualifiedType(const DIDerivedType *QT) {
}

SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
return transDbgArrayTypeNonSemantic(AT);

return transDbgArrayTypeOpenCL(AT);
}

SPIRVEntry *
LLVMToSPIRVDbgTran::transDbgArrayTypeOpenCL(const DICompositeType *AT) {
using namespace SPIRVDebug::Operand::TypeArray;
SPIRVWordVec Ops(MinOperandCount);
SPIRVEntry *Base = transDbgEntry(AT->getBaseType());
Expand Down Expand Up @@ -594,6 +608,80 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
return BM->addDebugInfo(SPIRVDebug::TypeArray, getVoidTy(), Ops);
}

SPIRVEntry *
LLVMToSPIRVDbgTran::transDbgArrayTypeNonSemantic(const DICompositeType *AT) {
using namespace SPIRVDebug::Operand::TypeArray;
SPIRVWordVec Ops(MinOperandCount);
SPIRVEntry *Base = transDbgEntry(AT->getBaseType());
Ops[BaseTypeIdx] = Base->getId();

DINodeArray AR(AT->getElements());
// For N-dimensianal arrays AR.getNumElements() == N
const unsigned N = AR.size();
Ops.resize(SubrangesIdx + N);
for (unsigned I = 0; I < N; ++I) {
DISubrange *SR = cast<DISubrange>(AR[I]);
ConstantInt *Count = SR->getCount().get<ConstantInt *>();
if (AT->isVector()) {
assert(N == 1 && "Multidimensional vector is not expected!");
Ops[ComponentCountIdx] = static_cast<SPIRVWord>(Count->getZExtValue());
return BM->addDebugInfo(SPIRVDebug::TypeVector, getVoidTy(), Ops);
}
Ops[SubrangesIdx + I] = transDbgEntry(SR)->getId();
}
return BM->addDebugInfo(SPIRVDebug::TypeArray, getVoidTy(), Ops);
}

SPIRVEntry *LLVMToSPIRVDbgTran::transDbgSubrangeType(const DISubrange *ST) {
using namespace SPIRVDebug::Operand::TypeSubrange;
SPIRVWordVec Ops(OperandCount);
auto TransOperand = [&Ops, this, ST](int Idx) -> void {
Metadata *RawNode = nullptr;
switch (Idx) {
case LowerBoundIdx:
RawNode = ST->getRawLowerBound();
break;
case UpperBoundIdx:
RawNode = ST->getRawUpperBound();
break;
case CountIdx:
RawNode = ST->getRawCountNode();
break;
case StrideIdx:
RawNode = ST->getRawStride();
break;
}
if (!RawNode) {
Ops[Idx] = getDebugInfoNoneId();
return;
}
if (auto *Node = dyn_cast<MDNode>(RawNode)) {
Ops[Idx] = transDbgEntry(Node)->getId();
} else {
ConstantInt *IntNode = nullptr;
switch (Idx) {
case LowerBoundIdx:
IntNode = ST->getLowerBound().get<ConstantInt *>();
break;
case UpperBoundIdx:
IntNode = ST->getUpperBound().get<ConstantInt *>();
break;
case CountIdx:
IntNode = ST->getCount().get<ConstantInt *>();
break;
case StrideIdx:
IntNode = ST->getStride().get<ConstantInt *>();
break;
}
Ops[Idx] = IntNode ? SPIRVWriter->transValue(IntNode, nullptr)->getId()
: getDebugInfoNoneId();
}
};
for (int Idx = CountIdx; Idx < OperandCount; ++Idx)
TransOperand(Idx);
return BM->addDebugInfo(SPIRVDebug::TypeSubrange, getVoidTy(), Ops);
}

SPIRVEntry *LLVMToSPIRVDbgTran::transDbgTypeDef(const DIDerivedType *DT) {
using namespace SPIRVDebug::Operand::Typedef;
SPIRVWordVec Ops(OperandCount);
Expand Down
3 changes: 3 additions & 0 deletions lib/SPIRV/LLVMToSPIRVDbgTran.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class LLVMToSPIRVDbgTran {
SPIRVEntry *transDbgPointerType(const DIDerivedType *PT);
SPIRVEntry *transDbgQualifiedType(const DIDerivedType *QT);
SPIRVEntry *transDbgArrayType(const DICompositeType *AT);
SPIRVEntry *transDbgArrayTypeOpenCL(const DICompositeType *AT);
SPIRVEntry *transDbgArrayTypeNonSemantic(const DICompositeType *AT);
SPIRVEntry *transDbgSubrangeType(const DISubrange *ST);
SPIRVEntry *transDbgTypeDef(const DIDerivedType *D);
SPIRVEntry *transDbgSubroutineType(const DISubroutineType *FT);
SPIRVEntry *transDbgEnumType(const DICompositeType *ET);
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2298,6 +2298,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
return mapValue(BV, transOCLBuiltinFromExtInst(ExtInst, BB));
case SPIRVEIS_Debug:
case SPIRVEIS_OpenCL_DebugInfo_100:
case SPIRVEIS_NonSemantic_Kernel_DebugInfo_100:
return mapValue(BV, DbgTran->transDebugIntrinsic(ExtInst, BB));
default:
llvm_unreachable("Unknown extended instruction set!");
Expand Down
68 changes: 67 additions & 1 deletion lib/SPIRV/SPIRVToLLVMDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ SPIRVExtInst *SPIRVToLLVMDbgTran::getDbgInst(const SPIRVId Id) {
if (isa<OpExtInst>(E)) {
SPIRVExtInst *EI = static_cast<SPIRVExtInst *>(E);
if (EI->getExtSetKind() == SPIRV::SPIRVEIS_Debug ||
EI->getExtSetKind() == SPIRV::SPIRVEIS_OpenCL_DebugInfo_100)
EI->getExtSetKind() == SPIRV::SPIRVEIS_OpenCL_DebugInfo_100 ||
EI->getExtSetKind() == SPIRV::SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
return EI;
}
return nullptr;
Expand Down Expand Up @@ -192,6 +193,14 @@ DIType *SPIRVToLLVMDbgTran::transTypePointer(const SPIRVExtInst *DebugInst) {

DICompositeType *
SPIRVToLLVMDbgTran::transTypeArray(const SPIRVExtInst *DebugInst) {
if (DebugInst->getExtSetKind() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
return transTypeArrayNonSemantic(DebugInst);

return transTypeArrayOpenCL(DebugInst);
}

DICompositeType *
SPIRVToLLVMDbgTran::transTypeArrayOpenCL(const SPIRVExtInst *DebugInst) {
using namespace SPIRVDebug::Operand::TypeArray;
const SPIRVWordVec &Ops = DebugInst->getArguments();
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
Expand Down Expand Up @@ -246,6 +255,28 @@ SPIRVToLLVMDbgTran::transTypeArray(const SPIRVExtInst *DebugInst) {
return Builder.createArrayType(Size, 0 /*align*/, BaseTy, SubscriptArray);
}

DICompositeType *
SPIRVToLLVMDbgTran::transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst) {
using namespace SPIRVDebug::Operand::TypeArray;
const SPIRVWordVec &Ops = DebugInst->getArguments();
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
DIType *BaseTy =
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
size_t TotalCount = 1;
SmallVector<llvm::Metadata *, 8> Subscripts;
if (DebugInst->getExtOp() == SPIRVDebug::TypeArray) {
for (size_t I = SubrangesIdx; I < Ops.size(); ++I) {
auto *SR = transDebugInst<DISubrange>(BM->get<SPIRVExtInst>(Ops[I]));
if (auto *Count = SR->getCount().get<ConstantInt *>())
TotalCount *= Count->getZExtValue() > 0 ? Count->getZExtValue() : 0;
Subscripts.push_back(SR);
}
}
DINodeArray SubscriptArray = Builder.getOrCreateArray(Subscripts);
size_t Size = getDerivedSizeInBits(BaseTy) * TotalCount;
return Builder.createArrayType(Size, 0 /*align*/, BaseTy, SubscriptArray);
}

DICompositeType *
SPIRVToLLVMDbgTran::transTypeVector(const SPIRVExtInst *DebugInst) {
using namespace SPIRVDebug::Operand::TypeVector;
Expand Down Expand Up @@ -286,6 +317,8 @@ SPIRVToLLVMDbgTran::transTypeComposite(const SPIRVExtInst *DebugInst) {
SPIRVEntry *SizeEntry = BM->getEntry(Ops[SizeIdx]);
if (!(SizeEntry->isExtInst(SPIRVEIS_Debug, SPIRVDebug::DebugInfoNone) ||
SizeEntry->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100,
SPIRVDebug::DebugInfoNone) ||
SizeEntry->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
SPIRVDebug::DebugInfoNone))) {
Size = BM->get<SPIRVConstant>(Ops[SizeIdx])->getZExtIntValue();
}
Expand Down Expand Up @@ -341,6 +374,36 @@ SPIRVToLLVMDbgTran::transTypeComposite(const SPIRVExtInst *DebugInst) {
return CT;
}

DISubrange *
SPIRVToLLVMDbgTran::transTypeSubrange(const SPIRVExtInst *DebugInst) {
using namespace SPIRVDebug::Operand::TypeSubrange;
const SPIRVWordVec &Ops = DebugInst->getArguments();
assert(Ops.size() == OperandCount && "Invalid number of operands");
std::vector<Metadata *> TranslatedOps(OperandCount, nullptr);
auto TransOperand = [&Ops, &TranslatedOps, this](int Idx) -> void {
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[Idx])) {
if (auto *GlobalVar = getDbgInst<SPIRVDebug::GlobalVariable>(Ops[Idx])) {
TranslatedOps[Idx] =
cast<Metadata>(transDebugInst<DIGlobalVariable>(GlobalVar));
} else if (auto *LocalVar =
getDbgInst<SPIRVDebug::LocalVariable>(Ops[Idx])) {
TranslatedOps[Idx] =
cast<Metadata>(transDebugInst<DILocalVariable>(LocalVar));
} else if (auto *Expr = getDbgInst<SPIRVDebug::Expression>(Ops[Idx])) {
TranslatedOps[Idx] = cast<Metadata>(transDebugInst<DIExpression>(Expr));
} else if (auto *Const = BM->get<SPIRVConstant>(Ops[Idx])) {
int64_t ConstantAsInt = static_cast<int64_t>(Const->getZExtIntValue());
TranslatedOps[Idx] = cast<Metadata>(ConstantAsMetadata::get(
ConstantInt::get(M->getContext(), APInt(64, ConstantAsInt))));
}
}
};
for (int Idx = CountIdx; Idx < OperandCount; ++Idx)
TransOperand(Idx);
return Builder.getOrCreateSubrange(TranslatedOps[0], TranslatedOps[1],
TranslatedOps[2], TranslatedOps[3]);
}

DINode *SPIRVToLLVMDbgTran::transTypeMember(const SPIRVExtInst *DebugInst) {
using namespace SPIRVDebug::Operand::TypeMember;
const SPIRVWordVec &Ops = DebugInst->getArguments();
Expand Down Expand Up @@ -887,6 +950,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
case SPIRVDebug::TypeArray:
return transTypeArray(DebugInst);

case SPIRVDebug::TypeSubrange:
return transTypeSubrange(DebugInst);

case SPIRVDebug::TypeVector:
return transTypeVector(DebugInst);

Expand Down
8 changes: 7 additions & 1 deletion lib/SPIRV/SPIRVToLLVMDbgTran.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class SPIRVToLLVMDbgTran {
template <typename T = MDNode>
T *transDebugInst(const SPIRVExtInst *DebugInst) {
assert((DebugInst->getExtSetKind() == SPIRVEIS_Debug ||
DebugInst->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100) &&
DebugInst->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100 ||
DebugInst->getExtSetKind() ==
SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) &&
"Unexpected extended instruction set");
auto It = DebugInstCache.find(DebugInst);
if (It != DebugInstCache.end())
Expand Down Expand Up @@ -108,11 +110,15 @@ class SPIRVToLLVMDbgTran {
DIType *transTypePointer(const SPIRVExtInst *DebugInst);

DICompositeType *transTypeArray(const SPIRVExtInst *DebugInst);
DICompositeType *transTypeArrayOpenCL(const SPIRVExtInst *DebugInst);
DICompositeType *transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst);

DICompositeType *transTypeVector(const SPIRVExtInst *DebugInst);

DICompositeType *transTypeComposite(const SPIRVExtInst *DebugInst);

DISubrange *transTypeSubrange(const SPIRVExtInst *DebugInst);

DINode *transTypeMember(const SPIRVExtInst *DebugInst);

DINode *transTypeEnum(const SPIRVExtInst *DebugInst);
Expand Down
14 changes: 13 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRV.debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ enum Instruction {
ImportedEntity = 34,
Source = 35,
ModuleINTEL = 36,
InstCount = 37
InstCount = 37,
TypeSubrange = 110
};

enum Flag {
Expand Down Expand Up @@ -323,12 +324,23 @@ namespace TypeArray {
enum {
BaseTypeIdx = 0,
ComponentCountIdx = 1,
SubrangesIdx = 1,
MinOperandCount = 2
};
}

namespace TypeVector = TypeArray;

namespace TypeSubrange {
enum {
CountIdx = 0,
LowerBoundIdx = 1,
UpperBoundIdx = 2,
StrideIdx = 3,
OperandCount = 4
};
}

namespace Typedef {
enum {
NameIdx = 0,
Expand Down
3 changes: 3 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ enum SPIRVExtInstSetKind {
SPIRVEIS_OpenCL,
SPIRVEIS_Debug,
SPIRVEIS_OpenCL_DebugInfo_100,
SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
SPIRVEIS_Count,
};

Expand Down Expand Up @@ -129,6 +130,8 @@ template <> inline void SPIRVMap<SPIRVExtInstSetKind, std::string>::init() {
add(SPIRVEIS_OpenCL, "OpenCL.std");
add(SPIRVEIS_Debug, "SPIRV.debug");
add(SPIRVEIS_OpenCL_DebugInfo_100, "OpenCL.DebugInfo.100");
add(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
"NonSemantic.Kernel.DebugInfo.100");
}
typedef SPIRVMap<SPIRVExtInstSetKind, std::string> SPIRVBuiltinSetNameMap;

Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVExtInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ template <> inline void SPIRVMap<SPIRVDebugExtOpKind, std::string>::init() {
"DebugTemplateTemplateParameter");
add(SPIRVDebug::TypeTemplate, "DebugTemplate");
add(SPIRVDebug::TypePtrToMember, "DebugTypePtrToMember,");
add(SPIRVDebug::TypeSubrange, "DebugTypeSubrange");
add(SPIRVDebug::Inheritance, "DebugInheritance");
add(SPIRVDebug::Function, "DebugFunction");
add(SPIRVDebug::FunctionDecl, "DebugFunctionDecl");
Expand Down
6 changes: 5 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,14 @@ bool SPIRVFunction::decodeBB(SPIRVDecoder &Decoder) {
Module->add(Inst);
} else {
if (Inst->isExtInst(SPIRVEIS_Debug, SPIRVDebug::Scope) ||
Inst->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100, SPIRVDebug::Scope)) {
Inst->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100, SPIRVDebug::Scope) ||
Inst->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
SPIRVDebug::Scope)) {
DebugScope = Inst;
} else if (Inst->isExtInst(SPIRVEIS_Debug, SPIRVDebug::NoScope) ||
Inst->isExtInst(SPIRVEIS_OpenCL_DebugInfo_100,
SPIRVDebug::NoScope) ||
Inst->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
SPIRVDebug::NoScope)) {
DebugScope = nullptr;
} else {
Expand Down
5 changes: 4 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1761,7 +1761,8 @@ class SPIRVExtInst : public SPIRVFunctionCallGeneric<OpExtInst, 5> {
assert(Module && "Invalid module");
ExtSetKind = Module->getBuiltinSet(ExtSetId);
assert((ExtSetKind == SPIRVEIS_OpenCL || ExtSetKind == SPIRVEIS_Debug ||
ExtSetKind == SPIRVEIS_OpenCL_DebugInfo_100) &&
ExtSetKind == SPIRVEIS_OpenCL_DebugInfo_100 ||
ExtSetKind == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) &&
"not supported");
}
void encode(spv_ostream &O) const override {
Expand All @@ -1772,6 +1773,7 @@ class SPIRVExtInst : public SPIRVFunctionCallGeneric<OpExtInst, 5> {
break;
case SPIRVEIS_Debug:
case SPIRVEIS_OpenCL_DebugInfo_100:
case SPIRVEIS_NonSemantic_Kernel_DebugInfo_100:
getEncoder(O) << ExtOpDebug;
break;
default:
Expand All @@ -1789,6 +1791,7 @@ class SPIRVExtInst : public SPIRVFunctionCallGeneric<OpExtInst, 5> {
break;
case SPIRVEIS_Debug:
case SPIRVEIS_OpenCL_DebugInfo_100:
case SPIRVEIS_NonSemantic_Kernel_DebugInfo_100:
getDecoder(I) >> ExtOpDebug;
break;
default:
Expand Down
3 changes: 2 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,8 @@ void SPIRVModuleImpl::layoutEntry(SPIRVEntry *E) {
case OpExtInst: {
SPIRVExtInst *EI = static_cast<SPIRVExtInst *>(E);
if ((EI->getExtSetKind() == SPIRVEIS_Debug ||
EI->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100) &&
EI->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100 ||
EI->getExtSetKind() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) &&
EI->getExtOp() != SPIRVDebug::Declare &&
EI->getExtOp() != SPIRVDebug::Value &&
EI->getExtOp() != SPIRVDebug::Scope &&
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,8 @@ class SPIRVModule {
return SPIRVEIS_Debug;
case DebugInfoEIS::OpenCL_DebugInfo_100:
return SPIRVEIS_OpenCL_DebugInfo_100;
case DebugInfoEIS::NonSemantic_Kernel_DebugInfo_100:
return SPIRVEIS_NonSemantic_Kernel_DebugInfo_100;
}
assert(false && "Unexpected debug info EIS!");
return SPIRVEIS_Debug;
Expand Down
Loading

0 comments on commit 8e8ef50

Please sign in to comment.