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

27

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

29

30namespace llvm {

32 static char ID;

36

38

39private:

40 bool IsGlobalDIEmitted = false;

42};

43}

44

45using namespace llvm;

46

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

49

51

55}

56

60}

61

64}

65

76

92

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

94

95

97 IsGlobalDIEmitted = false;

98 return false;

99 }

100

101

105 int64_t DwarfVersion = 0;

106 int64_t DebugInfoVersion = 0;

109

110

111 {

113 getAnalysis().getMMI();

115 Context = &M->getContext();

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

117 if (!DbgCu)

118 return false;

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

120 if (const auto *CompileUnit = dyn_cast(Op)) {

124 File->getFilename());

126 }

127 }

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

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

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

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

132 DwarfVersion =

133 cast(

134 cast(Op->getOperand(2))->getValue())

135 ->getSExtValue();

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

137 DebugInfoVersion =

138 cast(

139 cast(Op->getOperand(2))->getValue())

140 ->getSExtValue();

141 }

142

143

144

145 for (auto &F : *M) {

146 for (auto &BB : F) {

147 for (auto &I : BB) {

150 if (auto *BasicType =

151 dyn_cast(LocalVariable->getType())) {

152 BasicTypes.insert(BasicType);

153 } else if (auto *DerivedType =

154 dyn_cast(LocalVariable->getType())) {

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

156 PointerDerivedTypes.insert(DerivedType);

157

158

159

160

161 if (DerivedType->getBaseType())

163 cast(DerivedType->getBaseType()));

164 }

165 }

166 }

167 }

168 }

169 }

170 }

171

172 {

173

180

181

182

183

185

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

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

192 return StrReg;

193 };

194

197

198 const auto EmitDIInstruction =

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

200 std::initializer_list Registers) {

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

205 MIRBuilder.buildInstr(SPIRV::OpExtInst)

208 .addImm(static_cast<int64_t>(

209 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))

210 .addImm(Inst);

213 }

216 return InstReg;

217 };

218

221

222 const Register DwarfVersionReg =

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

224

225 const Register DebugInfoVersionReg =

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

227

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

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

230

231 const Register DebugSourceResIdReg = EmitDIInstruction(

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

233

234 SourceLanguage SpirvSourceLanguage = SourceLanguage::Unknown;

235 switch (LLVMSourceLanguages[Idx]) {

236 case dwarf::DW_LANG_OpenCL:

237 SpirvSourceLanguage = SourceLanguage::OpenCL_C;

238 break;

239 case dwarf::DW_LANG_OpenCL_CPP:

240 SpirvSourceLanguage = SourceLanguage::OpenCL_CPP;

241 break;

242 case dwarf::DW_LANG_CPP_for_OpenCL:

243 SpirvSourceLanguage = SourceLanguage::CPP_for_OpenCL;

244 break;

245 case dwarf::DW_LANG_GLSL:

246 SpirvSourceLanguage = SourceLanguage::GLSL;

247 break;

248 case dwarf::DW_LANG_HLSL:

249 SpirvSourceLanguage = SourceLanguage::HLSL;

250 break;

251 case dwarf::DW_LANG_SYCL:

252 SpirvSourceLanguage = SourceLanguage::SYCL;

253 break;

254 case dwarf::DW_LANG_Zig:

255 SpirvSourceLanguage = SourceLanguage::Zig;

256 }

257

258 const Register SourceLanguageReg =

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

260

261 [[maybe_unused]]

262 const Register DebugCompUnitResIdReg =

263 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugCompilationUnit,

264 {DebugInfoVersionReg, DwarfVersionReg,

265 DebugSourceResIdReg, SourceLanguageReg});

266 }

267

268

269

272

273

274

275

277 BasicTypeRegPairs;

278 for (auto *BasicType : BasicTypes) {

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

280

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

283

284 uint64_t AttributeEncoding = BaseTypeAttributeEncoding::Unspecified;

285 switch (BasicType->getEncoding()) {

286 case dwarf::DW_ATE_signed:

287 AttributeEncoding = BaseTypeAttributeEncoding::Signed;

288 break;

289 case dwarf::DW_ATE_unsigned:

290 AttributeEncoding = BaseTypeAttributeEncoding::Unsigned;

291 break;

292 case dwarf::DW_ATE_unsigned_char:

293 AttributeEncoding = BaseTypeAttributeEncoding::UnsignedChar;

294 break;

295 case dwarf::DW_ATE_signed_char:

296 AttributeEncoding = BaseTypeAttributeEncoding::SignedChar;

297 break;

298 case dwarf::DW_ATE_float:

299 AttributeEncoding = BaseTypeAttributeEncoding::Float;

300 break;

301 case dwarf::DW_ATE_boolean:

302 AttributeEncoding = BaseTypeAttributeEncoding::Boolean;

303 break;

304 case dwarf::DW_ATE_address:

305 AttributeEncoding = BaseTypeAttributeEncoding::Address;

306 }

307

308 const Register AttributeEncodingReg =

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

310

311 const Register BasicTypeReg =

312 EmitDIInstruction(SPIRV::NonSemanticExtInst::DebugTypeBasic,

313 {BasicTypeStrReg, ConstIntBitwidthReg,

314 AttributeEncodingReg, I32ZeroReg});

315 BasicTypeRegPairs.emplace_back(BasicType, BasicTypeReg);

316 }

317

318 if (PointerDerivedTypes.size()) {

319 for (const auto *PointerDerivedType : PointerDerivedTypes) {

320

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

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

326 MIRBuilder, I32Ty, false);

327

328

329

330 const auto *MaybeNestedBasicType =

331 cast_or_null(PointerDerivedType->getBaseType());

332 if (MaybeNestedBasicType) {

333 for (const auto &BasicTypeRegPair : BasicTypeRegPairs) {

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

335 if (DefinedBasicType == MaybeNestedBasicType) {

336 [[maybe_unused]]

337 const Register DebugPointerTypeReg = EmitDIInstruction(

338 SPIRV::NonSemanticExtInst::DebugTypePointer,

339 {BasicTypeReg, StorageClassReg, I32ZeroReg});

340 }

341 }

342 } else {

343 const Register DebugInfoNoneReg =

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

345 [[maybe_unused]]

346 const Register DebugPointerTypeReg = EmitDIInstruction(

347 SPIRV::NonSemanticExtInst::DebugTypePointer,

348 {DebugInfoNoneReg, StorageClassReg, I32ZeroReg});

349 }

350 }

351 }

352 }

353 return true;

354}

355

357 bool Res = false;

358

359

360 if (!IsGlobalDIEmitted) {

361 IsGlobalDIEmitted = true;

362 Res = emitGlobalDI(MF);

363 }

364 return Res;

365}

unsigned const MachineRegisterInfo * MRI

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.

unsigned const TargetRegisterInfo * TRI

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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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

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.

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()

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.

void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)

Register getSPIRVTypeID(const SPIRVType *SpirvType) const

SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)

Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR=true, 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.

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

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 initializeSPIRVEmitNonSemanticDIPass(PassRegistry &)

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.

bool runOnMachineFunction(MachineFunction &MF) override

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...