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;
1144 return std::nullopt;
1146 MCRegister NameReg = getCachedOpStringReg(
M->getName());
1147 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1148 M->getFile(),
true);
1149 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1150 ExtInstSetReg, MAI);
1151 MCRegister LineReg =
1152 emitOpConstantI32(
static_cast<uint32_t
>(
M->getLine()), I32TypeReg, MAI);
1155 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1156 MCRegister OffsetReg = emitOpConstantI32(
1157 static_cast<uint32_t
>(
M->getOffsetInBits()), I32TypeReg, MAI);
1158 MCRegister SizeReg = emitOpConstantI32(
1159 static_cast<uint32_t
>(
M->getSizeInBits()), I32TypeReg, MAI);
1160 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(M), I32TypeReg, MAI);
1171 return emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeMember, VoidTypeReg,
1173 {NameReg, *TyRegOpt, SrcReg, LineReg, ColReg, OffsetReg,
1178std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeComposite(
1182 auto ParentRegOpt = resolveScope(CT->
getScope());
1184 return std::nullopt;
1187 return std::nullopt;
1189 MCRegister NameReg = getCachedOpStringReg(CT->
getName());
1190 MCRegister LinkageReg = getCachedOpStringReg(CT->
getIdentifier());
1191 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1193 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1194 ExtInstSetReg, MAI);
1197 emitOpConstantI32(mapCompositeTypeTag(CT->
getTag()), I32TypeReg, MAI);
1198 MCRegister LineReg =
1199 emitOpConstantI32(
static_cast<uint32_t
>(CT->
getLine()), I32TypeReg, MAI);
1200 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1203 MCRegister SizeReg = CachedDebugInfoNoneReg;
1205 SizeReg = emitOpConstantI32(
static_cast<uint32_t
>(CT->
getSizeInBits()),
1208 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(CT), I32TypeReg, MAI);
1211 LineReg, ColReg, *ParentRegOpt,
1212 LinkageReg, SizeReg, FlagsReg};
1214 return emitExtInst(SPIRV::NonSemanticExtInst::DebugTypeComposite, VoidTypeReg,
1215 ExtInstSetReg,
Ops, MAI);
1218std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypedef(
1222 auto BaseRegOpt = lookupOptReg(DebugScopeRegs, TD->getBaseType());
1224 return std::nullopt;
1226 MCRegister NameReg = getCachedOpStringReg(TD->
getName());
1227 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1229 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1230 ExtInstSetReg, MAI);
1231 MCRegister LineReg =
1232 emitOpConstantI32(
static_cast<uint32_t
>(TD->
getLine()), I32TypeReg, MAI);
1234 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1239 auto ParentRegOpt = resolveScope(TD->
getScope());
1241 return std::nullopt;
1242 MCRegister ParentReg = *ParentRegOpt;
1245 SPIRV::NonSemanticExtInst::DebugTypedef, VoidTypeReg, ExtInstSetReg,
1246 {NameReg, *BaseRegOpt, SrcReg, LineReg, ColReg, ParentReg}, MAI);
1251 if (CompileUnits.empty())
1259 for (
const CompileUnitInfo &Info : CompileUnits) {
1261 MCRegister PathReg = emitOpStringIfNew(Info.FilePath, MAI);
1262 ScopeToPathOpStringReg[Info.TheCU] = PathReg;
1263 if (
const DIFile *
F = Info.TheCU->getFile())
1264 ScopeToPathOpStringReg[
F] = PathReg;
1269 emitOpStringIfNew(
BT->getName(), MAI);
1272 SubprogramDeclarations, SubprogramDefinitions)) {
1273 emitOpStringIfNew(SP->getName(), MAI);
1274 emitOpStringIfNew(SP->getLinkageName(), MAI);
1275 emitAndCacheScopePathOpStringReg(SP, MAI);
1282 emitOpStringIfNew(CT->
getName(), MAI);
1284 emitAndCacheScopePathOpStringReg(CT->
getFile(), MAI);
1287 if (!M || M->getTag() != dwarf::DW_TAG_member)
1289 emitOpStringIfNew(M->getName(), MAI);
1290 emitAndCacheScopePathOpStringReg(M->getFile(), MAI);
1296 emitOpStringIfNew(TD->
getName(), MAI);
1297 emitAndCacheScopePathOpStringReg(TD->
getFile(), MAI);
1300 for (
const auto &[GV,
_] : GlobalVariableDebugInfoMap) {
1301 emitOpStringIfNew(GV->
getName(), MAI);
1303 emitAndCacheScopePathOpStringReg(GV->
getFile(), MAI);
1307 emitOpStringIfNew(LV->
getName(), MAI);
1308 emitAndCacheScopePathOpStringReg(LV->
getFile(), MAI);
1313 for (
const DIScope *S : LexicalBlocks) {
1314 emitAndCacheScopePathOpStringReg(S->
getFile(), MAI);
1316 emitOpStringIfNew(NS->getName(), MAI);
1320 emitAndCacheScopePathOpStringReg(
DL->getScope(), MAI);
1322 CachedEmptyStringReg = emitOpStringIfNew(
"", MAI);
1325 NonSemanticOpStringsSectionEmitted =
true;
1329void SPIRVNonSemanticDebugHandler::emitDebugFunctionDefinition(
1333 "DebugFunctionDefinition operands must be valid");
1334 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1336 emitExtInst(SPIRV::NonSemanticExtInst::DebugFunctionDefinition, VoidTypeReg,
1337 ExtInstSetReg, {DebugFunctionReg, OpFunctionReg}, MAI);
1340void SPIRVNonSemanticDebugHandler::resetPerFunctionDebugState() {
1341 CurrentMF =
nullptr;
1342 LastFunctionOpVariable =
nullptr;
1343 DebugFunctionDefinitionEmitted =
false;
1344 LastLineMI =
nullptr;
1345 LastScopeMI =
nullptr;
1348void SPIRVNonSemanticDebugHandler::preparePerFunctionDebug(
1350 resetPerFunctionDebugState();
1351 if (!GlobalNSDIEnabled || !CurrentMAI)
1362 if (!SP || !
SP->isDefinition())
1367 LastFunctionOpVariable =
1368 findLastFunctionOpVariableDeclaration(*MF, *CurrentMAI);
1371void SPIRVNonSemanticDebugHandler::tryEmitDebugFunctionDefinition(
1373 if (DebugFunctionDefinitionEmitted || !GlobalNSDIEnabled)
1376 assert(CurrentMF &&
"no current MachineFunction");
1377 const Function &
F = CurrentMF->getFunction();
1378 const DISubprogram *
SP =
F.getSubprogram();
1379 if (!SP || !
SP->isDefinition())
1382 auto DFIt = DebugScopeRegs.find(SP);
1383 if (DFIt == DebugScopeRegs.end())
1390 emitDebugFunctionDefinition(DFIt->second, OpFunctionReg, MAI);
1391 DebugFunctionDefinitionEmitted =
true;
1396 preparePerFunctionDebug(MF);
1401 resetPerFunctionDebugState();
1408 if (!DebugFunctionDefinitionEmitted)
1411 std::optional<const MachineInstr *>
Target = resolveDebugLocTarget(
MI);
1415 emitDebugScopeForInstruction(*
Target);
1416 emitDebugLineForInstruction(*
Target);
1418 emitDebugDeclare(
MI);
1428static std::optional<Register>
1432 if (!
MI.isIndirectDebugValue())
1433 return std::nullopt;
1437 Register LocReg =
MI.getDebugOperand(0).getReg();
1439 return std::nullopt;
1450 const MachineInstr *Def =
MI.getMF()->getRegInfo().getUniqueVRegDef(LocReg);
1451 if (!Def || Def->getOpcode() != SPIRV::OpVariable)
1452 return std::nullopt;
1457void SPIRVNonSemanticDebugHandler::emitDebugDeclare(
const MachineInstr *
MI) {
1458 assert(DebugFunctionDefinitionEmitted &&
1459 "DebugFunctionDefinition must be emitted");
1460 assert(CurrentMAI &&
"CurrentMAI must be set");
1466 auto VarRegOpt = lookupOptReg(DebugLocalVariableRegs,
MI->getDebugVariable());
1470 auto ExprRegOpt = lookupOptReg(DebugExpressionRegs,
MI->getDebugExpression());
1474 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1479 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1481 emitExtInst(SPIRV::NonSemanticExtInst::DebugDeclare, VoidTypeReg,
1482 ExtInstSetReg, {*VarRegOpt, StorageReg, *ExprRegOpt}, MAI);
1486 return Opcode == SPIRV::OpSelectionMerge || Opcode == SPIRV::OpLoopMerge ||
1487 Opcode == SPIRV::OpLoopControlINTEL;
1494 switch (
MI->getOpcode()) {
1495 case SPIRV::OpFunction:
1496 case SPIRV::OpFunctionParameter:
1497 case SPIRV::OpFunctionEnd:
1498 case SPIRV::OpLabel:
1510 :
MI->getPrevNode();
1511 Adj; Adj = Forward ? Adj->getNextNode() : Adj->getPrevNode()) {
1519std::optional<const MachineInstr *>
1520SPIRVNonSemanticDebugHandler::resolveDebugLocTarget(
const MachineInstr *
MI) {
1521 assert(CurrentMAI &&
"CurrentMAI must be set");
1522 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1527 return std::nullopt;
1535 return std::nullopt;
1541 assert(
MI &&
"Merge instruction must be followed by a terminator");
1547void SPIRVNonSemanticDebugHandler::emitDebugScopeForInstruction(
1549 assert(DebugFunctionDefinitionEmitted &&
1550 "DebugFunctionDefinition must be emitted");
1551 assert(CurrentMAI &&
"CurrentMAI must be set");
1556 if (LastScopeMI &&
MI->getParent() != LastScopeMI->getParent())
1557 LastScopeMI =
nullptr;
1559 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1560 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1563 const DILocation *CurDL =
MI->getDebugLoc().get();
1568 emitExtInst(SPIRV::NonSemanticExtInst::DebugNoScope, VoidTypeReg,
1569 ExtInstSetReg, {}, MAI);
1570 LastScopeMI =
nullptr;
1575 const DIScope *CurScope = CurDL->getScope();
1576 const DILocation *CurInlinedAt = CurDL->getInlinedAt();
1579 const DILocation *LastDL = LastScopeMI->getDebugLoc().get();
1580 if (LastDL->getScope() == CurScope &&
1581 LastDL->getInlinedAt() == CurInlinedAt)
1585 auto CurScopeRegOpt = resolveScope(CurScope);
1586 if (!CurScopeRegOpt)
1592 MCRegister InlinedReg = DebugInlinedAtRegs.lookup(CurInlinedAt);
1595 Ops.push_back(InlinedReg);
1599 emitExtInst(SPIRV::NonSemanticExtInst::DebugScope, VoidTypeReg, ExtInstSetReg,
1605void SPIRVNonSemanticDebugHandler::emitDebugLineForInstruction(
1607 assert(DebugFunctionDefinitionEmitted &&
1608 "DebugFunctionDefinition must be emitted");
1609 assert(CurrentMAI &&
"CurrentMAI must be set");
1614 if (LastLineMI &&
MI->getParent() != LastLineMI->getParent())
1615 LastLineMI =
nullptr;
1617 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1618 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1621 const DILocation *
DL =
MI->getDebugLoc().get();
1626 emitExtInst(SPIRV::NonSemanticExtInst::DebugNoLine, VoidTypeReg,
1627 ExtInstSetReg, {}, MAI);
1628 LastLineMI =
nullptr;
1638 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1639 DL->getScope(),
true);
1640 unsigned Line =
DL->getLine();
1641 unsigned Col =
DL->getColumn();
1643 MCRegister SrcReg = DebugSourceRegByFileStr.lookup(FileStrReg.
id());
1644 MCRegister LineReg = I32ConstantCache.lookup(Line);
1645 MCRegister ColStartReg = I32ConstantCache.lookup(Col);
1646 MCRegister ColEndReg = I32ConstantCache.lookup(Col + 1);
1658 if (LastLineMI &&
MI->getDebugLoc() == LastLineMI->getDebugLoc())
1662 emitExtInst(SPIRV::NonSemanticExtInst::DebugLine, VoidTypeReg, ExtInstSetReg,
1663 {SrcReg, LineReg, LineReg, ColStartReg, ColEndReg}, MAI);
1672 if (!
MI || !GlobalNSDIEnabled || DebugFunctionDefinitionEmitted || !CurrentMF)
1675 if (
MI != LastFunctionOpVariable)
1681 assert(CurrentMAI &&
"CurrentMAI must be set");
1682 tryEmitDebugFunctionDefinition(*CurrentMAI);
1687 if (!GlobalNSDIEnabled || DebugFunctionDefinitionEmitted || !CurrentMF)
1690 assert(CurrentMF == &MF &&
1691 "notification does not match the current MachineFunction");
1693 if (LastFunctionOpVariable)
1699 tryEmitDebugFunctionDefinition(*CurrentMAI);
1702void SPIRVNonSemanticDebugHandler::collectDebugExpressions(
1705 assert(ModuleInfo &&
"MachineModuleInfo must be set during module output");
1713 if (
MI.isDebugValueLike())
1714 Out.insert(
MI.getDebugExpression());
1720 if (GlobalDIEmitted)
1723 GlobalDIEmitted =
true;
1725 if (CompileUnits.empty()) {
1726 GlobalNSDIEnabled =
false;
1732 if (!ExtInstSetReg.
isValid()) {
1733 GlobalNSDIEnabled =
false;
1738 assert(NonSemanticOpStringsSectionEmitted &&
1739 "emitNonSemanticDebugStrings() must run before "
1740 "emitNonSemanticGlobalDebugInfo()");
1745 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1746 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
1748 CachedDebugInfoNoneReg = emitExtInst(SPIRV::NonSemanticExtInst::DebugInfoNone,
1749 VoidTypeReg, ExtInstSetReg, {}, MAI);
1761 MCRegister DebugInfoVersionReg = emitOpConstantI32(100, I32TypeReg, MAI);
1763 emitOpConstantI32(
static_cast<uint32_t>(DwarfVersion), I32TypeReg, MAI);
1768 map_to_vector(CompileUnits, [&](
const CompileUnitInfo &Info) {
1769 return emitOpConstantI32(Info.SpirvSourceLanguage, I32TypeReg, MAI);
1773 for (
auto [Info, SrcLangReg] :
llvm::zip(CompileUnits, SrcLangRegs)) {
1774 MCRegister FileStrReg = ScopeToPathOpStringReg.lookup(Info.TheCU);
1776 "CU path OpString must be emitted in emitNonSemanticDebugStrings");
1777 MCRegister DebugSourceReg = getOrEmitDebugSourceForFileStrReg(
1778 FileStrReg, VoidTypeReg, ExtInstSetReg, MAI);
1780 SPIRV::NonSemanticExtInst::DebugCompilationUnit, VoidTypeReg,
1782 {DebugInfoVersionReg, DwarfVersionReg, DebugSourceReg, SrcLangReg},
1785 DebugScopeRegs[Info.TheCU] = CUDbgReg;
1790 MCRegister I32ZeroReg = emitOpConstantI32(0, I32TypeReg, MAI);
1796 MCRegister NameReg = getCachedOpStringReg(
BT->getName());
1798 static_cast<uint32_t>(
BT->getSizeInBits()), I32TypeReg, MAI);
1802 unsigned Encoding = 0;
1803 switch (
BT->getEncoding()) {
1804 case dwarf::DW_ATE_address:
1807 case dwarf::DW_ATE_boolean:
1810 case dwarf::DW_ATE_float:
1813 case dwarf::DW_ATE_signed:
1816 case dwarf::DW_ATE_signed_char:
1819 case dwarf::DW_ATE_unsigned:
1822 case dwarf::DW_ATE_unsigned_char:
1826 MCRegister EncodingReg = emitOpConstantI32(Encoding, I32TypeReg, MAI);
1829 SPIRV::NonSemanticExtInst::DebugTypeBasic, VoidTypeReg, ExtInstSetReg,
1830 {NameReg, SizeReg, EncodingReg, I32ZeroReg}, MAI);
1831 DebugScopeRegs[
BT] = BTReg;
1836 if (
auto VecReg = emitDebugTypeVector(VT, ExtInstSetReg, MAI))
1837 DebugScopeRegs[VT] = *VecReg;
1842 if (
auto PtrReg = emitDebugTypePointer(PT, ExtInstSetReg, MAI))
1843 DebugScopeRegs[PT] = *PtrReg;
1850 if (
auto ArrReg = emitDebugTypeArray(AT, ExtInstSetReg, MAI))
1851 DebugScopeRegs[AT] = *ArrReg;
1857 emitDebugTypeFunctionForSubroutineType(ST, ExtInstSetReg, MAI))
1858 DebugScopeRegs[ST] = *FnTyReg;
1870 if (
auto LBReg = emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg,
1871 ExtInstSetReg, MAI))
1872 DebugScopeRegs[S] = *LBReg;
1882 emitDebugTypedef(TD, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI))
1883 DebugScopeRegs[TD] = *TDReg;
1887 for (
const DISubprogram *SP : SubprogramDeclarations) {
1888 if (
auto DeclReg = emitDebugFunctionDeclaration(SP, VoidTypeReg, I32TypeReg,
1889 ExtInstSetReg, MAI))
1890 DebugScopeRegs[SP] = *DeclReg;
1901 if (!M || M->getTag() != dwarf::DW_TAG_member)
1903 if (
auto MemberReg = emitDebugTypeMember(M, VoidTypeReg, I32TypeReg,
1904 ExtInstSetReg, MAI))
1907 if (
auto CompReg = emitDebugTypeComposite(CT, MemberRegs, VoidTypeReg,
1908 I32TypeReg, ExtInstSetReg, MAI))
1909 DebugScopeRegs[CT] = *CompReg;
1915 emitDebugFunction(SP, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI))
1916 DebugScopeRegs[SP] = *FnReg;
1925 if (
auto LBReg = emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg,
1926 ExtInstSetReg, MAI))
1927 DebugScopeRegs[S] = *LBReg;
1933 if (
auto LVReg = emitDebugLocalVariable(LV, VoidTypeReg, I32TypeReg,
1934 ExtInstSetReg, MAI))
1935 DebugLocalVariableRegs[LV] = *LVReg;
1942 collectDebugExpressions(Expressions);
1944 if (
auto ExprReg = emitDebugExpression(Expr, VoidTypeReg, I32TypeReg,
1945 ExtInstSetReg, MAI))
1946 DebugExpressionRegs[Expr] = *ExprReg;
1949 for (
const auto &[GV, Info] : GlobalVariableDebugInfoMap)
1950 emitDebugGlobalVariable(GV, Info, VoidTypeReg, I32TypeReg, ExtInstSetReg,
1956 getOrEmitDebugInlinedAt(IA, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
1959 emitOpConstantI32(
DL->getLine(), I32TypeReg, MAI);
1960 emitOpConstantI32(
DL->getColumn(), I32TypeReg, MAI);
1961 emitOpConstantI32(
DL->getColumn() + 1, I32TypeReg, MAI);
1963 getCachedScopePathOpStringReg(
DL->getScope(),
1965 getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg, ExtInstSetReg,
1969 GlobalNSDIEnabled =
true;
1973SPIRVNonSemanticDebugHandler::getDebugFullPath(
const DIScope *Scope)
const {
1983 Out.assign(Dir.
begin(), Dir.
end());
1989MCRegister SPIRVNonSemanticDebugHandler::getOrEmitDebugSourceForFileStrReg(
1992 const unsigned Key = FileStrReg.
id();
1993 auto It = DebugSourceRegByFileStr.find(
Key);
1994 if (It != DebugSourceRegByFileStr.end())
1997 MCRegister
DS = emitExtInst(SPIRV::NonSemanticExtInst::DebugSource,
1998 VoidTypeReg, ExtInstSetReg, {FileStrReg}, MAI);
1999 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)