Skip to content

Commit

Permalink
[SPIR-V] Emit DebugTypePointer in NonSemantic DI
Browse files Browse the repository at this point in the history
Implementation of DI instruction from NonSemantic.Shader.DebugInfo.100.
  • Loading branch information
bwlodarcz committed Sep 27, 2024
1 parent 5cc64bf commit 428e06e
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 4 deletions.
61 changes: 58 additions & 3 deletions llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "SPIRVGlobalRegistry.h"
#include "SPIRVRegisterInfo.h"
#include "SPIRVTargetMachine.h"
#include "SPIRVUtils.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/BinaryFormat/Dwarf.h"
Expand Down Expand Up @@ -104,6 +105,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
int64_t DwarfVersion = 0;
int64_t DebugInfoVersion = 0;
SmallPtrSet<DIBasicType *, 12> BasicTypes;
SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;
// Searching through the Module metadata to find nescessary
// information like DwarfVersion or SourceLanguage
{
Expand Down Expand Up @@ -146,8 +148,21 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
DILocalVariable *LocalVariable = DVR.getVariable();
if (auto *BasicType =
dyn_cast<DIBasicType>(LocalVariable->getType()))
dyn_cast<DIBasicType>(LocalVariable->getType())) {
BasicTypes.insert(BasicType);
} else if (auto *DerivedType =
dyn_cast<DIDerivedType>(LocalVariable->getType())) {
if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
PointerDerivedTypes.insert(DerivedType);
// DIBasicType can be unreachable from DbgRecord and only
// pointed on from other DI types
// DerivedType->getBaseType is null when pointer
// is representing a void type
if (DerivedType->getBaseType())
BasicTypes.insert(
cast<DIBasicType>(DerivedType->getBaseType()));
}
}
}
}
}
Expand Down Expand Up @@ -206,6 +221,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {

const Register DwarfVersionReg =
GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);

const Register DebugInfoVersionReg =
GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);

Expand Down Expand Up @@ -237,7 +253,6 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
break;
case dwarf::DW_LANG_Zig:
SpirvSourceLanguage = SourceLanguage::Zig;
break;
}

const Register SourceLanguageReg =
Expand All @@ -255,6 +270,11 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
const Register I32ZeroReg =
GR->buildConstantInt(0, MIRBuilder, I32Ty, false);

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

Expand Down Expand Up @@ -288,11 +308,46 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
const Register AttributeEncodingReg =
GR->buildConstantInt(AttributeEncoding, MIRBuilder, I32Ty, false);

[[maybe_unused]]
const Register BasicTypeReg =
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,
{BasicTypeStrReg, ConstIntBitwidthReg,
AttributeEncodingReg, I32ZeroReg});
BasicTypeRegPairs.emplace_back(BasicType, BasicTypeReg);
}

if (PointerDerivedTypes.size()) {
for (const auto *PointerDerivedType : PointerDerivedTypes) {

assert(PointerDerivedType->getDWARFAddressSpace().has_value());
const Register StorageClassReg = GR->buildConstantInt(
addressSpaceToStorageClass(
PointerDerivedType->getDWARFAddressSpace().value(),
*TM->getSubtargetImpl()),
MIRBuilder, I32Ty, false);

// If the Pointer is representing a void type it's getBaseType
// is a nullptr
const auto *MaybeNestedBasicType =
cast_or_null<DIBasicType>(PointerDerivedType->getBaseType());
if (MaybeNestedBasicType) {
for (const auto &BasicTypeRegPair : BasicTypeRegPairs) {
const auto &[DefinedBasicType, BasicTypeReg] = BasicTypeRegPair;
if (DefinedBasicType == MaybeNestedBasicType) {
[[maybe_unused]]
const Register DebugPointerTypeReg = EmitDIInstruction(
SPIRV::NonSemanticExtInst::DebugTypePointer,
{BasicTypeReg, StorageClassReg, I32ZeroReg});
}
}
} else {
const Register DebugInfoNoneReg =
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugInfoNone, {});
[[maybe_unused]]
const Register DebugPointerTypeReg = EmitDIInstruction(
SPIRV::NonSemanticExtInst::DebugTypePointer,
{DebugInfoNoneReg, StorageClassReg, I32ZeroReg});
}
}
}
}
return true;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
namespace NS = SPIRV::NonSemanticExtInst;
static constexpr int64_t GlobalNonSemanticDITy[] = {
NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
NS::DebugTypeBasic};
NS::DebugTypeBasic, NS::DebugTypePointer};
bool IsGlobalDI = false;
for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
Expand Down
Loading

0 comments on commit 428e06e

Please sign in to comment.