42template <
typename MapT>
43static std::optional<MCRegister> lookupOptReg(
const MapT &Map,
44 typename MapT::key_type
Key) {
48 assert(It->second.isValid() &&
"invalid register stored in map");
75 if (CT->getTag() == dwarf::DW_TAG_array_type) {
91 }
else if (CT->getTag() == dwarf::DW_TAG_structure_type ||
92 CT->getTag() == dwarf::DW_TAG_class_type ||
93 CT->getTag() == dwarf::DW_TAG_union_type) {
99 if (DT && DT->getTag() == dwarf::DW_TAG_pointer_type)
101 else if (DT && DT->getTag() == dwarf::DW_TAG_typedef)
106 NSDIFlagIsProtected = 1u << 0,
107 NSDIFlagIsPrivate = 1u << 1,
108 NSDIFlagIsPublic = NSDIFlagIsPrivate | NSDIFlagIsProtected,
109 NSDIFlagIsLocal = 1u << 2,
110 NSDIFlagIsDefinition = 1u << 3,
111 NSDIFlagFwdDecl = 1u << 4,
112 NSDIFlagArtificial = 1u << 5,
113 NSDIFlagExplicit = 1u << 6,
114 NSDIFlagPrototyped = 1u << 7,
115 NSDIFlagObjectPointer = 1u << 8,
116 NSDIFlagStaticMember = 1u << 9,
117 NSDIFlagIndirectVariable = 1u << 10,
118 NSDIFlagLValueReference = 1u << 11,
119 NSDIFlagRValueReference = 1u << 12,
120 NSDIFlagIsOptimized = 1u << 13,
121 NSDIFlagIsEnumClass = 1u << 14,
122 NSDIFlagTypePassByValue = 1u << 15,
123 NSDIFlagTypePassByReference = 1u << 16,
124 NSDIFlagUnknownPhysicalLayout = 1u << 17,
130 Flags |= NSDIFlagIsPublic;
132 Flags |= NSDIFlagIsProtected;
134 Flags |= NSDIFlagIsPrivate;
135 if (DFlags & DINode::FlagFwdDecl)
136 Flags |= NSDIFlagFwdDecl;
137 if (DFlags & DINode::FlagArtificial)
138 Flags |= NSDIFlagArtificial;
139 if (DFlags & DINode::FlagExplicit)
140 Flags |= NSDIFlagExplicit;
141 if (DFlags & DINode::FlagPrototyped)
142 Flags |= NSDIFlagPrototyped;
143 if (DFlags & DINode::FlagObjectPointer)
144 Flags |= NSDIFlagObjectPointer;
145 if (DFlags & DINode::FlagStaticMember)
146 Flags |= NSDIFlagStaticMember;
147 if (DFlags & DINode::FlagLValueReference)
148 Flags |= NSDIFlagLValueReference;
149 if (DFlags & DINode::FlagRValueReference)
150 Flags |= NSDIFlagRValueReference;
151 if (DFlags & DINode::FlagTypePassByValue)
152 Flags |= NSDIFlagTypePassByValue;
153 if (DFlags & DINode::FlagTypePassByReference)
154 Flags |= NSDIFlagTypePassByReference;
155 if (DFlags & DINode::FlagEnumClass)
156 Flags |= NSDIFlagIsEnumClass;
163 if (GV->isLocalToUnit())
164 Flags |= NSDIFlagIsLocal;
165 if (GV->isDefinition())
166 Flags |= NSDIFlagIsDefinition;
169 if (SP->isLocalToUnit())
170 Flags |= NSDIFlagIsLocal;
171 if (SP->isOptimized())
172 Flags |= NSDIFlagIsOptimized;
173 if (SP->isDefinition())
174 Flags |= NSDIFlagIsDefinition;
175 Flags |= mapDIFlagsToNonSemantic(SP->getFlags());
177 if (DN->
getTag() == dwarf::DW_TAG_reference_type)
178 Flags |= NSDIFlagLValueReference;
179 if (DN->
getTag() == dwarf::DW_TAG_rvalue_reference_type)
180 Flags |= NSDIFlagRValueReference;
182 Flags |= mapDIFlagsToNonSemantic(Ty->getFlags());
184 Flags |= mapDIFlagsToNonSemantic(LV->getFlags());
190static uint32_t mapCompositeTypeTag(
unsigned Tag) {
192 case dwarf::DW_TAG_class_type:
194 case dwarf::DW_TAG_structure_type:
196 case dwarf::DW_TAG_union_type:
200 ". Expecting 0, 1 or 2");
215 bool SeenOpVariable =
false;
217 if (
MI.getOpcode() == SPIRV::OpVariable) {
218 SeenOpVariable =
true;
220 LastOpVariable = &
MI;
224 bool CanInterleaveWithOpVariable =
225 MI.getOpcode() == SPIRV::OpLine ||
MI.getOpcode() == SPIRV::OpNoLine;
226 if (SeenOpVariable && !CanInterleaveWithOpVariable &&
230 return LastOpVariable;
241unsigned SPIRVNonSemanticDebugHandler::toNSDISrcLang(
unsigned DwarfSrcLang) {
242 switch (DwarfSrcLang) {
243 case dwarf::DW_LANG_OpenCL:
245 case dwarf::DW_LANG_OpenCL_CPP:
247 case dwarf::DW_LANG_CPP_for_OpenCL:
249 case dwarf::DW_LANG_GLSL:
251 case dwarf::DW_LANG_HLSL:
253 case dwarf::DW_LANG_SYCL:
255 case dwarf::DW_LANG_Zig:
280 for (
const MDNode *
N : SP->getRetainedNodes())
285 Locations.insert(
DL);
288 Locations.insert(
DL);
319 CompileUnits.clear();
321 PointerTypes.clear();
322 SubroutineTypes.clear();
325 CompositeTypes.clear();
326 TypedefTypes.clear();
327 SubprogramDeclarations.clear();
328 SubprogramDefinitions.clear();
329 UniqueDebugLocations.clear();
330 GlobalVariableDebugInfoMap.clear();
331 LocalVariables.clear();
332 DebugLocalVariableRegs.clear();
333 DebugExpressionRegs.clear();
334 LexicalBlocks.clear();
335 DebugScopeRegs.clear();
336 DebugInlinedAtRegs.clear();
337 ScopeToPathOpStringReg.clear();
338 DebugSourceRegByFileStr.clear();
339 OpStringContentCache.clear();
340 I32ConstantCache.clear();
341 DebugTypeFunctionCache.clear();
342 DebugOperationCache.clear();
343 DebugExpressionCache.clear();
344 GlobalDIEmitted =
false;
345 GlobalNSDIEnabled =
false;
346 CurrentMAI =
nullptr;
348 NonSemanticOpStringsSectionEmitted =
false;
358 CompileUnitInfo Info;
361 Info.FilePath = File->getFilename();
364 File->getFilename());
367 Info.SpirvSourceLanguage = toNSDISrcLang(
CU->getSourceLanguage().getName());
368 CompileUnits.push_back(std::move(Info));
374 if (
const NamedMDNode *Flags = M->getNamedMetadata(
"llvm.module.flags")) {
375 for (
const auto *
Op : Flags->operands()) {
389 partitionTypes(Ty, BasicTypes, PointerTypes, SubroutineTypes, VectorTypes,
390 ArrayTypes, CompositeTypes, TypedefTypes);
394 if (SP->isDefinition())
395 SubprogramDefinitions.push_back(SP);
397 SubprogramDeclarations.push_back(SP);
404 G.getDebugInfo(GVEs);
415 GlobalVariableDebugInfoMap.try_emplace(
416 GV, GlobalVariableDebugInfo{Expr, DIGVToLLVMGV.
lookup(GV)});
431 if (CompileUnits.empty())
433 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_non_semantic_info))
446void SPIRVNonSemanticDebugHandler::emitMCInst(
MCInst &Inst) {
451SPIRVNonSemanticDebugHandler::emitOpString(
StringRef S,
462MCRegister SPIRVNonSemanticDebugHandler::emitOpStringIfNew(
465 assert(!NonSemanticOpStringsSectionEmitted &&
466 "emitOpStringIfNew is only valid while emitting SPIR-V section 7");
468 auto [It,
Inserted] = OpStringContentCache.try_emplace(S, MCRegister());
470 It->second = emitOpString(S, MAI);
477 assert(NonSemanticOpStringsSectionEmitted &&
478 "getCachedOpStringReg requires emitNonSemanticDebugStrings() first");
480 auto It = OpStringContentCache.find(S);
481 assert(It != OpStringContentCache.end() &&
482 "NSDI OpString missing from cache; emitNonSemanticDebugStrings must "
483 "cache every string used in section 10");
487MCRegister SPIRVNonSemanticDebugHandler::emitAndCacheScopePathOpStringReg(
489 auto [It,
Inserted] = ScopeToPathOpStringReg.try_emplace(Scope, MCRegister());
491 It->second = emitOpStringIfNew(getDebugFullPath(Scope), MAI);
495MCRegister SPIRVNonSemanticDebugHandler::getCachedScopePathOpStringReg(
496 const DIScope *Scope,
bool UseEmptyPathIfNullScope) {
498 assert(UseEmptyPathIfNullScope &&
499 "null scope path lookup requires UseEmptyPathIfNullScope");
500 assert(CachedEmptyStringReg.isValid() &&
501 "empty path OpString must be cached in emitNonSemanticDebugStrings");
502 return CachedEmptyStringReg;
504 auto It = ScopeToPathOpStringReg.find(Scope);
505 assert(It != ScopeToPathOpStringReg.end() &&
506 "path OpString must be cached in emitNonSemanticDebugStrings");
507 MCRegister FileStrReg = It->second;
508 assert(FileStrReg.
isValid() &&
"path OpString id must be valid once cached");
512MCRegister SPIRVNonSemanticDebugHandler::emitOpConstantI32(
529MCRegister SPIRVNonSemanticDebugHandler::emitExtInst(
530 SPIRV::NonSemanticExtInst::NonSemanticExtInst Opcode,
546MCRegister SPIRVNonSemanticDebugHandler::getOrEmitDebugTypeFunction(
554 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeFunction,
555 VoidTypeReg, ExtInstSetReg,
Ops, MAI);
560MCRegister SPIRVNonSemanticDebugHandler::getOrEmitOpTypeVoidReg(
562 if (!CachedOpTypeVoidReg.isValid())
563 CachedOpTypeVoidReg = findOrEmitOpTypeVoid(MAI);
564 return CachedOpTypeVoidReg;
567MCRegister SPIRVNonSemanticDebugHandler::getOrEmitOpTypeInt32Reg(
569 if (!CachedOpTypeInt32Reg.isValid())
570 CachedOpTypeInt32Reg = findOrEmitOpTypeInt32(MAI);
571 return CachedOpTypeInt32Reg;
574MCRegister SPIRVNonSemanticDebugHandler::findOrEmitOpTypeVoid(
577 if (
MI->getOpcode() == SPIRV::OpTypeVoid)
588MCRegister SPIRVNonSemanticDebugHandler::findOrEmitOpTypeInt32(
591 if (
MI->getOpcode() == SPIRV::OpTypeInt &&
592 MI->getOperand(1).getImm() == 32 &&
MI->getOperand(2).getImm() == 0)
605std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypePointer(
610 if (!PT->getDWARFAddressSpace().has_value())
613 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
614 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
615 MCRegister DebugTypePointerFlagsReg =
616 emitOpConstantI32(transDebugFlags(PT), I32TypeReg, MAI);
620 const auto &
ST =
static_cast<const SPIRVSubtarget &
>(
Asm->getSubtargetInfo());
621 MCRegister StorageClassReg = emitOpConstantI32(
625 if (
const DIType *BaseTy = PT->getBaseType()) {
626 auto BaseIt = DebugScopeRegs.find(BaseTy);
627 if (BaseIt != DebugScopeRegs.end())
629 SPIRV::NonSemanticExtInst::DebugTypePointer, VoidTypeReg,
631 {BaseIt->second, StorageClassReg, DebugTypePointerFlagsReg}, MAI);
640 SPIRV::NonSemanticExtInst::DebugTypePointer, VoidTypeReg, ExtInstSetReg,
641 {CachedDebugInfoNoneReg, StorageClassReg, DebugTypePointerFlagsReg}, MAI);
644std::optional<MCRegister>
645SPIRVNonSemanticDebugHandler::emitDebugTypeFunctionForSubroutineType(
648 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
649 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
650 MCRegister DebugTypeFunctionFlagsReg =
651 emitOpConstantI32(transDebugFlags(ST), I32TypeReg, MAI);
652 DITypeArray
TA =
ST->getTypeArray();
654 Ops.push_back(DebugTypeFunctionFlagsReg);
659 Ops.push_back(VoidTypeReg);
661 for (
unsigned I = 0,
E =
TA.size();
I !=
E; ++
I) {
662 bool IsReturnType = (
I == 0);
663 auto OptReg = mapDISignatureTypeToReg(TA[
I], VoidTypeReg, IsReturnType);
668 Ops.push_back(*OptReg);
671 return getOrEmitDebugTypeFunction(
Ops, VoidTypeReg, ExtInstSetReg, MAI);
675std::optional<MCRegister> SPIRVNonSemanticDebugHandler::resolveScope(
679 return lookupOptReg(DebugScopeRegs, Scope);
683 return lookupOptReg(DebugScopeRegs, FallbackCU);
685 if (CompileUnits.empty())
688 return lookupOptReg(DebugScopeRegs, CompileUnits[0].TheCU);
691std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugLexicalBlock(
695 "S must be a DILexicalBlock or DINamespace in emitDebugLexicalBlock");
696 auto ParentRegOpt = resolveScope(S->
getScope());
700 MCRegister FileStrReg = getCachedScopePathOpStringReg(
702 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
707 MCRegister LineReg = emitOpConstantI32(
static_cast<uint32_t
>(LB->getLine()),
709 MCRegister ColReg = emitOpConstantI32(
710 static_cast<uint32_t
>(LB->getColumn()), I32TypeReg, MAI);
711 Ops = {SrcReg, LineReg, ColReg, *ParentRegOpt};
715 MCRegister LineReg = emitOpConstantI32(0, I32TypeReg, MAI);
716 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
717 MCRegister NameReg = getCachedOpStringReg(NS->getName());
718 Ops = {SrcReg, LineReg, ColReg, *ParentRegOpt, NameReg};
721 return emitExtInst(SPIRV::NonSemanticExtInst::DebugLexicalBlock, VoidTypeReg,
722 ExtInstSetReg,
Ops, MAI);
725MCRegister SPIRVNonSemanticDebugHandler::getOrEmitDebugInlinedAt(
728 assert(IA &&
"IA must not be null in getOrEmitDebugInlinedAt");
730 if (MCRegister Cached = DebugInlinedAtRegs.lookup(IA))
733 auto ScopeRegOpt = resolveScope(
IA->getScope());
738 emitOpConstantI32(
static_cast<uint32_t
>(
IA->getLine()), I32TypeReg, MAI);
743 if (
const DILocation *Outer =
IA->getInlinedAt()) {
744 MCRegister OuterReg = getOrEmitDebugInlinedAt(
745 Outer, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
748 Ops.push_back(OuterReg);
751 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugInlinedAt,
752 VoidTypeReg, ExtInstSetReg,
Ops, MAI);
753 DebugInlinedAtRegs[
IA] =
Reg;
757std::optional<MCRegister>
758SPIRVNonSemanticDebugHandler::emitDebugFunctionDeclaration(
761 assert(SP &&
"SP must not be null in emitDebugFunctionDeclaration");
763 "SP must not be a definition in emitDebugFunctionDeclaration");
766 const DISubroutineType *
ST =
SP->getType();
768 auto FnTyRegOpt = lookupOptReg(DebugScopeRegs, ST);
771 MCRegister FnTyReg = *FnTyRegOpt;
773 auto ParentRegOpt = resolveScope(
SP->getScope(),
SP->getUnit());
777 MCRegister ParentReg = *ParentRegOpt;
779 MCRegister FileStrReg = getCachedScopePathOpStringReg(SP);
781 MCRegister NameReg = getCachedOpStringReg(
SP->getName());
782 MCRegister LinkageReg = getCachedOpStringReg(
SP->getLinkageName());
783 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
787 emitOpConstantI32(
static_cast<uint32_t
>(
SP->getLine()), I32TypeReg, MAI);
788 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
790 uint32_t FlagsVal = transDebugFlags(SP);
793 FlagsVal &= ~NSDIFlagIsDefinition;
794 MCRegister FlagsReg = emitOpConstantI32(FlagsVal, I32TypeReg, MAI);
796 return emitExtInst(SPIRV::NonSemanticExtInst::DebugFunctionDeclaration,
797 VoidTypeReg, ExtInstSetReg,
798 {NameReg, FnTyReg, SrcReg, LineReg, ColReg, ParentReg,
799 LinkageReg, FlagsReg},
803std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugFunction(
806 assert(SP &&
"SP must not be null in emitDebugFunction");
807 assert(
SP->isDefinition() &&
"SP must be a definition in emitDebugFunction");
809 const DISubroutineType *
ST =
SP->getType();
810 auto FnTyRegOpt = lookupOptReg(DebugScopeRegs, ST);
814 auto ParentRegOpt = resolveScope(
SP->getScope(),
SP->getUnit());
818 MCRegister NameReg = getCachedOpStringReg(
SP->getName());
819 MCRegister LinkageReg = getCachedOpStringReg(
SP->getLinkageName());
820 MCRegister FileStrReg = getCachedScopePathOpStringReg(SP);
821 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
825 emitOpConstantI32(
static_cast<uint32_t
>(
SP->getLine()), I32TypeReg, MAI);
828 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
829 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(SP), I32TypeReg, MAI);
830 MCRegister ScopeLineReg = emitOpConstantI32(
831 static_cast<uint32_t
>(
SP->getScopeLine()), I32TypeReg, MAI);
834 LineReg, ColReg, *ParentRegOpt,
835 LinkageReg, FlagsReg, ScopeLineReg};
837 if (
const DISubprogram *Decl =
SP->getDeclaration()) {
838 if (
auto DeclRegOpt = lookupOptReg(DebugScopeRegs, Decl))
839 Ops.push_back(*DeclRegOpt);
842 return emitExtInst(SPIRV::NonSemanticExtInst::DebugFunction, VoidTypeReg,
843 ExtInstSetReg,
Ops, MAI);
846std::optional<MCRegister> SPIRVNonSemanticDebugHandler::mapDISignatureTypeToReg(
851 assert(CachedDebugInfoNoneReg.isValid() &&
852 "DebugInfoNone must be emitted before DISubroutineType operands");
853 return CachedDebugInfoNoneReg;
855 return lookupOptReg(DebugScopeRegs, Ty);
873static std::optional<NonSemanticDebugOp>
876 case dwarf::DW_OP_deref:
878 case dwarf::DW_OP_plus:
880 case dwarf::DW_OP_minus:
882 case dwarf::DW_OP_plus_uconst:
884 case dwarf::DW_OP_bit_piece:
886 case dwarf::DW_OP_swap:
888 case dwarf::DW_OP_xderef:
890 case dwarf::DW_OP_stack_value:
892 case dwarf::DW_OP_constu:
901std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugOperation(
905 std::optional<NonSemanticDebugOp> NSOp =
910 SmallVector<uint32_t, 3>
Key{
static_cast<uint32_t
>(*NSOp)};
911 for (
unsigned I = 0,
E =
Op.getNumArgs();
I !=
E; ++
I) {
915 Key.push_back(
static_cast<uint32_t
>(Arg));
918 auto [It,
Inserted] = DebugOperationCache.try_emplace(std::move(
Key));
923 for (uint32_t V : It->first)
924 Operands.push_back(emitOpConstantI32(V, I32TypeReg, MAI));
925 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugOperation,
926 VoidTypeReg, ExtInstSetReg,
Operands, MAI);
931std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugExpression(
934 assert(Expr &&
"Expr must not be null in emitDebugExpression");
937 for (
const DIExpression::ExprOperand &
Op : Expr->
expr_ops()) {
938 std::optional<MCRegister> OpReg =
939 emitDebugOperation(
Op, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
946 DebugExpressionCache.try_emplace(std::move(OperationRegs));
950 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugExpression,
951 VoidTypeReg, ExtInstSetReg, It->first, MAI);
956std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugGlobalVariable(
960 assert(GV &&
"GV must not be null in emitDebugGlobalVariable");
962 auto ParentRegOpt = resolveScope(GV->
getScope());
966 MCRegister ParentReg = *ParentRegOpt;
972 MCRegister TyReg = CachedDebugInfoNoneReg;
973 if (
const DIType *Ty = GV->
getType()) {
974 auto TyRegOpt = lookupOptReg(DebugScopeRegs, Ty);
980 std::optional<MCRegister> StaticMemberRegOpt;
982 StaticMemberRegOpt = lookupOptReg(DebugScopeRegs, SM);
983 if (!StaticMemberRegOpt)
987 MCRegister NameReg = getCachedOpStringReg(GV->
getName());
988 MCRegister LinkageReg = getCachedOpStringReg(GV->
getLinkageName());
989 MCRegister FileStrReg = getCachedScopePathOpStringReg(
991 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
995 emitOpConstantI32(
static_cast<uint32_t
>(GV->
getLine()), I32TypeReg, MAI);
999 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1006 MCRegister VariableReg = CachedDebugInfoNoneReg;
1007 if (
const GlobalVariable *LLVMGV =
Info.LLVMGV) {
1010 VariableReg = GVReg;
1011 }
else if (
Info.Expr &&
Info.Expr->getNumElements() != 0) {
1012 if (
auto ExprReg = emitDebugExpression(
Info.Expr, VoidTypeReg, I32TypeReg,
1013 ExtInstSetReg, MAI))
1014 VariableReg = *ExprReg;
1017 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(GV), I32TypeReg, MAI);
1020 LineReg, ColReg, ParentReg,
1021 LinkageReg, VariableReg, FlagsReg};
1023 if (StaticMemberRegOpt)
1024 Ops.push_back(*StaticMemberRegOpt);
1026 return emitExtInst(SPIRV::NonSemanticExtInst::DebugGlobalVariable,
1027 VoidTypeReg, ExtInstSetReg,
Ops, MAI);
1030std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugLocalVariable(
1033 assert(LV &&
"LV must not be null in emitDebugLocalVariable");
1035 auto ParentRegOpt = resolveScope(LV->
getScope());
1037 return std::nullopt;
1039 MCRegister TyReg = CachedDebugInfoNoneReg;
1040 if (
const DIType *Ty = LV->
getType()) {
1041 auto TyRegOpt = lookupOptReg(DebugScopeRegs, Ty);
1043 return std::nullopt;
1047 MCRegister NameReg = getCachedOpStringReg(LV->
getName());
1048 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1050 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1051 ExtInstSetReg, MAI);
1052 MCRegister LineReg =
1053 emitOpConstantI32(
static_cast<uint32_t
>(LV->
getLine()), I32TypeReg, MAI);
1055 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1056 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(LV), I32TypeReg, MAI);
1059 ColReg, *ParentRegOpt, FlagsReg};
1060 if (
unsigned Arg = LV->
getArg())
1061 Ops.push_back(emitOpConstantI32(Arg, I32TypeReg, MAI));
1063 return emitExtInst(SPIRV::NonSemanticExtInst::DebugLocalVariable, VoidTypeReg,
1064 ExtInstSetReg,
Ops, MAI);
1067std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeVector(
1072 return std::nullopt;
1073 auto BTIt = DebugScopeRegs.find(BaseTy);
1074 if (BTIt == DebugScopeRegs.end())
1075 return std::nullopt;
1081 return std::nullopt;
1085 return std::nullopt;
1087 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1088 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
1089 MCRegister CountReg = emitOpConstantI32(
1090 static_cast<uint32_t
>(CI->getZExtValue()), I32TypeReg, MAI);
1091 return emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeVector, VoidTypeReg,
1092 ExtInstSetReg, {BTIt->second, CountReg}, MAI);
1095std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeArray(
1100 auto BaseRegOpt = lookupOptReg(DebugScopeRegs, AT->
getBaseType());
1102 return std::nullopt;
1104 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1105 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
1108 Ops.push_back(*BaseRegOpt);
1124 const APInt &
Value = CI->getValue();
1125 if (
Value.getActiveBits() <= 32)
1126 Count =
static_cast<uint32_t
>(
Value.getZExtValue());
1128 Ops.push_back(emitOpConstantI32(
Count, I32TypeReg, MAI));
1131 return emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeArray, VoidTypeReg,
1132 ExtInstSetReg,
Ops, MAI);
1135std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeMember(
1139 auto TyRegOpt = lookupOptReg(DebugScopeRegs,
M->getBaseType());
1141 return std::nullopt;
1143 MCRegister NameReg = getCachedOpStringReg(
M->getName());
1144 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1145 M->getFile(),
true);
1146 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1147 ExtInstSetReg, MAI);
1148 MCRegister LineReg =
1149 emitOpConstantI32(
static_cast<uint32_t
>(
M->getLine()), I32TypeReg, MAI);
1152 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1153 MCRegister OffsetReg = emitOpConstantI32(
1154 static_cast<uint32_t
>(
M->getOffsetInBits()), I32TypeReg, MAI);
1155 MCRegister SizeReg = emitOpConstantI32(
1156 static_cast<uint32_t
>(
M->getSizeInBits()), I32TypeReg, MAI);
1157 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(M), I32TypeReg, MAI);
1168 return emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeMember, VoidTypeReg,
1170 {NameReg, *TyRegOpt, SrcReg, LineReg, ColReg, OffsetReg,
1175std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeComposite(
1179 auto ParentRegOpt = resolveScope(CT->
getScope());
1181 return std::nullopt;
1183 MCRegister NameReg = getCachedOpStringReg(CT->
getName());
1184 MCRegister LinkageReg = getCachedOpStringReg(CT->
getIdentifier());
1185 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1187 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1188 ExtInstSetReg, MAI);
1191 emitOpConstantI32(mapCompositeTypeTag(CT->
getTag()), I32TypeReg, MAI);
1192 MCRegister LineReg =
1193 emitOpConstantI32(
static_cast<uint32_t
>(CT->
getLine()), I32TypeReg, MAI);
1194 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1197 MCRegister SizeReg = CachedDebugInfoNoneReg;
1199 SizeReg = emitOpConstantI32(
static_cast<uint32_t
>(CT->
getSizeInBits()),
1202 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(CT), I32TypeReg, MAI);
1205 LineReg, ColReg, *ParentRegOpt,
1206 LinkageReg, SizeReg, FlagsReg};
1208 return emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeComposite, VoidTypeReg,
1209 ExtInstSetReg,
Ops, MAI);
1212std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypedef(
1216 auto BaseRegOpt = lookupOptReg(DebugScopeRegs, TD->getBaseType());
1218 return std::nullopt;
1220 MCRegister NameReg = getCachedOpStringReg(TD->
getName());
1221 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1223 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1224 ExtInstSetReg, MAI);
1225 MCRegister LineReg =
1226 emitOpConstantI32(
static_cast<uint32_t
>(TD->
getLine()), I32TypeReg, MAI);
1228 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1233 auto ParentRegOpt = resolveScope(TD->
getScope());
1235 return std::nullopt;
1236 MCRegister ParentReg = *ParentRegOpt;
1239 SPIRV::NonSemanticExtInst::DebugTypedef, VoidTypeReg, ExtInstSetReg,
1240 {NameReg, *BaseRegOpt, SrcReg, LineReg, ColReg, ParentReg}, MAI);
1245 if (CompileUnits.empty())
1253 for (
const CompileUnitInfo &Info : CompileUnits) {
1255 MCRegister PathReg = emitOpStringIfNew(Info.FilePath, MAI);
1256 ScopeToPathOpStringReg[Info.TheCU] = PathReg;
1257 if (
const DIFile *
F = Info.TheCU->getFile())
1258 ScopeToPathOpStringReg[
F] = PathReg;
1263 emitOpStringIfNew(
BT->getName(), MAI);
1266 SubprogramDeclarations, SubprogramDefinitions)) {
1267 emitOpStringIfNew(SP->getName(), MAI);
1268 emitOpStringIfNew(SP->getLinkageName(), MAI);
1269 emitAndCacheScopePathOpStringReg(SP, MAI);
1276 emitOpStringIfNew(CT->
getName(), MAI);
1278 emitAndCacheScopePathOpStringReg(CT->
getFile(), MAI);
1281 if (!M || M->getTag() != dwarf::DW_TAG_member)
1283 emitOpStringIfNew(M->getName(), MAI);
1284 emitAndCacheScopePathOpStringReg(M->getFile(), MAI);
1290 emitOpStringIfNew(TD->
getName(), MAI);
1291 emitAndCacheScopePathOpStringReg(TD->
getFile(), MAI);
1294 for (
const auto &[GV,
_] : GlobalVariableDebugInfoMap) {
1295 emitOpStringIfNew(GV->
getName(), MAI);
1297 emitAndCacheScopePathOpStringReg(GV->
getFile(), MAI);
1301 emitOpStringIfNew(LV->
getName(), MAI);
1302 emitAndCacheScopePathOpStringReg(LV->
getFile(), MAI);
1307 for (
const DIScope *S : LexicalBlocks) {
1308 emitAndCacheScopePathOpStringReg(S->
getFile(), MAI);
1310 emitOpStringIfNew(NS->getName(), MAI);
1314 emitAndCacheScopePathOpStringReg(
DL->getScope(), MAI);
1316 CachedEmptyStringReg = emitOpStringIfNew(
"", MAI);
1319 NonSemanticOpStringsSectionEmitted =
true;
1323void SPIRVNonSemanticDebugHandler::emitDebugFunctionDefinition(
1327 "DebugFunctionDefinition operands must be valid");
1328 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1330 emitExtInst(SPIRV::NonSemanticExtInst::DebugFunctionDefinition, VoidTypeReg,
1331 ExtInstSetReg, {DebugFunctionReg, OpFunctionReg}, MAI);
1334void SPIRVNonSemanticDebugHandler::resetPerFunctionDebugState() {
1335 CurrentMF =
nullptr;
1336 LastFunctionOpVariable =
nullptr;
1337 DebugFunctionDefinitionEmitted =
false;
1338 LastLineMI =
nullptr;
1339 LastScopeMI =
nullptr;
1342void SPIRVNonSemanticDebugHandler::preparePerFunctionDebug(
1344 resetPerFunctionDebugState();
1345 if (!GlobalNSDIEnabled || !CurrentMAI)
1356 if (!SP || !
SP->isDefinition())
1361 LastFunctionOpVariable =
1362 findLastFunctionOpVariableDeclaration(*MF, *CurrentMAI);
1365void SPIRVNonSemanticDebugHandler::tryEmitDebugFunctionDefinition(
1367 if (DebugFunctionDefinitionEmitted || !GlobalNSDIEnabled)
1370 assert(CurrentMF &&
"no current MachineFunction");
1371 const Function &
F = CurrentMF->getFunction();
1372 const DISubprogram *
SP =
F.getSubprogram();
1373 if (!SP || !
SP->isDefinition())
1376 auto DFIt = DebugScopeRegs.find(SP);
1377 if (DFIt == DebugScopeRegs.end())
1384 emitDebugFunctionDefinition(DFIt->second, OpFunctionReg, MAI);
1385 DebugFunctionDefinitionEmitted =
true;
1390 preparePerFunctionDebug(MF);
1395 resetPerFunctionDebugState();
1402 if (!DebugFunctionDefinitionEmitted)
1405 std::optional<const MachineInstr *>
Target = resolveDebugLocTarget(
MI);
1409 emitDebugScopeForInstruction(*
Target);
1410 emitDebugLineForInstruction(*
Target);
1412 emitDebugDeclare(
MI);
1422static std::optional<Register>
1426 if (!
MI.isIndirectDebugValue())
1427 return std::nullopt;
1431 Register LocReg =
MI.getDebugOperand(0).getReg();
1433 return std::nullopt;
1444 const MachineInstr *Def =
MI.getMF()->getRegInfo().getUniqueVRegDef(LocReg);
1445 if (!Def || Def->getOpcode() != SPIRV::OpVariable)
1446 return std::nullopt;
1451void SPIRVNonSemanticDebugHandler::emitDebugDeclare(
const MachineInstr *
MI) {
1452 assert(DebugFunctionDefinitionEmitted &&
1453 "DebugFunctionDefinition must be emitted");
1454 assert(CurrentMAI &&
"CurrentMAI must be set");
1460 auto VarRegOpt = lookupOptReg(DebugLocalVariableRegs,
MI->getDebugVariable());
1464 auto ExprRegOpt = lookupOptReg(DebugExpressionRegs,
MI->getDebugExpression());
1468 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1473 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1475 emitExtInst(SPIRV::NonSemanticExtInst::DebugDeclare, VoidTypeReg,
1476 ExtInstSetReg, {*VarRegOpt, StorageReg, *ExprRegOpt}, MAI);
1480 return Opcode == SPIRV::OpSelectionMerge || Opcode == SPIRV::OpLoopMerge ||
1481 Opcode == SPIRV::OpLoopControlINTEL;
1488 switch (
MI->getOpcode()) {
1489 case SPIRV::OpFunction:
1490 case SPIRV::OpFunctionParameter:
1491 case SPIRV::OpFunctionEnd:
1492 case SPIRV::OpLabel:
1504 :
MI->getPrevNode();
1505 Adj; Adj = Forward ? Adj->getNextNode() : Adj->getPrevNode()) {
1513std::optional<const MachineInstr *>
1514SPIRVNonSemanticDebugHandler::resolveDebugLocTarget(
const MachineInstr *
MI) {
1515 assert(CurrentMAI &&
"CurrentMAI must be set");
1516 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1521 return std::nullopt;
1529 return std::nullopt;
1535 assert(
MI &&
"Merge instruction must be followed by a terminator");
1541void SPIRVNonSemanticDebugHandler::emitDebugScopeForInstruction(
1543 assert(DebugFunctionDefinitionEmitted &&
1544 "DebugFunctionDefinition must be emitted");
1545 assert(CurrentMAI &&
"CurrentMAI must be set");
1550 if (LastScopeMI &&
MI->getParent() != LastScopeMI->getParent())
1551 LastScopeMI =
nullptr;
1553 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1554 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1557 const DILocation *CurDL =
MI->getDebugLoc().get();
1562 emitExtInst(SPIRV::NonSemanticExtInst::DebugNoScope, VoidTypeReg,
1563 ExtInstSetReg, {}, MAI);
1564 LastScopeMI =
nullptr;
1569 const DIScope *CurScope = CurDL->getScope();
1570 const DILocation *CurInlinedAt = CurDL->getInlinedAt();
1573 const DILocation *LastDL = LastScopeMI->getDebugLoc().get();
1574 if (LastDL->getScope() == CurScope &&
1575 LastDL->getInlinedAt() == CurInlinedAt)
1579 auto CurScopeRegOpt = resolveScope(CurScope);
1580 if (!CurScopeRegOpt)
1586 MCRegister InlinedReg = DebugInlinedAtRegs.lookup(CurInlinedAt);
1589 Ops.push_back(InlinedReg);
1593 emitExtInst(SPIRV::NonSemanticExtInst::DebugScope, VoidTypeReg, ExtInstSetReg,
1599void SPIRVNonSemanticDebugHandler::emitDebugLineForInstruction(
1601 assert(DebugFunctionDefinitionEmitted &&
1602 "DebugFunctionDefinition must be emitted");
1603 assert(CurrentMAI &&
"CurrentMAI must be set");
1608 if (LastLineMI &&
MI->getParent() != LastLineMI->getParent())
1609 LastLineMI =
nullptr;
1611 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1612 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1615 const DILocation *
DL =
MI->getDebugLoc().get();
1620 emitExtInst(SPIRV::NonSemanticExtInst::DebugNoLine, VoidTypeReg,
1621 ExtInstSetReg, {}, MAI);
1622 LastLineMI =
nullptr;
1632 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1633 DL->getScope(),
true);
1634 unsigned Line =
DL->getLine();
1635 unsigned Col =
DL->getColumn();
1637 MCRegister SrcReg = DebugSourceRegByFileStr.lookup(FileStrReg.
id());
1638 MCRegister LineReg = I32ConstantCache.lookup(Line);
1639 MCRegister ColStartReg = I32ConstantCache.lookup(Col);
1640 MCRegister ColEndReg = I32ConstantCache.lookup(Col + 1);
1652 if (LastLineMI &&
MI->getDebugLoc() == LastLineMI->getDebugLoc())
1656 emitExtInst(SPIRV::NonSemanticExtInst::DebugLine, VoidTypeReg, ExtInstSetReg,
1657 {SrcReg, LineReg, LineReg, ColStartReg, ColEndReg}, MAI);
1666 if (!
MI || !GlobalNSDIEnabled || DebugFunctionDefinitionEmitted || !CurrentMF)
1669 if (
MI != LastFunctionOpVariable)
1675 assert(CurrentMAI &&
"CurrentMAI must be set");
1676 tryEmitDebugFunctionDefinition(*CurrentMAI);
1681 if (!GlobalNSDIEnabled || DebugFunctionDefinitionEmitted || !CurrentMF)
1684 assert(CurrentMF == &MF &&
1685 "notification does not match the current MachineFunction");
1687 if (LastFunctionOpVariable)
1693 tryEmitDebugFunctionDefinition(*CurrentMAI);
1696void SPIRVNonSemanticDebugHandler::collectDebugExpressions(
1699 assert(ModuleInfo &&
"MachineModuleInfo must be set during module output");
1707 if (
MI.isDebugValueLike())
1708 Out.insert(
MI.getDebugExpression());
1714 if (GlobalDIEmitted)
1717 GlobalDIEmitted =
true;
1719 if (CompileUnits.empty()) {
1720 GlobalNSDIEnabled =
false;
1726 if (!ExtInstSetReg.
isValid()) {
1727 GlobalNSDIEnabled =
false;
1732 assert(NonSemanticOpStringsSectionEmitted &&
1733 "emitNonSemanticDebugStrings() must run before "
1734 "emitNonSemanticGlobalDebugInfo()");
1739 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1740 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
1742 CachedDebugInfoNoneReg = emitExtInst(SPIRV::NonSemanticExtInst::DebugInfoNone,
1743 VoidTypeReg, ExtInstSetReg, {}, MAI);
1755 MCRegister DebugInfoVersionReg = emitOpConstantI32(100, I32TypeReg, MAI);
1757 emitOpConstantI32(
static_cast<uint32_t>(DwarfVersion), I32TypeReg, MAI);
1762 map_to_vector(CompileUnits, [&](
const CompileUnitInfo &Info) {
1763 return emitOpConstantI32(Info.SpirvSourceLanguage, I32TypeReg, MAI);
1767 for (
auto [Info, SrcLangReg] :
llvm::zip(CompileUnits, SrcLangRegs)) {
1768 MCRegister FileStrReg = ScopeToPathOpStringReg.lookup(Info.TheCU);
1770 "CU path OpString must be emitted in emitNonSemanticDebugStrings");
1771 MCRegister DebugSourceReg = getOrEmitDebugSourceForFileStrReg(
1772 FileStrReg, VoidTypeReg, ExtInstSetReg, MAI);
1774 SPIRV::NonSemanticExtInst::DebugCompilationUnit, VoidTypeReg,
1776 {DebugInfoVersionReg, DwarfVersionReg, DebugSourceReg, SrcLangReg},
1779 DebugScopeRegs[Info.TheCU] = CUDbgReg;
1784 MCRegister I32ZeroReg = emitOpConstantI32(0, I32TypeReg, MAI);
1787 MCRegister NameReg = getCachedOpStringReg(
BT->getName());
1789 static_cast<uint32_t>(
BT->getSizeInBits()), I32TypeReg, MAI);
1793 unsigned Encoding = 0;
1794 switch (
BT->getEncoding()) {
1795 case dwarf::DW_ATE_address:
1798 case dwarf::DW_ATE_boolean:
1801 case dwarf::DW_ATE_float:
1804 case dwarf::DW_ATE_signed:
1807 case dwarf::DW_ATE_signed_char:
1810 case dwarf::DW_ATE_unsigned:
1813 case dwarf::DW_ATE_unsigned_char:
1817 MCRegister EncodingReg = emitOpConstantI32(Encoding, I32TypeReg, MAI);
1820 SPIRV::NonSemanticExtInst::DebugTypeBasic, VoidTypeReg, ExtInstSetReg,
1821 {NameReg, SizeReg, EncodingReg, I32ZeroReg}, MAI);
1822 DebugScopeRegs[
BT] = BTReg;
1827 if (
auto VecReg = emitDebugTypeVector(VT, ExtInstSetReg, MAI))
1828 DebugScopeRegs[VT] = *VecReg;
1833 if (
auto PtrReg = emitDebugTypePointer(PT, ExtInstSetReg, MAI))
1834 DebugScopeRegs[PT] = *PtrReg;
1841 if (
auto ArrReg = emitDebugTypeArray(AT, ExtInstSetReg, MAI))
1842 DebugScopeRegs[AT] = *ArrReg;
1848 emitDebugTypeFunctionForSubroutineType(ST, ExtInstSetReg, MAI))
1849 DebugScopeRegs[ST] = *FnTyReg;
1861 if (
auto LBReg = emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg,
1862 ExtInstSetReg, MAI))
1863 DebugScopeRegs[S] = *LBReg;
1873 emitDebugTypedef(TD, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI))
1874 DebugScopeRegs[TD] = *TDReg;
1878 for (
const DISubprogram *SP : SubprogramDeclarations) {
1879 if (
auto DeclReg = emitDebugFunctionDeclaration(SP, VoidTypeReg, I32TypeReg,
1880 ExtInstSetReg, MAI))
1881 DebugScopeRegs[SP] = *DeclReg;
1892 if (!M || M->getTag() != dwarf::DW_TAG_member)
1894 if (
auto MemberReg = emitDebugTypeMember(M, VoidTypeReg, I32TypeReg,
1895 ExtInstSetReg, MAI))
1898 if (
auto CompReg = emitDebugTypeComposite(CT, MemberRegs, VoidTypeReg,
1899 I32TypeReg, ExtInstSetReg, MAI))
1900 DebugScopeRegs[CT] = *CompReg;
1906 emitDebugFunction(SP, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI))
1907 DebugScopeRegs[SP] = *FnReg;
1916 if (
auto LBReg = emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg,
1917 ExtInstSetReg, MAI))
1918 DebugScopeRegs[S] = *LBReg;
1924 if (
auto LVReg = emitDebugLocalVariable(LV, VoidTypeReg, I32TypeReg,
1925 ExtInstSetReg, MAI))
1926 DebugLocalVariableRegs[LV] = *LVReg;
1933 collectDebugExpressions(Expressions);
1935 if (
auto ExprReg = emitDebugExpression(Expr, VoidTypeReg, I32TypeReg,
1936 ExtInstSetReg, MAI))
1937 DebugExpressionRegs[Expr] = *ExprReg;
1940 for (
const auto &[GV, Info] : GlobalVariableDebugInfoMap)
1941 emitDebugGlobalVariable(GV, Info, VoidTypeReg, I32TypeReg, ExtInstSetReg,
1947 getOrEmitDebugInlinedAt(IA, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
1950 emitOpConstantI32(
DL->getLine(), I32TypeReg, MAI);
1951 emitOpConstantI32(
DL->getColumn(), I32TypeReg, MAI);
1952 emitOpConstantI32(
DL->getColumn() + 1, I32TypeReg, MAI);
1954 getCachedScopePathOpStringReg(
DL->getScope(),
1956 getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg, ExtInstSetReg,
1960 GlobalNSDIEnabled =
true;
1964SPIRVNonSemanticDebugHandler::getDebugFullPath(
const DIScope *Scope)
const {
1974 Out.assign(Dir.
begin(), Dir.
end());
1980MCRegister SPIRVNonSemanticDebugHandler::getOrEmitDebugSourceForFileStrReg(
1983 const unsigned Key = FileStrReg.
id();
1984 auto It = DebugSourceRegByFileStr.find(
Key);
1985 if (It != DebugSourceRegByFileStr.end())
1988 MCRegister
DS = emitExtInst(SPIRV::NonSemanticExtInst::DebugSource,
1989 VoidTypeReg, ExtInstSetReg, {FileStrReg}, MAI);
1990 DebugSourceRegByFileStr[
Key] =
DS;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static constexpr StringLiteral Filename
static const MachineInstr * findAdjacentEmittedInstruction(const MachineInstr *MI, SPIRV::ModuleAnalysisInfo &MAI, bool Forward)
static void collectLexicalBlockChain(const DIScope *S, SetVector< const DIScope * > &Out)
static bool isMergeInstruction(unsigned Opcode)
static bool isDebugLocTarget(const MachineInstr *MI, SPIRV::ModuleAnalysisInfo &MAI)
static std::optional< Register > getDebugDeclareStorageReg(const MachineInstr &MI)
static std::optional< NonSemanticDebugOp > mapDwarfOpToNonSemanticOp(uint64_t DwarfOp)
static void collectDebugLocationsAndLocalVariables(const Module &M, SetVector< const DILocation * > &Locations, SetVector< const DILocalVariable * > &LVs)
#define SPIRV_BACKEND_SERVICE_FUN_NAME
This file implements a set that has insertion order iteration characteristics.
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.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
bool isValid() const
Return true if the attribute is any kind of attribute.
Basic type, like 'int' or 'float'.
StringRef getIdentifier() const
DINodeArray getElements() const
DIType * getBaseType() const
A lightweight wrapper around an expression operand.
iterator_range< expr_op_iterator > expr_ops() const
A pair of DIGlobalVariable and DIExpression.
DIDerivedType * getStaticDataMemberDeclaration() const
StringRef getLinkageName() const
DILocalScope * getScope() const
Get the local scope for this variable.
Tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
Base class for scope-like contexts.
LLVM_ABI DIScope * getScope() const
Subprogram description. Uses SubclassData1.
Type array for a subprogram.
StringRef getName() const
bool isForwardDecl() const
uint64_t getSizeInBits() const
DIScope * getScope() const
DIScope * getScope() const
StringRef getName() const
Base class for non-instruction debug metadata records that have positions within IR.
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
DebugHandlerBase(AsmPrinter *A)
void beginModule(Module *M) override
Utility to find all debug info in a module.
LLVM_ABI void processModule(const Module &M)
Process entire module and collect debug info anchors.
iterator_range< global_variable_expression_iterator > global_variables() const
iterator_range< subprogram_iterator > subprograms() const
iterator_range< type_iterator > types() const
iterator_range< scope_iterator > scopes() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
DISubprogram * getSubprogram() const
Get the attached subprogram.
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
constexpr unsigned id() const
Tracking metadata reference owned by Metadata.
bool equalsStr(StringRef Str) const
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & front() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
This class contains meta information specific to a module.
const Module * getModule() const
LLVM_ABI MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
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 endFunctionImpl(const MachineFunction *MF) override
void beginFunctionImpl(const MachineFunction *MF) override
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)
void endInstruction() override
Process end of an instruction.
void notifyEntryLabelEmitted(const MachineFunction &MF)
Called after the synthesized entry OpLabel has been emitted.
A vector that has set insertion semantics.
bool insert(const value_type &X)
Insert a new element into the SetVector.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
reverse_iterator rbegin()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
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.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
void addStringImm(StringRef Str, MCInst &Inst)
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_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
bool isa_and_nonnull(const Y &Val)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
MCRegister getExtInstSetReg(unsigned SetNum)
DenseMap< unsigned, MCRegister > ExtInstSetMap
InstrList & getMSInstrs(unsigned MSType)
MCRegister getRegisterAlias(const MachineFunction *MF, Register Reg)
bool getSkipEmission(const MachineInstr *MI)
MCRegister getGlobalObjReg(const GlobalObject *GO)
MCRegister getNextIDRegister()
void addExtension(Extension::Extension ToAdd)