LLVM 20.0.0git
SPIRVEmitNonSemanticDI.cpp
Go to the documentation of this file.
3#include "SPIRV.h"
5#include "SPIRVRegisterInfo.h"
17#include "llvm/IR/Metadata.h"
18#include "llvm/PassRegistry.h"
20#include "llvm/Support/Path.h"
21
22#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
23
24namespace llvm {
26 static char ID;
30
31 bool runOnMachineFunction(MachineFunction &MF) override;
32
33private:
34 bool IsGlobalDIEmitted = false;
35 bool emitGlobalDI(MachineFunction &MF);
36};
37} // namespace llvm
38
39using namespace llvm;
40
42 "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
43
45
48 return new SPIRVEmitNonSemanticDI(TM);
49}
50
52 : MachineFunctionPass(ID), TM(TM) {
54}
55
58}
59
60bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
61 // If this MachineFunction doesn't have any BB repeat procedure
62 // for the next
63 if (MF.begin() == MF.end()) {
64 IsGlobalDIEmitted = false;
65 return false;
66 }
67
68 // Required variables to get from metadata search
69 LLVMContext *Context;
70 SmallString<128> FilePath;
71 unsigned SourceLanguage = 0;
72 int64_t DwarfVersion = 0;
73 int64_t DebugInfoVersion = 0;
74
75 // Searching through the Module metadata to find nescessary
76 // information like DwarfVersion or SourceLanguage
77 {
78 const MachineModuleInfo &MMI =
79 getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
80 const Module *M = MMI.getModule();
81 Context = &M->getContext();
82 const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
83 if (!DbgCu)
84 return false;
85 for (const auto *Op : DbgCu->operands()) {
86 if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
87 DIFile *File = CompileUnit->getFile();
88 sys::path::append(FilePath, File->getDirectory(), File->getFilename());
89 SourceLanguage = CompileUnit->getSourceLanguage();
90 break;
91 }
92 }
93 const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
94 for (const auto *Op : ModuleFlags->operands()) {
95 const MDOperand &MaybeStrOp = Op->getOperand(1);
96 if (MaybeStrOp.equalsStr("Dwarf Version"))
97 DwarfVersion =
98 cast<ConstantInt>(
99 cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
100 ->getSExtValue();
101 else if (MaybeStrOp.equalsStr("Debug Info Version"))
102 DebugInfoVersion =
103 cast<ConstantInt>(
104 cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
105 ->getSExtValue();
106 }
107 }
108 // NonSemantic.Shader.DebugInfo.100 global DI instruction emitting
109 {
110 // Required LLVM variables for emitting logic
116 MachineBasicBlock &MBB = *MF.begin();
117
118 // To correct placement of a OpLabel instruction during SPIRVAsmPrinter
119 // emission all new instructions needs to be placed after OpFunction
120 // and before first terminator
122
123 // Emit OpString with FilePath which is required by DebugSource
124 const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
125 MRI.setType(StrReg, LLT::scalar(32));
126 MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
127 MIB.addDef(StrReg);
128 addStringImm(FilePath, MIB);
129
130 const SPIRVType *VoidTy =
131 GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);
132
133 // Emit DebugSource which is required by DebugCompilationUnit
134 const Register DebugSourceResIdReg =
135 MRI.createVirtualRegister(&SPIRV::IDRegClass);
136 MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
137 MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
138 .addDef(DebugSourceResIdReg)
139 .addUse(GR->getSPIRVTypeID(VoidTy))
140 .addImm(static_cast<int64_t>(
141 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
142 .addImm(SPIRV::NonSemanticExtInst::DebugSource)
143 .addUse(StrReg);
144 MIB.constrainAllUses(*TII, *TRI, *RBI);
145 GR->assignSPIRVTypeToVReg(VoidTy, DebugSourceResIdReg, MF);
146
147 const SPIRVType *I32Ty =
148 GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
149
150 // Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
151 // instructions required by DebugCompilationUnit
152 const Register DwarfVersionReg =
153 GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
154 const Register DebugInfoVersionReg =
155 GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);
156 const Register SourceLanguageReg =
157 GR->buildConstantInt(SourceLanguage, MIRBuilder, I32Ty, false);
158
159 // Emit DebugCompilationUnit
160 const Register DebugCompUnitResIdReg =
161 MRI.createVirtualRegister(&SPIRV::IDRegClass);
162 MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
163 MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
164 .addDef(DebugCompUnitResIdReg)
165 .addUse(GR->getSPIRVTypeID(VoidTy))
166 .addImm(static_cast<int64_t>(
167 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
168 .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
169 .addUse(DebugInfoVersionReg)
170 .addUse(DwarfVersionReg)
171 .addUse(DebugSourceResIdReg)
172 .addUse(SourceLanguageReg);
173 MIB.constrainAllUses(*TII, *TRI, *RBI);
174 GR->assignSPIRVTypeToVReg(VoidTy, DebugCompUnitResIdReg, MF);
175 }
176 return true;
177}
178
180 bool Res = false;
181 // emitGlobalDI needs to be executed only once to avoid
182 // emitting duplicates
183 if (!IsGlobalDIEmitted) {
184 IsGlobalDIEmitted = true;
185 Res = emitGlobalDI(MF);
186 }
187 return Res;
188}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
This file contains the declarations for metadata subclasses.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
#define DEBUG_TYPE
This file defines the SmallString class.
This class represents an Operation in the Expression.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:891
bool equalsStr(StringRef Str) const
Definition: Metadata.h:913
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.
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.
Representation of each machine instruction.
Definition: MachineInstr.h:69
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.
Definition: Module.h:65
A tuple of MDNodes.
Definition: Metadata.h:1730
iterator_range< op_iterator > operands()
Definition: Metadata.h:1826
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.
Definition: Register.h:19
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, MachineFunction &MF)
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR=true)
const SPIRVInstrInfo * getInstrInfo() const override
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
const SPIRVRegisterInfo * getRegisterInfo() const override
const RegisterBankInfo * getRegBankInfo() const override
const SPIRVSubtarget * getSubtargetImpl() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
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 ...
SourceLanguage
Definition: Dwarf.h:207
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineFunctionPass * createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM)
void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &)
void addStringImm(const StringRef &Str, MCInst &Inst)
Definition: SPIRVUtils.cpp:51
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...