LLVM: lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp Source File (original) (raw)

26

27#define DEBUG_TYPE "spirv-nonsemantic-debug-info"

28

29using namespace llvm;

30

31namespace {

33 static char ID;

37

39

40private:

41 bool IsGlobalDIEmitted = false;

43};

44}

45

47 "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)

48

49char SPIRVEmitNonSemanticDI::ID = 0;

50

53 return new SPIRVEmitNonSemanticDI(TM);

54}

55

66

82

83bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {

84

85

87 IsGlobalDIEmitted = false;

88 return false;

89 }

90

91

95 int64_t DwarfVersion = 0;

96 int64_t DebugInfoVersion = 0;

97 SmallPtrSet<DIBasicType *, 12> BasicTypes;

98 SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;

99

100

101 {

102 const MachineModuleInfo &MMI =

103 getAnalysis().getMMI();

106 const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");

107 if (!DbgCu)

108 return false;

109 for (const auto *Op : DbgCu->operands()) {

111 DIFile *File = CompileUnit->getFile();

114 File->getFilename());

116 CompileUnit->getSourceLanguage().getUnversionedName());

117 }

118 }

119 const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");

120 assert(ModuleFlags && "Expected llvm.module.flags metadata to be present");

121 for (const auto *Op : ModuleFlags->operands()) {

122 const MDOperand &MaybeStrOp = Op->getOperand(1);

123 if (MaybeStrOp.equalsStr("Dwarf Version"))

124 DwarfVersion =

127 ->getSExtValue();

128 else if (MaybeStrOp.equalsStr("Debug Info Version"))

129 DebugInfoVersion =

132 ->getSExtValue();

133 }

134

135

136

137 for (auto &F : *M) {

138 for (auto &BB : F) {

139 for (auto &I : BB) {

140 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {

141 DILocalVariable *LocalVariable = DVR.getVariable();

142 if (auto *BasicType =

144 BasicTypes.insert(BasicType);

145 } else if (auto *DerivedType =

147 if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {

148 PointerDerivedTypes.insert(DerivedType);

149

150

151

152

154 DerivedType->getBaseType()))

156 }

157 }

158 }

159 }

160 }

161 }

162 }

163

164 {

165

171 MachineBasicBlock &MBB = *MF.begin();

172

173

174

175

177

178 const auto EmitOpString = [&](StringRef SR) {

179 const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);

181 MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);

184 return StrReg;

185 };

186

189 SPIRV::AccessQualifier::ReadWrite, false);

190

191 const auto EmitDIInstruction =

192 [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,

193 std::initializer_list Registers) {

195 MRI.createVirtualRegister(&SPIRV::IDRegClass);

197 MachineInstrBuilder MIB =

198 MIRBuilder.buildInstr(SPIRV::OpExtInst)

201 .addImm(static_cast<int64_t>(

202 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))

206 }

209 return InstReg;

210 };

211

214 SPIRV::AccessQualifier::ReadWrite, false);

215

216 const Register DwarfVersionReg =

217 GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);

218

219 const Register DebugInfoVersionReg =

220 GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);

221

222 for (unsigned Idx = 0; Idx < LLVMSourceLanguages.size(); ++Idx) {

223 const Register FilePathStrReg = EmitOpString(FilePaths[Idx]);

224

225 const Register DebugSourceResIdReg = EmitDIInstruction(

226 SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});

227

229 switch (LLVMSourceLanguages[Idx]) {

230 case dwarf::DW_LANG_OpenCL:

232 break;

233 case dwarf::DW_LANG_OpenCL_CPP:

235 break;

236 case dwarf::DW_LANG_CPP_for_OpenCL:

238 break;

239 case dwarf::DW_LANG_GLSL:

241 break;

242 case dwarf::DW_LANG_HLSL:

244 break;

245 case dwarf::DW_LANG_SYCL:

247 break;

248 case dwarf::DW_LANG_Zig:

250 }

251

252 const Register SourceLanguageReg =

253 GR->buildConstantInt(SpirvSourceLanguage, MIRBuilder, I32Ty, false);

254

255 [[maybe_unused]]

256 const Register DebugCompUnitResIdReg =

257 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugCompilationUnit,

258 {DebugInfoVersionReg, DwarfVersionReg,

259 DebugSourceResIdReg, SourceLanguageReg});

260 }

261

262

263

266

267

268

269

271 BasicTypeRegPairs;

272 for (auto *BasicType : BasicTypes) {

273 const Register BasicTypeStrReg = EmitOpString(BasicType->getName());

274

276 BasicType->getSizeInBits(), MIRBuilder, I32Ty, false);

277

