Skip to content

Commit 3f93ae9

Browse files
committed
[SPIR-V] Emit DebugTypePointer in NonSemantic DI
Implementation of DI instruction from NonSemantic.Shader.DebugInfo.100.
1 parent c71b212 commit 3f93ae9

File tree

3 files changed

+318
-7
lines changed

3 files changed

+318
-7
lines changed

llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
8888
int64_t DwarfVersion = 0;
8989
int64_t DebugInfoVersion = 0;
9090
SmallPtrSet<DIBasicType *, 12> BasicTypes;
91+
SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;
9192
// Searching through the Module metadata to find nescessary
9293
// information like DwarfVersion or SourceLanguage
9394
{
@@ -129,8 +130,22 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
129130
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
130131
DILocalVariable *LocalVariable = DVR.getVariable();
131132
if (auto *BasicType =
132-
dyn_cast<DIBasicType>(LocalVariable->getType()))
133+
dyn_cast<DIBasicType>(LocalVariable->getType())) {
133134
BasicTypes.insert(BasicType);
135+
} else if (auto *DerivedType =
136+
dyn_cast<DIDerivedType>(LocalVariable->getType())) {
137+
if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
138+
PointerDerivedTypes.insert(DerivedType);
139+
// DIBasicType can be unreachable from DbgRecord and only
140+
// pointed on from other DI types
141+
// DerivedType->getBaseType is null when pointer
142+
// is representing a void type
143+
if (DerivedType->getBaseType()) {
144+
BasicTypes.insert(
145+
cast<DIBasicType>(DerivedType->getBaseType()));
146+
}
147+
}
148+
}
134149
}
135150
}
136151
}
@@ -160,7 +175,6 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
160175
return StrReg;
161176
};
162177

163-
// Emit OpString with FilePath which is required by DebugSource
164178
const Register FilePathStrReg = EmitOpString(FilePath);
165179

166180
const SPIRVType *VoidTy =
@@ -187,15 +201,12 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
187201
return InstReg;
188202
};
189203

190-
// Emit DebugSource which is required by DebugCompilationUnit
191204
const Register DebugSourceResIdReg = EmitDIInstruction(
192205
SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
193206

194207
const SPIRVType *I32Ty =
195208
GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
196209

197-
// Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
198-
// instructions required by DebugCompilationUnit
199210
const Register DwarfVersionReg =
200211
GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
201212
const Register DebugInfoVersionReg =
@@ -214,6 +225,11 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
214225
const Register I32ZeroReg =
215226
GR->buildConstantInt(0, MIRBuilder, I32Ty, false);
216227

228+
// We need to store pairs because further instructions reference
229+
// the DIBasicTypes and size will be always small so there isn't
230+
// need for any kind of map
231+
SmallVector<std::pair<const DIBasicType *const, const Register>, 12>
232+
BasicTypeRegPairs;
217233
for (auto *BasicType : BasicTypes) {
218234
const Register BasicTypeStrReg = EmitOpString(BasicType->getName());
219235

@@ -247,11 +263,31 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
247263
const Register AttributeEncodingReg =
248264
GR->buildConstantInt(AttributeEncoding, MIRBuilder, I32Ty, false);
249265

250-
[[maybe_unused]]
251266
const Register BasicTypeReg =
252267
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,
253268
{BasicTypeStrReg, ConstIntBitwidthReg,
254269
AttributeEncodingReg, I32ZeroReg});
270+
BasicTypeRegPairs.emplace_back(BasicType, BasicTypeReg);
271+
}
272+
273+
if (PointerDerivedTypes.size()) {
274+
const Register GenericStorageClass =
275+
GR->buildConstantInt(8, MIRBuilder, I32Ty, false);
276+
for (const auto *PointerDerivedType : PointerDerivedTypes) {
277+
// If the Pointer is representing a void type it's getBaseType
278+
// is a nullptr
279+
const auto *MaybeBT =
280+
cast_or_null<DIBasicType>(PointerDerivedType->getBaseType());
281+
for (const auto &BasicTypeRegPair : BasicTypeRegPairs) {
282+
const auto &[SBT, Reg] = BasicTypeRegPair;
283+
if (SBT == MaybeBT) {
284+
[[maybe_unused]]
285+
const Register DebugPointerTypeReg =
286+
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypePointer,
287+
{Reg, GenericStorageClass, I32ZeroReg});
288+
}
289+
}
290+
}
255291
}
256292
}
257293
return true;

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
436436
namespace NS = SPIRV::NonSemanticExtInst;
437437
static constexpr int64_t GlobalNonSemanticDITy[] = {
438438
NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
439-
NS::DebugTypeBasic};
439+
NS::DebugTypeBasic, NS::DebugTypePointer};
440440
bool IsGlobalDI = false;
441441
for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
442442
IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];

0 commit comments

Comments
 (0)