4
4
#include " SPIRVGlobalRegistry.h"
5
5
#include " SPIRVRegisterInfo.h"
6
6
#include " SPIRVTargetMachine.h"
7
+ #include " llvm/ADT/SmallSet.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"
@@ -71,7 +76,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
71
76
unsigned SourceLanguage = 0 ;
72
77
int64_t DwarfVersion = 0 ;
73
78
int64_t DebugInfoVersion = 0 ;
74
-
79
+ SmallSet<DIBasicType *, 12 > BasicTypes;
75
80
// Searching through the Module metadata to find nescessary
76
81
// information like DwarfVersion or SourceLanguage
77
82
{
@@ -104,6 +109,24 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
104
109
cast<ConstantAsMetadata>(Op->getOperand (2 ))->getValue ())
105
110
->getSExtValue ();
106
111
}
112
+
113
+ // This traversal is the only supported way to access
114
+ // instruction related DI metadata like DIBasicType
115
+ for (auto &F : *M) {
116
+ for (auto &BB : F) {
117
+ for (auto &I : BB) {
118
+ for (DbgRecord &DR : I.getDbgRecordRange ()) {
119
+ if (auto *DVR = dyn_cast<DbgVariableRecord>(&DR)) {
120
+ DILocalVariable *LocalVariable = DVR->getVariable ();
121
+ if (auto *BasicType =
122
+ dyn_cast<DIBasicType>(LocalVariable->getType ())) {
123
+ BasicTypes.insert (BasicType);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
107
130
}
108
131
// NonSemantic.Shader.DebugInfo.100 global DI instruction emitting
109
132
{
@@ -120,29 +143,45 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
120
143
// and before first terminator
121
144
MachineIRBuilder MIRBuilder (MBB, MBB.getFirstTerminator ());
122
145
146
+ const auto EmitOpString = [&](StringRef SR) {
147
+ const Register StrReg = MRI.createVirtualRegister (&SPIRV::IDRegClass);
148
+ MRI.setType (StrReg, LLT::scalar (32 ));
149
+ MachineInstrBuilder MIB = MIRBuilder.buildInstr (SPIRV::OpString);
150
+ MIB.addDef (StrReg);
151
+ addStringImm (SR, MIB);
152
+ return StrReg;
153
+ };
154
+
123
155
// 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);
156
+ const Register FilePathStrReg = EmitOpString (FilePath);
129
157
130
158
const SPIRVType *VoidTy =
131
159
GR->getOrCreateSPIRVType (Type::getVoidTy (*Context), MIRBuilder);
132
160
161
+ const auto EmitDIInstruction =
162
+ [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
163
+ std::initializer_list<Register> Registers) {
164
+ const Register InstReg =
165
+ MRI.createVirtualRegister (&SPIRV::IDRegClass);
166
+ MRI.setType (InstReg, LLT::scalar (32 ));
167
+ MachineInstrBuilder MIB =
168
+ MIRBuilder.buildInstr (SPIRV::OpExtInst)
169
+ .addDef (InstReg)
170
+ .addUse (GR->getSPIRVTypeID (VoidTy))
171
+ .addImm (static_cast <int64_t >(
172
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
173
+ .addImm (Inst);
174
+ for (auto Reg : Registers) {
175
+ MIB.addUse (Reg);
176
+ }
177
+ MIB.constrainAllUses (*TII, *TRI, *RBI);
178
+ GR->assignSPIRVTypeToVReg (VoidTy, InstReg, MF);
179
+ return InstReg;
180
+ };
181
+
133
182
// 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);
183
+ const Register DebugSourceResIdReg = EmitDIInstruction (
184
+ SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
146
185
147
186
const SPIRVType *I32Ty =
148
187
GR->getOrCreateSPIRVType (Type::getInt32Ty (*Context), MIRBuilder);
@@ -156,22 +195,56 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
156
195
const Register SourceLanguageReg =
157
196
GR->buildConstantInt (SourceLanguage, MIRBuilder, I32Ty, false );
158
197
159
- // Emit DebugCompilationUnit
198
+ [[maybe_unused]]
160
199
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);
200
+ EmitDIInstruction (SPIRV::NonSemanticExtInst::DebugCompilationUnit,
201
+ {DebugInfoVersionReg, DwarfVersionReg,
202
+ DebugSourceResIdReg, SourceLanguageReg});
203
+
204
+ // Emit DebugInfoNone. This instruction is a wildcard accepted
205
+ // by standard to put into instruction arguments as Not Available/Null
206
+ const Register DebugInfoNoneReg =
207
+ EmitDIInstruction (SPIRV::NonSemanticExtInst::DebugInfoNone, {});
208
+
209
+ for (auto *BasicType : BasicTypes) {
210
+ const Register BasicTypeStrReg = EmitOpString (BasicType->getName ());
211
+
212
+ const Register ConstIntBitwidthReg = GR->buildConstantInt (
213
+ BasicType->getSizeInBits (), MIRBuilder, I32Ty, false );
214
+
215
+ uint64_t AttributeEncoding = 0 ;
216
+ switch (BasicType->getEncoding ()) {
217
+ case dwarf::DW_ATE_signed:
218
+ AttributeEncoding = 4 ;
219
+ break ;
220
+ case dwarf::DW_ATE_unsigned:
221
+ AttributeEncoding = 6 ;
222
+ break ;
223
+ case dwarf::DW_ATE_unsigned_char:
224
+ AttributeEncoding = 7 ;
225
+ break ;
226
+ case dwarf::DW_ATE_signed_char:
227
+ AttributeEncoding = 5 ;
228
+ break ;
229
+ case dwarf::DW_ATE_float:
230
+ AttributeEncoding = 3 ;
231
+ break ;
232
+ case dwarf::DW_ATE_boolean:
233
+ AttributeEncoding = 2 ;
234
+ break ;
235
+ case dwarf::DW_ATE_address:
236
+ AttributeEncoding = 1 ;
237
+ }
238
+
239
+ const Register AttributeEncodingReg =
240
+ GR->buildConstantInt (AttributeEncoding, MIRBuilder, I32Ty, false );
241
+
242
+ [[maybe_unused]]
243
+ const Register BasicTypeReg =
244
+ EmitDIInstruction (SPIRV::NonSemanticExtInst::DebugTypeBasic,
245
+ {BasicTypeStrReg, ConstIntBitwidthReg,
246
+ AttributeEncodingReg, DebugInfoNoneReg});
247
+ }
175
248
}
176
249
return true ;
177
250
}
0 commit comments