Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIR-V] Emit DebugTypeBasic for NonSemantic DI #106980

Merged
merged 6 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
149 changes: 116 additions & 33 deletions llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include "SPIRVGlobalRegistry.h"
#include "SPIRVRegisterInfo.h"
#include "SPIRVTargetMachine.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
Expand All @@ -13,7 +15,10 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/Metadata.h"
#include "llvm/PassRegistry.h"
#include "llvm/Support/Casting.h"
Expand Down Expand Up @@ -57,6 +62,17 @@ SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
}

enum BaseTypeAttributeEncoding {
Unspecified = 0,
Address = 1,
Boolean = 2,
Float = 3,
Signed = 4,
SignedChar = 5,
Unsigned = 6,
UnsignedChar = 7
};

bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
// If this MachineFunction doesn't have any BB repeat procedure
// for the next
Expand All @@ -71,7 +87,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
unsigned SourceLanguage = 0;
int64_t DwarfVersion = 0;
int64_t DebugInfoVersion = 0;

SmallSet<DIBasicType *, 12> BasicTypes;
bwlodarcz marked this conversation as resolved.
Show resolved Hide resolved
// Searching through the Module metadata to find nescessary
// information like DwarfVersion or SourceLanguage
{
Expand Down Expand Up @@ -104,6 +120,23 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
->getSExtValue();
}

// This traversal is the only supported way to access
// instruction related DI metadata like DIBasicType
for (auto &F : *M) {
for (auto &BB : F) {
bwlodarcz marked this conversation as resolved.
Show resolved Hide resolved
for (auto &I : BB) {
for (DbgRecord &DR : I.getDbgRecordRange()) {
if (auto *DVR = dyn_cast<DbgVariableRecord>(&DR)) {
DILocalVariable *LocalVariable = DVR->getVariable();
if (auto *BasicType =
dyn_cast<DIBasicType>(LocalVariable->getType()))
BasicTypes.insert(BasicType);
}
}
}
}
}
}
// NonSemantic.Shader.DebugInfo.100 global DI instruction emitting
{
Expand All @@ -120,29 +153,45 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
// and before first terminator
MachineIRBuilder MIRBuilder(MBB, MBB.getFirstTerminator());

const auto EmitOpString = [&](StringRef SR) {
const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(StrReg, LLT::scalar(32));
MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
MIB.addDef(StrReg);
addStringImm(SR, MIB);
return StrReg;
};

// Emit OpString with FilePath which is required by DebugSource
const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(StrReg, LLT::scalar(32));
MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
MIB.addDef(StrReg);
addStringImm(FilePath, MIB);
const Register FilePathStrReg = EmitOpString(FilePath);

const SPIRVType *VoidTy =
GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);

const auto EmitDIInstruction =
[&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
std::initializer_list<Register> Registers) {
const Register InstReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(InstReg, LLT::scalar(32));
MachineInstrBuilder MIB =
MIRBuilder.buildInstr(SPIRV::OpExtInst)
.addDef(InstReg)
.addUse(GR->getSPIRVTypeID(VoidTy))
.addImm(static_cast<int64_t>(
SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
.addImm(Inst);
for (auto Reg : Registers) {
MIB.addUse(Reg);
}
MIB.constrainAllUses(*TII, *TRI, *RBI);
GR->assignSPIRVTypeToVReg(VoidTy, InstReg, MF);
return InstReg;
};

// Emit DebugSource which is required by DebugCompilationUnit
const Register DebugSourceResIdReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
.addDef(DebugSourceResIdReg)
.addUse(GR->getSPIRVTypeID(VoidTy))
.addImm(static_cast<int64_t>(
SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
.addImm(SPIRV::NonSemanticExtInst::DebugSource)
.addUse(StrReg);
MIB.constrainAllUses(*TII, *TRI, *RBI);
GR->assignSPIRVTypeToVReg(VoidTy, DebugSourceResIdReg, MF);
const Register DebugSourceResIdReg = EmitDIInstruction(
SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});

const SPIRVType *I32Ty =
GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
Expand All @@ -156,22 +205,56 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
const Register SourceLanguageReg =
GR->buildConstantInt(SourceLanguage, MIRBuilder, I32Ty, false);

// Emit DebugCompilationUnit
[[maybe_unused]]
const Register DebugCompUnitResIdReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
.addDef(DebugCompUnitResIdReg)
.addUse(GR->getSPIRVTypeID(VoidTy))
.addImm(static_cast<int64_t>(
SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
.addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
.addUse(DebugInfoVersionReg)
.addUse(DwarfVersionReg)
.addUse(DebugSourceResIdReg)
.addUse(SourceLanguageReg);
MIB.constrainAllUses(*TII, *TRI, *RBI);
GR->assignSPIRVTypeToVReg(VoidTy, DebugCompUnitResIdReg, MF);
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugCompilationUnit,
{DebugInfoVersionReg, DwarfVersionReg,
DebugSourceResIdReg, SourceLanguageReg});

// Emit DebugInfoNone. This instruction is a wildcard accepted
// by standard to put into instruction arguments as Not Available/Null
const Register DebugInfoNoneReg =
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugInfoNone, {});

for (auto *BasicType : BasicTypes) {
const Register BasicTypeStrReg = EmitOpString(BasicType->getName());

const Register ConstIntBitwidthReg = GR->buildConstantInt(
BasicType->getSizeInBits(), MIRBuilder, I32Ty, false);

uint64_t AttributeEncoding = BaseTypeAttributeEncoding::Unspecified;
switch (BasicType->getEncoding()) {
case dwarf::DW_ATE_signed:
AttributeEncoding = BaseTypeAttributeEncoding::Signed;
break;
case dwarf::DW_ATE_unsigned:
AttributeEncoding = BaseTypeAttributeEncoding::Unsigned;
break;
case dwarf::DW_ATE_unsigned_char:
AttributeEncoding = BaseTypeAttributeEncoding::UnsignedChar;
break;
case dwarf::DW_ATE_signed_char:
AttributeEncoding = BaseTypeAttributeEncoding::SignedChar;
break;
case dwarf::DW_ATE_float:
AttributeEncoding = BaseTypeAttributeEncoding::Float;
break;
case dwarf::DW_ATE_boolean:
AttributeEncoding = BaseTypeAttributeEncoding::Boolean;
break;
case dwarf::DW_ATE_address:
AttributeEncoding = BaseTypeAttributeEncoding::Address;
}

const Register AttributeEncodingReg =
GR->buildConstantInt(AttributeEncoding, MIRBuilder, I32Ty, false);

[[maybe_unused]]
const Register BasicTypeReg =
bwlodarcz marked this conversation as resolved.
Show resolved Hide resolved
EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,
{BasicTypeStrReg, ConstIntBitwidthReg,
AttributeEncodingReg, DebugInfoNoneReg});
bwlodarcz marked this conversation as resolved.
Show resolved Hide resolved
}
}
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,8 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
MachineOperand Ins = MI.getOperand(3);
namespace NS = SPIRV::NonSemanticExtInst;
static constexpr int64_t GlobalNonSemanticDITy[] = {
NS::DebugSource, NS::DebugCompilationUnit};
NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
NS::DebugTypeBasic};
bool IsGlobalDI = false;
for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
Expand Down
Loading
Loading