32unsigned SPIRVNonSemanticDebugHandler::toNSDISrcLang(
unsigned DwarfSrcLang) {
33 switch (DwarfSrcLang) {
34 case dwarf::DW_LANG_OpenCL:
36 case dwarf::DW_LANG_OpenCL_CPP:
38 case dwarf::DW_LANG_CPP_for_OpenCL:
40 case dwarf::DW_LANG_GLSL:
42 case dwarf::DW_LANG_HLSL:
44 case dwarf::DW_LANG_SYCL:
46 case dwarf::DW_LANG_Zig:
66 Info.FilePath = File->getFilename();
72 Info.SpirvSourceLanguage = toNSDISrcLang(
CU->getSourceLanguage().getName());
73 CompileUnits.push_back(std::move(Info));
79 if (
const NamedMDNode *Flags = M->getNamedMetadata(
"llvm.module.flags")) {
80 for (
const auto *
Op : Flags->operands()) {
91 for (
const auto &
F : *M) {
92 for (
const auto &BB :
F) {
93 for (
const auto &
I : BB) {
96 const DIType *Ty = DVR.getVariable()->getType();
98 BasicTypes.insert(
BT);
100 if (DT->getTag() == dwarf::DW_TAG_pointer_type) {
101 PointerTypes.insert(DT);
104 BasicTypes.insert(
BT);
115 if (CompileUnits.empty())
117 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_non_semantic_info))
126 constexpr unsigned NSSet =
static_cast<unsigned>(
127 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100);
132void SPIRVNonSemanticDebugHandler::emitMCInst(
MCInst &Inst) {
137SPIRVNonSemanticDebugHandler::emitOpString(
StringRef S,
148MCRegister SPIRVNonSemanticDebugHandler::emitOpConstantI32(
165MCRegister SPIRVNonSemanticDebugHandler::emitExtInst(
166 SPIRV::NonSemanticExtInst::NonSemanticExtInst Opcode,
176 for (MCRegister R : Operands)
182MCRegister SPIRVNonSemanticDebugHandler::findOrEmitOpTypeVoid(
185 if (
MI->getOpcode() == SPIRV::OpTypeVoid)
196MCRegister SPIRVNonSemanticDebugHandler::findOrEmitOpTypeInt32(
199 if (
MI->getOpcode() == SPIRV::OpTypeInt &&
200 MI->getOperand(1).getImm() == 32 &&
MI->getOperand(2).getImm() == 0)
213void SPIRVNonSemanticDebugHandler::emitDebugTypePointer(
220 if (!PT->getDWARFAddressSpace().has_value())
225 const auto &
ST =
static_cast<const SPIRVSubtarget &
>(
Asm->getSubtargetInfo());
226 MCRegister StorageClassReg = emitOpConstantI32(
232 if (BTIt != BasicTypeRegs.
end())
233 emitExtInst(SPIRV::NonSemanticExtInst::DebugTypePointer, VoidTypeReg,
234 ExtInstSetReg, {BTIt->second, StorageClassReg, I32ZeroReg},
241 MCRegister NoneReg = emitExtInst(SPIRV::NonSemanticExtInst::DebugInfoNone,
242 VoidTypeReg, ExtInstSetReg, {}, MAI);
243 emitExtInst(SPIRV::NonSemanticExtInst::DebugTypePointer, VoidTypeReg,
244 ExtInstSetReg, {NoneReg, StorageClassReg, I32ZeroReg}, MAI);
250 if (CompileUnits.empty())
255 constexpr unsigned NSSet =
static_cast<unsigned>(
256 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100);
260 for (
const CompileUnitInfo &Info : CompileUnits)
261 FileStringRegs.push_back(emitOpString(Info.FilePath, MAI));
264 BasicTypeNameRegs.push_back(emitOpString(
BT->getName(), MAI));
269 if (GlobalDIEmitted || CompileUnits.empty())
271 GlobalDIEmitted =
true;
274 constexpr unsigned NSSet =
static_cast<unsigned>(
275 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100);
280 MCRegister VoidTypeReg = findOrEmitOpTypeVoid(MAI);
281 MCRegister I32TypeReg = findOrEmitOpTypeInt32(MAI);
293 MCRegister DebugInfoVersionReg = emitOpConstantI32(100, I32TypeReg, MAI);
295 emitOpConstantI32(
static_cast<uint32_t>(DwarfVersion), I32TypeReg, MAI);
300 map_to_vector(CompileUnits, [&](
const CompileUnitInfo &Info) {
301 return emitOpConstantI32(Info.SpirvSourceLanguage, I32TypeReg, MAI);
306 assert(FileStringRegs.size() == CompileUnits.size() &&
307 "FileStringRegs must be populated by emitNonSemanticDebugStrings()");
308 for (
auto [Info, FileStrReg, SrcLangReg] :
309 llvm::zip(CompileUnits, FileStringRegs, SrcLangRegs)) {
311 emitExtInst(SPIRV::NonSemanticExtInst::DebugSource, VoidTypeReg,
312 ExtInstSetReg, {FileStrReg}, MAI);
314 SPIRV::NonSemanticExtInst::DebugCompilationUnit, VoidTypeReg,
316 {DebugInfoVersionReg, DwarfVersionReg, DebugSourceReg, SrcLangReg},
322 MCRegister I32ZeroReg = emitOpConstantI32(0, I32TypeReg, MAI);
331 BasicTypeNameRegs.size() == BasicTypes.size() &&
332 "BasicTypeNameRegs must be populated by emitNonSemanticDebugStrings()");
335 MCRegister NameReg = BasicTypeNameRegs[BTIdx++];
337 static_cast<uint32_t>(
BT->getSizeInBits()), I32TypeReg, MAI);
341 unsigned Encoding = 0;
342 switch (
BT->getEncoding()) {
343 case dwarf::DW_ATE_address:
346 case dwarf::DW_ATE_boolean:
349 case dwarf::DW_ATE_float:
352 case dwarf::DW_ATE_signed:
355 case dwarf::DW_ATE_signed_char:
358 case dwarf::DW_ATE_unsigned:
361 case dwarf::DW_ATE_unsigned_char:
365 MCRegister EncodingReg = emitOpConstantI32(Encoding, I32TypeReg, MAI);
368 SPIRV::NonSemanticExtInst::DebugTypeBasic, VoidTypeReg, ExtInstSetReg,
369 {NameReg, SizeReg, EncodingReg, I32ZeroReg}, MAI);
370 BasicTypeRegs[
BT] = BTReg;
375 emitDebugTypePointer(PT, VoidTypeReg, I32TypeReg, ExtInstSetReg, I32ZeroReg,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class is intended to be used as a driving class for all asm writers.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Basic type, like 'int' or 'float'.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
AsmPrinter * Asm
Target of debug info emission.
DebugHandlerBase(AsmPrinter *A)
void beginModule(Module *M) override
iterator find(const_arg_type_t< KeyT > Val)
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
Tracking metadata reference owned by Metadata.
bool equalsStr(StringRef Str) const
A Module instance is used to store all the information related to an LLVM module.
void emitNonSemanticDebugStrings(SPIRV::ModuleAnalysisInfo &MAI)
Emit OpString instructions for all NSDI file paths and basic type names into the debug section (secti...
void beginModule(Module *M) override
Collect compile-unit metadata from the module.
void emitNonSemanticGlobalDebugInfo(SPIRV::ModuleAnalysisInfo &MAI)
Emit module-scope NSDI instructions (DebugSource, DebugCompilationUnit, DebugTypeBasic,...
void prepareModuleOutput(const SPIRVSubtarget &ST, SPIRV::ModuleAnalysisInfo &MAI)
Add SPV_KHR_non_semantic_info extension and NonSemantic.Shader.DebugInfo.100 ext inst set entry to MA...
SPIRVNonSemanticDebugHandler(AsmPrinter &AP)
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.
LLVM Value Representation.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
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.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
auto dyn_cast_or_null(const Y &Val)
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - 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.
MCRegister getExtInstSetReg(unsigned SetNum)
DenseMap< unsigned, MCRegister > ExtInstSetMap
InstrList & getMSInstrs(unsigned MSType)
MCRegister getRegisterAlias(const MachineFunction *MF, Register Reg)
MCRegister getNextIDRegister()
void addExtension(Extension::Extension ToAdd)