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;
103 getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
106 const NamedMDNode *DbgCu =
M->getNamedMetadata(
"llvm.dbg.cu");
114 File->getFilename());
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()) {
122 if (MaybeStrOp.
equalsStr(
"Dwarf Version"))
125 cast<ConstantAsMetadata>(
Op->getOperand(2))->getValue())
127 else if (MaybeStrOp.
equalsStr(
"Debug Info Version"))
130 cast<ConstantAsMetadata>(
Op->getOperand(2))->getValue())
141 if (
auto *BasicType =
142 dyn_cast<DIBasicType>(LocalVariable->
getType())) {
143 BasicTypes.
insert(BasicType);
144 }
else if (
auto *DerivedType =
145 dyn_cast<DIDerivedType>(LocalVariable->
getType())) {
146 if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
147 PointerDerivedTypes.
insert(DerivedType);
152 if (
auto *
BT = dyn_cast_or_null<DIBasicType>(
153 DerivedType->getBaseType()))
177 const auto EmitOpString = [&](
StringRef SR) {
178 const Register StrReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
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);
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(),
318 *
TM->getSubtargetImpl()),
319 MIRBuilder, I32Ty,
false);
323 const auto *MaybeNestedBasicType =
324 dyn_cast_or_null<DIBasicType>(PointerDerivedType->getBaseType());
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!")
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.
Register const TargetRegisterInfo * TRI
#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.
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
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...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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()
Holds all the information related to register banks.
Wrapper class representing virtual and physical registers.
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)
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 LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Stores all information relating to a compile unit, be it in its original instance in the object file ...
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)
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
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.