27#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
41 bool IsGlobalDIEmitted =
false;
47 "SPIRV NonSemantic.Shader.DebugInfo.100 emitter",
false,
false)
49char SPIRVEmitNonSemanticDI::
ID = 0;
53 return new SPIRVEmitNonSemanticDI(TM);
87 IsGlobalDIEmitted =
false;
95 int64_t DwarfVersion = 0;
96 int64_t DebugInfoVersion = 0;
97 SmallPtrSet<DIBasicType *, 12> BasicTypes;
98 SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;
102 const MachineModuleInfo &MMI =
103 getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
106 const NamedMDNode *DbgCu =
M->getNamedMetadata(
"llvm.dbg.cu");
111 DIFile *
File = CompileUnit->getFile();
114 File->getFilename());
115 LLVMSourceLanguages.
push_back(CompileUnit->getSourceLanguage());
118 const NamedMDNode *ModuleFlags =
M->getNamedMetadata(
"llvm.module.flags");
119 assert(ModuleFlags &&
"Expected llvm.module.flags metadata to be present");
120 for (
const auto *
Op : ModuleFlags->
operands()) {
121 const MDOperand &MaybeStrOp =
Op->getOperand(1);
122 if (MaybeStrOp.
equalsStr(
"Dwarf Version"))
127 else if (MaybeStrOp.
equalsStr(
"Debug Info Version"))
139 for (DbgVariableRecord &DVR :
filterDbgVars(
I.getDbgRecordRange())) {
140 DILocalVariable *LocalVariable = DVR.getVariable();
141 if (
auto *BasicType =
143 BasicTypes.
insert(BasicType);
144 }
else if (
auto *DerivedType =
146 if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
147 PointerDerivedTypes.
insert(DerivedType);
153 DerivedType->getBaseType()))
170 MachineBasicBlock &
MBB = *MF.
begin();
177 const auto EmitOpString = [&](StringRef SR) {
178 const Register StrReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
180 MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
188 SPIRV::AccessQualifier::ReadWrite,
false);
190 const auto EmitDIInstruction =
191 [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
192 std::initializer_list<Register>
Registers) {
194 MRI.createVirtualRegister(&SPIRV::IDRegClass);
196 MachineInstrBuilder MIB =
197 MIRBuilder.buildInstr(SPIRV::OpExtInst)
200 .
addImm(
static_cast<int64_t
>(
201 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
213 SPIRV::AccessQualifier::ReadWrite,
false);
218 const Register DebugInfoVersionReg =
221 for (
unsigned Idx = 0; Idx < LLVMSourceLanguages.
size(); ++Idx) {
222 const Register FilePathStrReg = EmitOpString(FilePaths[Idx]);
224 const Register DebugSourceResIdReg = EmitDIInstruction(
225 SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
228 switch (LLVMSourceLanguages[Idx]) {
229 case dwarf::DW_LANG_OpenCL:
232 case dwarf::DW_LANG_OpenCL_CPP:
235 case dwarf::DW_LANG_CPP_for_OpenCL:
238 case dwarf::DW_LANG_GLSL:
241 case dwarf::DW_LANG_HLSL:
244 case dwarf::DW_LANG_SYCL:
247 case dwarf::DW_LANG_Zig:
255 const Register DebugCompUnitResIdReg =
256 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugCompilationUnit,
257 {DebugInfoVersionReg, DwarfVersionReg,
258 DebugSourceResIdReg, SourceLanguageReg});
271 for (
auto *BasicType : BasicTypes) {
272 const Register BasicTypeStrReg = EmitOpString(BasicType->getName());
275 BasicType->getSizeInBits(), MIRBuilder, I32Ty,
false);
278 switch (BasicType->getEncoding()) {
279 case dwarf::DW_ATE_signed:
282 case dwarf::DW_ATE_unsigned:
285 case dwarf::DW_ATE_unsigned_char:
288 case dwarf::DW_ATE_signed_char:
291 case dwarf::DW_ATE_float:
294 case dwarf::DW_ATE_boolean:
297 case dwarf::DW_ATE_address:
301 const Register AttributeEncodingReg =
305 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,
306 {BasicTypeStrReg, ConstIntBitwidthReg,
307 AttributeEncodingReg, I32ZeroReg});
308 BasicTypeRegPairs.
emplace_back(BasicType, BasicTypeReg);
311 if (PointerDerivedTypes.
size()) {
312 for (
const auto *PointerDerivedType : PointerDerivedTypes) {
314 assert(PointerDerivedType->getDWARFAddressSpace().has_value());
317 PointerDerivedType->getDWARFAddressSpace().value(),
319 MIRBuilder, I32Ty,
false);
323 const auto *MaybeNestedBasicType =
325 if (MaybeNestedBasicType) {
326 for (
const auto &BasicTypeRegPair : BasicTypeRegPairs) {
327 const auto &[DefinedBasicType, BasicTypeReg] = BasicTypeRegPair;
328 if (DefinedBasicType == MaybeNestedBasicType) {
330 const Register DebugPointerTypeReg = EmitDIInstruction(
331 SPIRV::NonSemanticExtInst::DebugTypePointer,
332 {BasicTypeReg, StorageClassReg, I32ZeroReg});
337 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugInfoNone, {});
339 const Register DebugPointerTypeReg = EmitDIInstruction(
340 SPIRV::NonSemanticExtInst::DebugTypePointer,
341 {DebugInfoNoneReg, StorageClassReg, I32ZeroReg});
349bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
353 if (!IsGlobalDIEmitted) {
354 IsGlobalDIEmitted =
true;
355 Res = emitGlobalDI(MF);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
Machine Check Debug Module
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
SI Pre allocate WWM Registers
BaseTypeAttributeEncoding
This file defines the SmallPtrSet class.
This file defines the SmallString class.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
bool equalsStr(StringRef Str) const
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
const Module * getModule() const
iterator_range< op_iterator > operands()
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR, bool ZeroAsNull=true)
const SPIRVInstrInfo * getInstrInfo() const override
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
const SPIRVRegisterInfo * getRegisterInfo() const override
const RegisterBankInfo * getRegBankInfo() const override
const SPIRVSubtarget * getSubtargetImpl() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
MachineFunctionPass * createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_or_null(const Y &Val)
const MachineInstr SPIRVType
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void addStringImm(const StringRef &Str, MCInst &Inst)
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.