LLVM: lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp Source File (original) (raw)
26
27#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
28
29using namespace llvm;
30
31namespace {
33 static char ID;
37
39
40private:
41 bool IsGlobalDIEmitted = false;
43};
44}
45
47 "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
48
49char SPIRVEmitNonSemanticDI::ID = 0;
50
53 return new SPIRVEmitNonSemanticDI(TM);
54}
55
66
82
83bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
84
85
87 IsGlobalDIEmitted = false;
88 return false;
89 }
90
91
95 int64_t DwarfVersion = 0;
96 int64_t DebugInfoVersion = 0;
97 SmallPtrSet<DIBasicType *, 12> BasicTypes;
98 SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;
99
100
101 {
102 const MachineModuleInfo &MMI =
103 getAnalysis().getMMI();
106 const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
107 if (!DbgCu)
108 return false;
109 for (const auto *Op : DbgCu->operands()) {
111 DIFile *File = CompileUnit->getFile();
114 File->getFilename());
116 CompileUnit->getSourceLanguage().getUnversionedName());
117 }
118 }
119 const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
120 assert(ModuleFlags && "Expected llvm.module.flags metadata to be present");
121 for (const auto *Op : ModuleFlags->operands()) {
122 const MDOperand &MaybeStrOp = Op->getOperand(1);
123 if (MaybeStrOp.equalsStr("Dwarf Version"))
124 DwarfVersion =
127 ->getSExtValue();
128 else if (MaybeStrOp.equalsStr("Debug Info Version"))
129 DebugInfoVersion =
132 ->getSExtValue();
133 }
134
135
136
137 for (auto &F : *M) {
138 for (auto &BB : F) {
139 for (auto &I : BB) {
140 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
141 DILocalVariable *LocalVariable = DVR.getVariable();
142 if (auto *BasicType =
144 BasicTypes.insert(BasicType);
145 } else if (auto *DerivedType =
147 if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
148 PointerDerivedTypes.insert(DerivedType);
149
150
151
152
154 DerivedType->getBaseType()))
156 }
157 }
158 }
159 }
160 }
161 }
162 }
163
164 {
165
171 MachineBasicBlock &MBB = *MF.begin();
172
173
174
175
177
178 const auto EmitOpString = [&](StringRef SR) {
179 const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
181 MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
184 return StrReg;
185 };
186
189 SPIRV::AccessQualifier::ReadWrite, false);
190
191 const auto EmitDIInstruction =
192 [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
193 std::initializer_list Registers) {
195 MRI.createVirtualRegister(&SPIRV::IDRegClass);
197 MachineInstrBuilder MIB =
198 MIRBuilder.buildInstr(SPIRV::OpExtInst)
201 .addImm(static_cast<int64_t>(
202 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
206 }
209 return InstReg;
210 };
211
214 SPIRV::AccessQualifier::ReadWrite, false);
215
216 const Register DwarfVersionReg =
217 GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
218
219 const Register DebugInfoVersionReg =
220 GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);
221
222 for (unsigned Idx = 0; Idx < LLVMSourceLanguages.size(); ++Idx) {
223 const Register FilePathStrReg = EmitOpString(FilePaths[Idx]);
224
225 const Register DebugSourceResIdReg = EmitDIInstruction(
226 SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
227
229 switch (LLVMSourceLanguages[Idx]) {
230 case dwarf::DW_LANG_OpenCL:
232 break;
233 case dwarf::DW_LANG_OpenCL_CPP:
235 break;
236 case dwarf::DW_LANG_CPP_for_OpenCL:
238 break;
239 case dwarf::DW_LANG_GLSL:
241 break;
242 case dwarf::DW_LANG_HLSL:
244 break;
245 case dwarf::DW_LANG_SYCL:
247 break;
248 case dwarf::DW_LANG_Zig:
250 }
251
252 const Register SourceLanguageReg =
253 GR->buildConstantInt(SpirvSourceLanguage, MIRBuilder, I32Ty, false);
254
255 [[maybe_unused]]
256 const Register DebugCompUnitResIdReg =
257 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugCompilationUnit,
258 {DebugInfoVersionReg, DwarfVersionReg,
259 DebugSourceResIdReg, SourceLanguageReg});
260 }
261
262
263
266
267
268
269
271 BasicTypeRegPairs;
272 for (auto *BasicType : BasicTypes) {
273 const Register BasicTypeStrReg = EmitOpString(BasicType->getName());
274
276 BasicType->getSizeInBits(), MIRBuilder, I32Ty, false);
277
279 switch (BasicType->getEncoding()) {
280 case dwarf::DW_ATE_signed:
282 break;
283 case dwarf::DW_ATE_unsigned:
285 break;
286 case dwarf::DW_ATE_unsigned_char:
288 break;
289 case dwarf::DW_ATE_signed_char:
291 break;
292 case dwarf::DW_ATE_float:
294 break;
295 case dwarf::DW_ATE_boolean:
297 break;
298 case dwarf::DW_ATE_address:
300 }
301
302 const Register AttributeEncodingReg =
303 GR->buildConstantInt(AttributeEncoding, MIRBuilder, I32Ty, false);
304
305 const Register BasicTypeReg =
306 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,
307 {BasicTypeStrReg, ConstIntBitwidthReg,
308 AttributeEncodingReg, I32ZeroReg});
309 BasicTypeRegPairs.emplace_back(BasicType, BasicTypeReg);
310 }
311
312 if (PointerDerivedTypes.size()) {
313 for (const auto *PointerDerivedType : PointerDerivedTypes) {
314
315 assert(PointerDerivedType->getDWARFAddressSpace().has_value());
318 PointerDerivedType->getDWARFAddressSpace().value(),
320 MIRBuilder, I32Ty, false);
321
322
323
324 const auto *MaybeNestedBasicType =
326 if (MaybeNestedBasicType) {
327 for (const auto &BasicTypeRegPair : BasicTypeRegPairs) {
328 const auto &[DefinedBasicType, BasicTypeReg] = BasicTypeRegPair;
329 if (DefinedBasicType == MaybeNestedBasicType) {
330 [[maybe_unused]]
331 const Register DebugPointerTypeReg = EmitDIInstruction(
332 SPIRV::NonSemanticExtInst::DebugTypePointer,
333 {BasicTypeReg, StorageClassReg, I32ZeroReg});
334 }
335 }
336 } else {
337 const Register DebugInfoNoneReg =
338 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugInfoNone, {});
339 [[maybe_unused]]
340 const Register DebugPointerTypeReg = EmitDIInstruction(
341 SPIRV::NonSemanticExtInst::DebugTypePointer,
342 {DebugInfoNoneReg, StorageClassReg, I32ZeroReg});
343 }
344 }
345 }
346 }
347 return true;
348}
349
350bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
351 bool Res = false;
352
353
354 if (!IsGlobalDIEmitted) {
355 IsGlobalDIEmitted = true;
356 Res = emitGlobalDI(MF);
357 }
358 return Res;
359}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
This file contains constants used for implementing Dwarf debug support.
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
SourceLanguage
Definition SPIRVEmitNonSemanticDI.cpp:67
@ HERO_C
Definition SPIRVEmitNonSemanticDI.cpp:76
@ SYCL
Definition SPIRVEmitNonSemanticDI.cpp:75
@ Unknown
Definition SPIRVEmitNonSemanticDI.cpp:68
@ HLSL
Definition SPIRVEmitNonSemanticDI.cpp:73
@ Slang
Definition SPIRVEmitNonSemanticDI.cpp:79
@ OpenCL_CPP
Definition SPIRVEmitNonSemanticDI.cpp:72
@ CPP_for_OpenCL
Definition SPIRVEmitNonSemanticDI.cpp:74
@ WGSL
Definition SPIRVEmitNonSemanticDI.cpp:78
@ OpenCL_C
Definition SPIRVEmitNonSemanticDI.cpp:71
@ Zig
Definition SPIRVEmitNonSemanticDI.cpp:80
@ NZSL
Definition SPIRVEmitNonSemanticDI.cpp:77
@ ESSL
Definition SPIRVEmitNonSemanticDI.cpp:69
@ GLSL
Definition SPIRVEmitNonSemanticDI.cpp:70
BaseTypeAttributeEncoding
Definition SPIRVEmitNonSemanticDI.cpp:56
@ Boolean
Definition SPIRVEmitNonSemanticDI.cpp:59
@ Address
Definition SPIRVEmitNonSemanticDI.cpp:58
@ UnsignedChar
Definition SPIRVEmitNonSemanticDI.cpp:64
@ SignedChar
Definition SPIRVEmitNonSemanticDI.cpp:62
@ Unspecified
Definition SPIRVEmitNonSemanticDI.cpp:57
@ Unsigned
Definition SPIRVEmitNonSemanticDI.cpp:63
@ Float
Definition SPIRVEmitNonSemanticDI.cpp:60
@ Signed
Definition SPIRVEmitNonSemanticDI.cpp:61
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 - 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 - 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.