4
4
#include " SPIRVGlobalRegistry.h"
5
5
#include " SPIRVRegisterInfo.h"
6
6
#include " SPIRVTargetMachine.h"
7
+ #include " llvm/ADT/SmallPtrSet.h"
7
8
#include " llvm/ADT/SmallString.h"
9
+ #include " llvm/BinaryFormat/Dwarf.h"
8
10
#include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
9
11
#include " llvm/CodeGen/MachineBasicBlock.h"
10
12
#include " llvm/CodeGen/MachineFunction.h"
13
15
#include " llvm/CodeGen/MachineInstrBuilder.h"
14
16
#include " llvm/CodeGen/MachineModuleInfo.h"
15
17
#include " llvm/CodeGen/MachineOperand.h"
18
+ #include " llvm/CodeGen/MachineRegisterInfo.h"
19
+ #include " llvm/CodeGen/Register.h"
16
20
#include " llvm/IR/DebugInfoMetadata.h"
21
+ #include " llvm/IR/DebugProgramInstruction.h"
17
22
#include " llvm/IR/Metadata.h"
18
23
#include " llvm/PassRegistry.h"
19
24
#include " llvm/Support/Casting.h"
@@ -57,6 +62,17 @@ SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
57
62
initializeSPIRVEmitNonSemanticDIPass (*PassRegistry::getPassRegistry ());
58
63
}
59
64
65
+ enum BaseTypeAttributeEncoding {
66
+ Unspecified = 0 ,
67
+ Address = 1 ,
68
+ Boolean = 2 ,
69
+ Float = 3 ,
70
+ Signed = 4 ,
71
+ SignedChar = 5 ,
72
+ Unsigned = 6 ,
73
+ UnsignedChar = 7
74
+ };
75
+
60
76
bool SPIRVEmitNonSemanticDI::emitGlobalDI (MachineFunction &MF) {
61
77
// If this MachineFunction doesn't have any BB repeat procedure
62
78
// for the next
@@ -71,7 +87,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
71
87
unsigned SourceLanguage = 0 ;
72
88
int64_t DwarfVersion = 0 ;
73
89
int64_t DebugInfoVersion = 0 ;
74
-
90
+ SmallPtrSet<DIBasicType *, 12 > BasicTypes;
75
91
// Searching through the Module metadata to find nescessary
76
92
// information like DwarfVersion or SourceLanguage
77
93
{
@@ -104,6 +120,21 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
104
120
cast<ConstantAsMetadata>(Op->getOperand (2 ))->getValue ())
105
121
->getSExtValue ();
106
122
}
123
+
124
+ // This traversal is the only supported way to access
125
+ // instruction related DI metadata like DIBasicType
126
+ for (auto &F : *M) {
127
+ for (auto &BB : F) {
128
+ for (auto &I : BB) {
129
+ for (DbgVariableRecord &DVR : filterDbgVars (I.getDbgRecordRange ())) {
130
+ DILocalVariable *LocalVariable = DVR.getVariable ();
131
+ if (auto *BasicType =
132
+ dyn_cast<DIBasicType>(LocalVariable->getType ()))
133
+ BasicTypes.insert (BasicType);
134
+ }
135
+ }
136
+ }
137
+ }
107
138
}
108
139
// NonSemantic.Shader.DebugInfo.100 global DI instruction emitting
109
140
{
@@ -120,29 +151,45 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
120
151
// and before first terminator
121
152
MachineIRBuilder MIRBuilder (MBB, MBB.getFirstTerminator ());
122
153
154
+ const auto EmitOpString = [&](StringRef SR) {
155
+ const Register StrReg = MRI.createVirtualRegister (&SPIRV::IDRegClass);
156
+ MRI.setType (StrReg, LLT::scalar (32 ));
157
+ MachineInstrBuilder MIB = MIRBuilder.buildInstr (SPIRV::OpString);
158
+ MIB.addDef (StrReg);
159
+ addStringImm (SR, MIB);
160
+ return StrReg;
161
+ };
162
+
123
163
// 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);
164
+ const Register FilePathStrReg = EmitOpString (FilePath);
129
165
130
166
const SPIRVType *VoidTy =
131
167
GR->getOrCreateSPIRVType (Type::getVoidTy (*Context), MIRBuilder);
132
168
169
+ const auto EmitDIInstruction =
170
+ [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
171
+ std::initializer_list<Register> Registers) {
172
+ const Register InstReg =
173
+ MRI.createVirtualRegister (&SPIRV::IDRegClass);
174
+ MRI.setType (InstReg, LLT::scalar (32 ));
175
+ MachineInstrBuilder MIB =
176
+ MIRBuilder.buildInstr (SPIRV::OpExtInst)
177
+ .addDef (InstReg)
178
+ .addUse (GR->getSPIRVTypeID (VoidTy))
179
+ .addImm (static_cast <int64_t >(
180
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
181
+ .addImm (Inst);
182
+ for (auto Reg : Registers) {
183
+ MIB.addUse (Reg);
184
+ }
185
+ MIB.constrainAllUses (*TII, *TRI, *RBI);
186
+ GR->assignSPIRVTypeToVReg (VoidTy, InstReg, MF);
187
+ return InstReg;
188
+ };
189
+
133
190
// 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);
191
+ const Register DebugSourceResIdReg = EmitDIInstruction (
192
+ SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
146
193
147
194
const SPIRVType *I32Ty =
148
195
GR->getOrCreateSPIRVType (Type::getInt32Ty (*Context), MIRBuilder);
@@ -156,22 +203,56 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
156
203
const Register SourceLanguageReg =
157
204
GR->buildConstantInt (SourceLanguage, MIRBuilder, I32Ty, false );
158
205
159
- // Emit DebugCompilationUnit
206
+ [[maybe_unused]]
160
207
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);
208
+ EmitDIInstruction (SPIRV::NonSemanticExtInst::DebugCompilationUnit,
209
+ {DebugInfoVersionReg, DwarfVersionReg,
210
+ DebugSourceResIdReg, SourceLanguageReg});
211
+
212
+ // We aren't extracting any DebugInfoFlags now so we
213
+ // emitting zero to use as <id>Flags argument for DebugBasicType
214
+ const Register I32ZeroReg =
215
+ GR->buildConstantInt (0 , MIRBuilder, I32Ty, false );
216
+
217
+ for (auto *BasicType : BasicTypes) {
218
+ const Register BasicTypeStrReg = EmitOpString (BasicType->getName ());
219
+
220
+ const Register ConstIntBitwidthReg = GR->buildConstantInt (
221
+ BasicType->getSizeInBits (), MIRBuilder, I32Ty, false );
222
+
223
+ uint64_t AttributeEncoding = BaseTypeAttributeEncoding::Unspecified;
224
+ switch (BasicType->getEncoding ()) {
225
+ case dwarf::DW_ATE_signed:
226
+ AttributeEncoding = BaseTypeAttributeEncoding::Signed;
227
+ break ;
228
+ case dwarf::DW_ATE_unsigned:
229
+ AttributeEncoding = BaseTypeAttributeEncoding::Unsigned;
230
+ break ;
231
+ case dwarf::DW_ATE_unsigned_char:
232
+ AttributeEncoding = BaseTypeAttributeEncoding::UnsignedChar;
233
+ break ;
234
+ case dwarf::DW_ATE_signed_char:
235
+ AttributeEncoding = BaseTypeAttributeEncoding::SignedChar;
236
+ break ;
237
+ case dwarf::DW_ATE_float:
238
+ AttributeEncoding = BaseTypeAttributeEncoding::Float;
239
+ break ;
240
+ case dwarf::DW_ATE_boolean:
241
+ AttributeEncoding = BaseTypeAttributeEncoding::Boolean ;
242
+ break ;
243
+ case dwarf::DW_ATE_address:
244
+ AttributeEncoding = BaseTypeAttributeEncoding::Address;
245
+ }
246
+
247
+ const Register AttributeEncodingReg =
248
+ GR->buildConstantInt (AttributeEncoding, MIRBuilder, I32Ty, false );
249
+
250
+ [[maybe_unused]]
251
+ const Register BasicTypeReg =
252
+ EmitDIInstruction (SPIRV::NonSemanticExtInst::DebugTypeBasic,
253
+ {BasicTypeStrReg, ConstIntBitwidthReg,
254
+ AttributeEncodingReg, I32ZeroReg});
255
+ }
175
256
}
176
257
return true ;
177
258
}
0 commit comments