LLVM: lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp Source File (original) (raw)
27
28#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
29
30namespace llvm {
36
38
39private:
40 bool IsGlobalDIEmitted = false;
42};
43}
44
45using namespace llvm;
46
48 "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
49
51
55}
56
60}
61
64}
65
76
92
93bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
94
95
97 IsGlobalDIEmitted = false;
98 return false;
99 }
100
101
105 int64_t DwarfVersion = 0;
106 int64_t DebugInfoVersion = 0;
109
110
111 {
113 getAnalysis().getMMI();
115 Context = &M->getContext();
116 const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
117 if (!DbgCu)
118 return false;
119 for (const auto *Op : DbgCu->operands()) {
120 if (const auto *CompileUnit = dyn_cast(Op)) {
124 File->getFilename());
126 }
127 }
128 const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
129 for (const auto *Op : ModuleFlags->operands()) {
130 const MDOperand &MaybeStrOp = Op->getOperand(1);
131 if (MaybeStrOp.equalsStr("Dwarf Version"))
132 DwarfVersion =
133 cast(
134 cast(Op->getOperand(2))->getValue())
135 ->getSExtValue();
136 else if (MaybeStrOp.equalsStr("Debug Info Version"))
137 DebugInfoVersion =
138 cast(
139 cast(Op->getOperand(2))->getValue())
140 ->getSExtValue();
141 }
142
143
144
145 for (auto &F : *M) {
146 for (auto &BB : F) {
147 for (auto &I : BB) {
150 if (auto *BasicType =
151 dyn_cast(LocalVariable->getType())) {
152 BasicTypes.insert(BasicType);
153 } else if (auto *DerivedType =
154 dyn_cast(LocalVariable->getType())) {
155 if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
156 PointerDerivedTypes.insert(DerivedType);
157
158
159
160
161 if (DerivedType->getBaseType())
163 cast(DerivedType->getBaseType()));
164 }
165 }
166 }
167 }
168 }
169 }
170 }
171
172 {
173
180
181
182
183
185
186 const auto EmitOpString = [&](StringRef SR) {
187 const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
192 return StrReg;
193 };
194
197
198 const auto EmitDIInstruction =
199 [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
200 std::initializer_list Registers) {
202 MRI.createVirtualRegister(&SPIRV::IDRegClass);
205 MIRBuilder.buildInstr(SPIRV::OpExtInst)
208 .addImm(static_cast<int64_t>(
209 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
210 .addImm(Inst);
213 }
216 return InstReg;
217 };
218
221
222 const Register DwarfVersionReg =
223 GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
224
225 const Register DebugInfoVersionReg =
226 GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);
227
228 for (unsigned Idx = 0; Idx < LLVMSourceLanguages.size(); ++Idx) {
229 const Register FilePathStrReg = EmitOpString(FilePaths[Idx]);
230
231 const Register DebugSourceResIdReg = EmitDIInstruction(
232 SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
233
234 SourceLanguage SpirvSourceLanguage = SourceLanguage::Unknown;
235 switch (LLVMSourceLanguages[Idx]) {
236 case dwarf::DW_LANG_OpenCL:
237 SpirvSourceLanguage = SourceLanguage::OpenCL_C;
238 break;
239 case dwarf::DW_LANG_OpenCL_CPP:
240 SpirvSourceLanguage = SourceLanguage::OpenCL_CPP;
241 break;
242 case dwarf::DW_LANG_CPP_for_OpenCL:
243 SpirvSourceLanguage = SourceLanguage::CPP_for_OpenCL;
244 break;
245 case dwarf::DW_LANG_GLSL:
246 SpirvSourceLanguage = SourceLanguage::GLSL;
247 break;
248 case dwarf::DW_LANG_HLSL:
249 SpirvSourceLanguage = SourceLanguage::HLSL;
250 break;
251 case dwarf::DW_LANG_SYCL:
252 SpirvSourceLanguage = SourceLanguage::SYCL;
253 break;
254 case dwarf::DW_LANG_Zig:
255 SpirvSourceLanguage = SourceLanguage::Zig;
256 }
257
258 const Register SourceLanguageReg =
259 GR->buildConstantInt(SpirvSourceLanguage, MIRBuilder, I32Ty, false);
260
261 [[maybe_unused]]
262 const Register DebugCompUnitResIdReg =
263 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugCompilationUnit,
264 {DebugInfoVersionReg, DwarfVersionReg,
265 DebugSourceResIdReg, SourceLanguageReg});
266 }
267
268
269
272
273
274
275
277 BasicTypeRegPairs;
278 for (auto *BasicType : BasicTypes) {
279 const Register BasicTypeStrReg = EmitOpString(BasicType->getName());
280
282 BasicType->getSizeInBits(), MIRBuilder, I32Ty, false);
283
284 uint64_t AttributeEncoding = BaseTypeAttributeEncoding::Unspecified;
285 switch (BasicType->getEncoding()) {
286 case dwarf::DW_ATE_signed:
287 AttributeEncoding = BaseTypeAttributeEncoding::Signed;
288 break;
289 case dwarf::DW_ATE_unsigned:
290 AttributeEncoding = BaseTypeAttributeEncoding::Unsigned;
291 break;
292 case dwarf::DW_ATE_unsigned_char:
293 AttributeEncoding = BaseTypeAttributeEncoding::UnsignedChar;
294 break;
295 case dwarf::DW_ATE_signed_char:
296 AttributeEncoding = BaseTypeAttributeEncoding::SignedChar;
297 break;
298 case dwarf::DW_ATE_float:
299 AttributeEncoding = BaseTypeAttributeEncoding::Float;
300 break;
301 case dwarf::DW_ATE_boolean:
302 AttributeEncoding = BaseTypeAttributeEncoding::Boolean;
303 break;
304 case dwarf::DW_ATE_address:
305 AttributeEncoding = BaseTypeAttributeEncoding::Address;
306 }
307
308 const Register AttributeEncodingReg =
309 GR->buildConstantInt(AttributeEncoding, MIRBuilder, I32Ty, false);
310
311 const Register BasicTypeReg =
312 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,
313 {BasicTypeStrReg, ConstIntBitwidthReg,
314 AttributeEncodingReg, I32ZeroReg});
315 BasicTypeRegPairs.emplace_back(BasicType, BasicTypeReg);
316 }
317
318 if (PointerDerivedTypes.size()) {
319 for (const auto *PointerDerivedType : PointerDerivedTypes) {
320
321 assert(PointerDerivedType->getDWARFAddressSpace().has_value());
324 PointerDerivedType->getDWARFAddressSpace().value(),
326 MIRBuilder, I32Ty, false);
327
328
329
330 const auto *MaybeNestedBasicType =
331 cast_or_null(PointerDerivedType->getBaseType());
332 if (MaybeNestedBasicType) {
333 for (const auto &BasicTypeRegPair : BasicTypeRegPairs) {
334 const auto &[DefinedBasicType, BasicTypeReg] = BasicTypeRegPair;
335 if (DefinedBasicType == MaybeNestedBasicType) {
336 [[maybe_unused]]
337 const Register DebugPointerTypeReg = EmitDIInstruction(
338 SPIRV::NonSemanticExtInst::DebugTypePointer,
339 {BasicTypeReg, StorageClassReg, I32ZeroReg});
340 }
341 }
342 } else {
343 const Register DebugInfoNoneReg =
344 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugInfoNone, {});
345 [[maybe_unused]]
346 const Register DebugPointerTypeReg = EmitDIInstruction(
347 SPIRV::NonSemanticExtInst::DebugTypePointer,
348 {DebugInfoNoneReg, StorageClassReg, I32ZeroReg});
349 }
350 }
351 }
352 }
353 return true;
354}
355
357 bool Res = false;
358
359
360 if (!IsGlobalDIEmitted) {
361 IsGlobalDIEmitted = true;
362 Res = emitGlobalDI(MF);
363 }
364 return Res;
365}
unsigned const MachineRegisterInfo * MRI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI Pre allocate WWM Registers
BaseTypeAttributeEncoding
This file defines the SmallPtrSet class.
This file defines the SmallString class.
This class represents an Operation in the Expression.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Tracking metadata reference owned by Metadata.
bool equalsStr(StringRef Str) const
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.
Helper class to build MachineInstr.
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.
Representation of each machine instruction.
This class contains meta information specific to a module.
const Module * getModule() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
iterator_range< op_iterator > operands()
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Holds all the information related to register banks.
Wrapper class representing virtual and physical registers.
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR=true, 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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
Stores all information relating to a compile unit, be it in its original instance in the object file ...
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)
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &)
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.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...