Skip to content

Commit

Permalink
Initial support NonSemantic.Kernel.DebugInfo.100 (#1846)
Browse files Browse the repository at this point in the history
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 Feb 20, 2023
1 parent 4af277c commit daad382
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 daad382

Please sign in to comment.