Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
81 changes: 63 additions & 18 deletions lib/SPIRV/LLVMToSPIRVDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgEntryImpl(const MDNode *MDN) {
case dwarf::DW_TAG_array_type:
return transDbgArrayType(cast<DICompositeType>(DIEntry));

case dwarf::DW_TAG_subrange_type:
return transDbgSubrangeType(cast<DISubrange>(DIEntry));
Comment thread
vmaksimo marked this conversation as resolved.
Outdated

case dwarf::DW_TAG_const_type:
case dwarf::DW_TAG_restrict_type:
case dwarf::DW_TAG_volatile_type:
Expand Down Expand Up @@ -560,8 +563,7 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
DINodeArray AR(AT->getElements());
// For N-dimensianal arrays AR.getNumElements() == N
const unsigned N = AR.size();
Ops.resize(ComponentCountIdx + N);
SPIRVWordVec LowerBounds(N);
Ops.resize(SubrangesIdx + N);
for (unsigned I = 0; I < N; ++I) {
DISubrange *SR = cast<DISubrange>(AR[I]);
ConstantInt *Count = SR->getCount().get<ConstantInt *>();
Expand All @@ -570,30 +572,73 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
Ops[ComponentCountIdx] = static_cast<SPIRVWord>(Count->getZExtValue());
return BM->addDebugInfo(SPIRVDebug::TypeVector, getVoidTy(), Ops);
}
if (Count) {
Ops[ComponentCountIdx + I] =
SPIRVWriter->transValue(Count, nullptr)->getId();
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) {
Ops[SubrangesIdx + I] = transDbgEntry(SR)->getId();
} else {
if (auto *UpperBound = dyn_cast<MDNode>(SR->getRawUpperBound()))
Ops[ComponentCountIdx + I] = transDbgEntry(UpperBound)->getId();
// According to the OpenCL.DebugInfo.100 specification Count must be a
// Constant or DIVariable. No other operands must be preserved.
if (Count)
Ops[ComponentCountIdx + I] =
SPIRVWriter->transValue(Count, nullptr)->getId();
else if (auto *CountNode =
dyn_cast_or_null<MDNode>(SR->getRawCountNode()))
Ops[ComponentCountIdx + I] = transDbgEntry(CountNode)->getId();
else
Ops[ComponentCountIdx + I] = getDebugInfoNoneId();
}
if (auto *RawLB = SR->getRawLowerBound()) {
if (auto *DIExprLB = dyn_cast<MDNode>(RawLB))
LowerBounds[I] = transDbgEntry(DIExprLB)->getId();
else {
ConstantInt *ConstIntLB = SR->getLowerBound().get<ConstantInt *>();
LowerBounds[I] = SPIRVWriter->transValue(ConstIntLB, nullptr)->getId();
}
} else {
LowerBounds[I] = getDebugInfoNoneId();
}
}
Ops.insert(Ops.end(), LowerBounds.begin(), LowerBounds.end());
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;
} else 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
1 change: 1 addition & 0 deletions lib/SPIRV/LLVMToSPIRVDbgTran.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class LLVMToSPIRVDbgTran {
SPIRVEntry *transDbgPointerType(const DIDerivedType *PT);
SPIRVEntry *transDbgQualifiedType(const DIDerivedType *QT);
SPIRVEntry *transDbgArrayType(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
97 changes: 62 additions & 35 deletions 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 @@ -199,46 +200,37 @@ SPIRVToLLVMDbgTran::transTypeArray(const SPIRVExtInst *DebugInst) {
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
size_t TotalCount = 1;
SmallVector<llvm::Metadata *, 8> Subscripts;
// Ops looks like: { BaseType, count1|upperBound1, count2|upperBound2, ...,
// countN|upperBoundN, lowerBound1, lowerBound2, ..., lowerBoundN }
for (size_t I = ComponentCountIdx, E = Ops.size() / 2 + 1; I < E; ++I) {
if (auto *LocalVar = getDbgInst<SPIRVDebug::LocalVariable>(Ops[I])) {
auto *UpperBound = transDebugInst<DILocalVariable>(LocalVar);
SPIRVConstant *C = BM->get<SPIRVConstant>(Ops[Ops.size() / 2 + I]);
int64_t ConstantAsInt = static_cast<int64_t>(C->getZExtIntValue());
auto *LowerBound = ConstantAsMetadata::get(
ConstantInt::get(M->getContext(), APInt(64, ConstantAsInt)));
Subscripts.push_back(Builder.getOrCreateSubrange(nullptr, LowerBound,
UpperBound, nullptr));
continue;
if (DebugInst->isExtInst(SPIRVEIS_NonSemantic_Kernel_DebugInfo_100,
Comment thread
MrSidims marked this conversation as resolved.
Outdated
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);
}
if (auto *ExprUB = getDbgInst<SPIRVDebug::Expression>(Ops[I])) {
auto *UpperBound = transDebugInst<DIExpression>(ExprUB);
auto *ExprLB =
getDbgInst<SPIRVDebug::Expression>(Ops[Ops.size() / 2 + I]);
auto *LowerBound = transDebugInst<DIExpression>(ExprLB);
Subscripts.push_back(Builder.getOrCreateSubrange(nullptr, LowerBound,
UpperBound, nullptr));
continue;
}
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[I])) {
SPIRVConstant *C = BM->get<SPIRVConstant>(Ops[I]);
int64_t Count = static_cast<int64_t>(C->getZExtIntValue());
// If the SPIR-V file was generated by an older version of the translator,
// Ops may not contain the LowerBound
if (Ops.size() / 2 + I < Ops.size()) {
C = BM->get<SPIRVConstant>(Ops[Ops.size() / 2 + I]);
int64_t LowerBound = static_cast<int64_t>(C->getZExtIntValue());
Subscripts.push_back(Builder.getOrCreateSubrange(LowerBound, Count));
} else {
} else {
for (size_t I = ComponentCountIdx, E = Ops.size(); I < E; ++I) {
// Otherwise Count could be a constant or DIVariable
if (auto *LocalVarCount = getDbgInst<SPIRVDebug::LocalVariable>(Ops[I])) {
auto *DILocalVarCount = transDebugInst<DILocalVariable>(LocalVarCount);
Subscripts.push_back(Builder.getOrCreateSubrange(
DILocalVarCount, nullptr, nullptr, nullptr));
} else if (auto *GlobalVarCount =
getDbgInst<SPIRVDebug::GlobalVariable>(Ops[I])) {
auto *DIGlobalVarCount =
transDebugInst<DIGlobalVariable>(GlobalVarCount);
Subscripts.push_back(Builder.getOrCreateSubrange(
DIGlobalVarCount, nullptr, nullptr, nullptr));
} else if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[I])) {
SPIRVConstant *C = BM->get<SPIRVConstant>(Ops[I]);
int64_t Count = static_cast<int64_t>(C->getZExtIntValue());
// Count = -1 means that the array is empty
TotalCount *= Count > 0 ? Count : 0;
auto *CountAsMD = ConstantAsMetadata::get(
ConstantInt::get(M->getContext(), APInt(64, Count)));
Subscripts.push_back(
Builder.getOrCreateSubrange(CountAsMD, nullptr, nullptr, nullptr));
}
// Count = -1 means that the array is empty
TotalCount *= Count > 0 ? static_cast<size_t>(Count) : 0;
continue;
}
}
DINodeArray SubscriptArray = Builder.getOrCreateArray(Subscripts);
Expand Down Expand Up @@ -286,6 +278,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 +335,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 +911,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
6 changes: 5 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 @@ -113,6 +115,8 @@ class SPIRVToLLVMDbgTran {

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
Loading