279 switch (BasicType->getEncoding()) {

280 case dwarf::DW_ATE_signed:

282 break;

283 case dwarf::DW_ATE_unsigned:

285 break;

286 case dwarf::DW_ATE_unsigned_char:

288 break;

289 case dwarf::DW_ATE_signed_char:

291 break;

292 case dwarf::DW_ATE_float:

294 break;

295 case dwarf::DW_ATE_boolean:

297 break;

298 case dwarf::DW_ATE_address:

300 }

301

302 const Register AttributeEncodingReg =

303 GR->buildConstantInt(AttributeEncoding, MIRBuilder, I32Ty, false);

304

305 const Register BasicTypeReg =

306 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,

307 {BasicTypeStrReg, ConstIntBitwidthReg,

308 AttributeEncodingReg, I32ZeroReg});

309 BasicTypeRegPairs.emplace_back(BasicType, BasicTypeReg);

310 }

311

312 if (PointerDerivedTypes.size()) {

313 for (const auto *PointerDerivedType : PointerDerivedTypes) {

314

315 assert(PointerDerivedType->getDWARFAddressSpace().has_value());

318 PointerDerivedType->getDWARFAddressSpace().value(),

320 MIRBuilder, I32Ty, false);

321

322

323

324 const auto *MaybeNestedBasicType =

326 if (MaybeNestedBasicType) {

327 for (const auto &BasicTypeRegPair : BasicTypeRegPairs) {

328 const auto &[DefinedBasicType, BasicTypeReg] = BasicTypeRegPair;

329 if (DefinedBasicType == MaybeNestedBasicType) {

330 [[maybe_unused]]

331 const Register DebugPointerTypeReg = EmitDIInstruction(

332 SPIRV::NonSemanticExtInst::DebugTypePointer,

333 {BasicTypeReg, StorageClassReg, I32ZeroReg});

334 }

335 }

336 } else {

337 const Register DebugInfoNoneReg =

338 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugInfoNone, {});

339 [[maybe_unused]]

340 const Register DebugPointerTypeReg = EmitDIInstruction(

341 SPIRV::NonSemanticExtInst::DebugTypePointer,

342 {DebugInfoNoneReg, StorageClassReg, I32ZeroReg});

343 }

344 }

345 }

346 }

347 return true;

348}

349

350bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {

351 bool Res = false;

352

353

354 if (!IsGlobalDIEmitted) {

355 IsGlobalDIEmitted = true;

356 Res = emitGlobalDI(MF);

357 }

358 return Res;

359}

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

This file contains constants used for implementing Dwarf debug support.

Machine Check Debug Module

This file declares the MachineIRBuilder class.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

SI Pre allocate WWM Registers

SourceLanguage

Definition SPIRVEmitNonSemanticDI.cpp:67

@ HERO_C

Definition SPIRVEmitNonSemanticDI.cpp:76

@ SYCL

Definition SPIRVEmitNonSemanticDI.cpp:75

@ Unknown

Definition SPIRVEmitNonSemanticDI.cpp:68

@ HLSL

Definition SPIRVEmitNonSemanticDI.cpp:73

@ Slang

Definition SPIRVEmitNonSemanticDI.cpp:79

@ OpenCL_CPP

Definition SPIRVEmitNonSemanticDI.cpp:72

@ CPP_for_OpenCL

Definition SPIRVEmitNonSemanticDI.cpp:74

@ WGSL

Definition SPIRVEmitNonSemanticDI.cpp:78

@ OpenCL_C

Definition SPIRVEmitNonSemanticDI.cpp:71

@ Zig

Definition SPIRVEmitNonSemanticDI.cpp:80

@ NZSL

Definition SPIRVEmitNonSemanticDI.cpp:77

@ ESSL

Definition SPIRVEmitNonSemanticDI.cpp:69

@ GLSL

Definition SPIRVEmitNonSemanticDI.cpp:70

BaseTypeAttributeEncoding

Definition SPIRVEmitNonSemanticDI.cpp:56

@ Boolean

Definition SPIRVEmitNonSemanticDI.cpp:59

@ Address

Definition SPIRVEmitNonSemanticDI.cpp:58

@ UnsignedChar

Definition SPIRVEmitNonSemanticDI.cpp:64

@ SignedChar

Definition SPIRVEmitNonSemanticDI.cpp:62

@ Unspecified

Definition SPIRVEmitNonSemanticDI.cpp:57

@ Unsigned

Definition SPIRVEmitNonSemanticDI.cpp:63

@ Float

Definition SPIRVEmitNonSemanticDI.cpp:60

@ Signed

Definition SPIRVEmitNonSemanticDI.cpp:61

This file defines the SmallPtrSet class.

This file defines the SmallString class.

static constexpr LLT scalar(unsigned SizeInBits)

Get a low-level scalar or aggregate "bag of bits".

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...

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

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.

const Module * getModule() const

iterator_range< op_iterator > operands()

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)

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.

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

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)

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto dyn_cast_or_null(const Y &Val)

const MachineInstr SPIRVType

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

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.