43 "spirv-debug-lexical-block-discriminator-scope",
44 cl::desc(
"Use a DebugLexicalBlockDiscriminator as a DebugScope"),
51template <
typename MapT>
52static std::optional<MCRegister> lookupOptReg(
const MapT &Map,
53 typename MapT::key_type
Key) {
54 auto It = Map.find(
Key);
57 assert(It->second.isValid() &&
"invalid register stored in map");
62 NSDIFlagIsProtected = 1u << 0,
63 NSDIFlagIsPrivate = 1u << 1,
64 NSDIFlagIsPublic = NSDIFlagIsPrivate | NSDIFlagIsProtected,
65 NSDIFlagIsLocal = 1u << 2,
66 NSDIFlagIsDefinition = 1u << 3,
67 NSDIFlagFwdDecl = 1u << 4,
68 NSDIFlagArtificial = 1u << 5,
69 NSDIFlagExplicit = 1u << 6,
70 NSDIFlagPrototyped = 1u << 7,
71 NSDIFlagObjectPointer = 1u << 8,
72 NSDIFlagStaticMember = 1u << 9,
73 NSDIFlagIndirectVariable = 1u << 10,
74 NSDIFlagLValueReference = 1u << 11,
75 NSDIFlagRValueReference = 1u << 12,
76 NSDIFlagIsOptimized = 1u << 13,
77 NSDIFlagIsEnumClass = 1u << 14,
78 NSDIFlagTypePassByValue = 1u << 15,
79 NSDIFlagTypePassByReference = 1u << 16,
80 NSDIFlagUnknownPhysicalLayout = 1u << 17,
86 Flags |= NSDIFlagIsPublic;
88 Flags |= NSDIFlagIsProtected;
90 Flags |= NSDIFlagIsPrivate;
91 if (DFlags & DINode::FlagFwdDecl)
92 Flags |= NSDIFlagFwdDecl;
93 if (DFlags & DINode::FlagArtificial)
94 Flags |= NSDIFlagArtificial;
95 if (DFlags & DINode::FlagExplicit)
96 Flags |= NSDIFlagExplicit;
97 if (DFlags & DINode::FlagPrototyped)
98 Flags |= NSDIFlagPrototyped;
99 if (DFlags & DINode::FlagObjectPointer)
100 Flags |= NSDIFlagObjectPointer;
101 if (DFlags & DINode::FlagStaticMember)
102 Flags |= NSDIFlagStaticMember;
103 if (DFlags & DINode::FlagLValueReference)
104 Flags |= NSDIFlagLValueReference;
105 if (DFlags & DINode::FlagRValueReference)
106 Flags |= NSDIFlagRValueReference;
107 if (DFlags & DINode::FlagTypePassByValue)
108 Flags |= NSDIFlagTypePassByValue;
109 if (DFlags & DINode::FlagTypePassByReference)
110 Flags |= NSDIFlagTypePassByReference;
111 if (DFlags & DINode::FlagEnumClass)
112 Flags |= NSDIFlagIsEnumClass;
119 if (GV->isLocalToUnit())
120 Flags |= NSDIFlagIsLocal;
121 if (GV->isDefinition())
122 Flags |= NSDIFlagIsDefinition;
125 if (SP->isLocalToUnit())
126 Flags |= NSDIFlagIsLocal;
127 if (SP->isOptimized())
128 Flags |= NSDIFlagIsOptimized;
129 if (SP->isDefinition())
130 Flags |= NSDIFlagIsDefinition;
131 Flags |= mapDIFlagsToNonSemantic(SP->getFlags());
133 if (DN->
getTag() == dwarf::DW_TAG_reference_type)
134 Flags |= NSDIFlagLValueReference;
135 if (DN->
getTag() == dwarf::DW_TAG_rvalue_reference_type)
136 Flags |= NSDIFlagRValueReference;
138 Flags |= mapDIFlagsToNonSemantic(Ty->getFlags());
140 Flags |= mapDIFlagsToNonSemantic(LV->getFlags());
146static uint32_t mapCompositeTypeTag(
unsigned Tag) {
148 case dwarf::DW_TAG_class_type:
150 case dwarf::DW_TAG_structure_type:
152 case dwarf::DW_TAG_union_type:
156 ". Expecting 0, 1 or 2");
171 bool SeenOpVariable =
false;
173 if (
MI.getOpcode() == SPIRV::OpVariable) {
174 SeenOpVariable =
true;
176 LastOpVariable = &
MI;
180 bool CanInterleaveWithOpVariable =
181 MI.getOpcode() == SPIRV::OpLine ||
MI.getOpcode() == SPIRV::OpNoLine;
182 if (SeenOpVariable && !CanInterleaveWithOpVariable &&
186 return LastOpVariable;
197unsigned SPIRVNonSemanticDebugHandler::toNSDISrcLang(
unsigned DwarfSrcLang) {
198 switch (DwarfSrcLang) {
199 case dwarf::DW_LANG_OpenCL:
201 case dwarf::DW_LANG_OpenCL_CPP:
203 case dwarf::DW_LANG_CPP_for_OpenCL:
205 case dwarf::DW_LANG_GLSL:
207 case dwarf::DW_LANG_HLSL:
209 case dwarf::DW_LANG_SYCL:
211 case dwarf::DW_LANG_Zig:
219 return BT->getEncoding() == dwarf::DW_ATE_boolean;
228 unsigned Width =
BT->getSizeInBits();
237 ?
Value.trunc(std::min(Width, 64u)).getZExtValue()
238 :
Value.getZExtValue(),
251 if (DT->getTag() != dwarf::DW_TAG_typedef || !Seen.
insert(DT).second)
253 Ty = DT->getBaseType();
264 unsigned Size =
BT->getSizeInBits();
265 switch (
BT->getEncoding()) {
266 case dwarf::DW_ATE_signed:
267 case dwarf::DW_ATE_unsigned:
268 case dwarf::DW_ATE_signed_char:
269 case dwarf::DW_ATE_unsigned_char:
271 case dwarf::DW_ATE_float:
297 for (
const MDNode *
N : SP->getRetainedNodes())
302 Locations.insert(
DL);
305 Locations.insert(
DL);
321 while (S && !Out.contains(S) &&
337 CompileUnits.clear();
339 EnumCompileUnits.clear();
341 UniqueDebugLocations.clear();
342 GlobalVariableDebugInfoMap.clear();
343 LocalVariables.clear();
344 DebugLocalVariableRegs.clear();
345 DebugExpressionRegs.clear();
346 LexicalBlocks.clear();
347 DebugScopeRegs.clear();
348 ScopesInProgress.clear();
349 FailedScopes.clear();
350 DebugInlinedAtRegs.clear();
351 ScopeToPathOpStringReg.clear();
352 DebugSourceRegByFileStr.clear();
353 OpStringContentCache.clear();
354 ScalarTypeCache.clear();
355 ScalarConstantCache.clear();
356 ConstantValueRegs.clear();
357 DebugOperationCache.clear();
358 DebugExpressionCache.clear();
359 ModuleScopeIds.clear();
360 GlobalDIEmitted =
false;
361 GlobalNSDIEnabled =
false;
362 CurrentMAI =
nullptr;
364 NonSemanticOpStringsSectionEmitted =
false;
374 CompileUnitInfo Info;
377 Info.FilePath = File->getFilename();
380 File->getFilename());
383 Info.SpirvSourceLanguage = toNSDISrcLang(
CU->getSourceLanguage().getName());
384 CompileUnits.push_back(std::move(Info));
386 EnumCompileUnits.try_emplace(ET,
CU);
392 if (
const NamedMDNode *Flags = M->getNamedMetadata(
"llvm.module.flags")) {
393 for (
const auto *
Op : Flags->operands()) {
408 return Ty->getTag() != dwarf::DW_TAG_member;
417 G.getDebugInfo(GVEs);
428 GlobalVariableDebugInfoMap.try_emplace(
429 GV, GlobalVariableDebugInfo{Expr, DIGVToLLVMGV.
lookup(GV)});
447 if (
MI.getNumOperands() == 0 || !
MI.getOperand(0).isReg() ||
448 !
MI.getOperand(0).isDef())
455 if (CompileUnits.empty())
457 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_non_semantic_info))
471 ModuleScopeIds.insert(Id);
475void SPIRVNonSemanticDebugHandler::emitMCInst(
MCInst &Inst) {
480SPIRVNonSemanticDebugHandler::emitOpString(
StringRef S,
491MCRegister SPIRVNonSemanticDebugHandler::emitOpStringIfNew(
494 assert(!NonSemanticOpStringsSectionEmitted &&
495 "emitOpStringIfNew is only valid while emitting SPIR-V section 7");
497 auto [It,
Inserted] = OpStringContentCache.try_emplace(S, MCRegister());
499 It->second = emitOpString(S, MAI);
506 assert(NonSemanticOpStringsSectionEmitted &&
507 "getCachedOpStringReg requires emitNonSemanticDebugStrings() first");
509 auto It = OpStringContentCache.find(S);
510 assert(It != OpStringContentCache.end() &&
511 "NSDI OpString missing from cache; emitNonSemanticDebugStrings must "
512 "cache every string used in section 10");
516MCRegister SPIRVNonSemanticDebugHandler::emitAndCacheScopePathOpStringReg(
518 auto [It,
Inserted] = ScopeToPathOpStringReg.try_emplace(Scope, MCRegister());
520 It->second = emitOpStringIfNew(getDebugFullPath(Scope), MAI);
524MCRegister SPIRVNonSemanticDebugHandler::getCachedScopePathOpStringReg(
525 const DIScope *Scope,
bool UseEmptyPathIfNullScope) {
527 assert(UseEmptyPathIfNullScope &&
528 "null scope path lookup requires UseEmptyPathIfNullScope");
529 assert(CachedEmptyStringReg.isValid() &&
530 "empty path OpString must be cached in emitNonSemanticDebugStrings");
531 return CachedEmptyStringReg;
533 auto It = ScopeToPathOpStringReg.find(Scope);
534 assert(It != ScopeToPathOpStringReg.end() &&
535 "path OpString must be cached in emitNonSemanticDebugStrings");
536 MCRegister FileStrReg = It->second;
537 assert(FileStrReg.
isValid() &&
"path OpString id must be valid once cached");
541MCRegister SPIRVNonSemanticDebugHandler::emitOpConstantI32(
543 return findOrEmitConstant(SPIRV::OpConstantI, I32TypeReg,
Value,
547MCRegister SPIRVNonSemanticDebugHandler::emitExtInst(
548 SPIRV::NonSemanticExtInst::NonSemanticExtInst Opcode,
565MCRegister SPIRVNonSemanticDebugHandler::getOrEmitOpTypeVoidReg(
567 if (!CachedOpTypeVoidReg.isValid())
568 CachedOpTypeVoidReg = findOrEmitOpTypeVoid(MAI);
569 return CachedOpTypeVoidReg;
572MCRegister SPIRVNonSemanticDebugHandler::getOrEmitOpTypeInt32Reg(
574 if (!CachedOpTypeInt32Reg.isValid())
575 CachedOpTypeInt32Reg = findOrEmitOpTypeInt32(MAI);
576 return CachedOpTypeInt32Reg;
579MCRegister SPIRVNonSemanticDebugHandler::findOrEmitOpTypeVoid(
582 if (
MI->getOpcode() == SPIRV::OpTypeVoid)
599 unsigned Width =
BT->getSizeInBits();
603MCRegister SPIRVNonSemanticDebugHandler::findOrEmitScalarType(
606 bool IsFloat =
BT->getEncoding() == dwarf::DW_ATE_float;
607 unsigned Opcode = IsBool ? SPIRV::OpTypeBool
608 : IsFloat ? SPIRV::OpTypeFloat
612 int64_t Width = IsBool ? 0 :
BT->getSizeInBits();
617 if (Opcode == SPIRV::OpTypeInt && Width == 32)
618 return getOrEmitOpTypeInt32Reg(MAI);
621 ScalarTypeCache.try_emplace({Opcode, Width}, MCRegister());
623 return CacheIt->second;
628 if (
MI->getOpcode() != Opcode)
630 if (IsBool || (
MI->getOperand(1).getImm() == Width &&
631 (IsFloat ||
MI->getOperand(2).getImm() == 0))) {
634 return CacheIt->second;
656 CacheIt->second =
Reg;
663 unsigned Words = IsWide ? 2 : 1;
664 if (
MI.getNumOperands() < 2 + Words)
667 for (
unsigned I = 0;
I < Words; ++
I) {
668 if (!
MI.getOperand(2 +
I).isImm())
674 return Found ==
Value;
677MCRegister SPIRVNonSemanticDebugHandler::findModuleConstant(
681 if (
MI->getOpcode() != Opcode ||
MI->getNumOperands() < 2)
695MCRegister SPIRVNonSemanticDebugHandler::findOrEmitConstant(
698 bool IsBool = Width == 0;
699 bool IsWide = Width == 64;
702 ScalarConstantCache.try_emplace({TypeReg.
id(),
Value}, MCRegister());
704 return CacheIt->second;
707 findModuleConstant(Opcode, TypeReg,
Value, IsBool, IsWide, MAI);
709 CacheIt->second = Found;
725 }
else if (Width == 16) {
732 CacheIt->second =
Reg;
736MCRegister SPIRVNonSemanticDebugHandler::findOrEmitScalarConstant(
738 MCRegister TypeReg = findOrEmitScalarType(
BT, MAI);
743 bool IsFloat =
BT->getEncoding() == dwarf::DW_ATE_float;
745 IsBool ? (
Value ? SPIRV::OpConstantTrue : SPIRV::OpConstantFalse)
746 : IsFloat ?
SPIRV::OpConstantF
747 :
SPIRV::OpConstantI;
748 return findOrEmitConstant(Opcode, TypeReg,
Value,
749 IsBool ? 0 :
BT->getSizeInBits(), MAI);
752MCRegister SPIRVNonSemanticDebugHandler::findOrEmitOpTypeInt32(
755 if (
MI->getOpcode() == SPIRV::OpTypeInt &&
756 MI->getOperand(1).getImm() == 32 &&
MI->getOperand(2).getImm() == 0)
772auto SPIRVNonSemanticDebugHandler::getOrCreateDebugScope(
const DIScope *S)
773 -> EmitResult<MCRegister> {
774 if (!S || FailedScopes.contains(S))
775 return EmitResult<MCRegister>::unsupported();
776 if (
auto Reg = lookupOptReg(DebugScopeRegs, S))
777 return EmitResult<MCRegister>::emitted(*
Reg);
781 if (!ScopesInProgress.insert(S).second)
782 return EmitResult<MCRegister>::inProgress();
784 EmitResult<PreparedScope>
P = emitDebugScope(S);
785 ScopesInProgress.erase(S);
786 assert((!
P || !GlobalNSDIEnabled) &&
787 "debug type or scope created after module-scope NSDI emission");
789 if (
P.Status == EmitStatus::Unsupported)
790 FailedScopes.insert(S);
791 return P.Status == EmitStatus::InProgress
792 ? EmitResult<MCRegister>::inProgress()
799 emitExtInst(
P.Value->Opcode, getOrEmitOpTypeVoidReg(MAI),
801 DebugScopeRegs[S] =
Reg;
802 return EmitResult<MCRegister>::emitted(
Reg);
805auto SPIRVNonSemanticDebugHandler::emitDebugTypeBasic(
809 return EmitResult<PreparedScope>::unsupported();
811 MCRegister NameReg = getCachedOpStringReg(
BT->getName());
813 static_cast<uint32_t
>(
BT->getSizeInBits()), I32TypeReg, MAI);
817 unsigned Encoding = 0;
818 switch (
BT->getEncoding()) {
819 case dwarf::DW_ATE_address:
822 case dwarf::DW_ATE_boolean:
825 case dwarf::DW_ATE_float:
828 case dwarf::DW_ATE_signed:
831 case dwarf::DW_ATE_signed_char:
834 case dwarf::DW_ATE_unsigned:
837 case dwarf::DW_ATE_unsigned_char:
841 MCRegister EncodingReg = emitOpConstantI32(Encoding, I32TypeReg, MAI);
842 MCRegister FlagsReg = emitOpConstantI32(0, I32TypeReg, MAI);
843 return EmitResult<PreparedScope>::emitted(
844 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypeBasic,
845 {NameReg, SizeReg, EncodingReg, FlagsReg}});
848auto SPIRVNonSemanticDebugHandler::emitDebugScope(
const DIScope *S)
849 -> EmitResult<PreparedScope> {
850 assert(CurrentMAI &&
"emitDebugScope requires CurrentMAI");
853 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
854 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
857 return emitDebugTypeBasic(
BT, I32TypeReg, MAI);
859 return emitDebugTypeFunctionForSubroutineType(ST, MAI);
861 return emitDebugTypeForCompositeType(CT, VoidTypeReg, I32TypeReg,
864 return emitDebugTypeForDerivedType(DT, VoidTypeReg, I32TypeReg,
867 return emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg, ExtInstSetReg,
870 return emitDebugLexicalBlockDiscriminator(LBF, VoidTypeReg, I32TypeReg,
873 if (
SP->isDefinition())
874 return emitDebugFunction(SP, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
875 return emitDebugFunctionDeclaration(SP, VoidTypeReg, I32TypeReg,
878 return EmitResult<PreparedScope>::unsupported();
881auto SPIRVNonSemanticDebugHandler::emitDebugTypeForCompositeType(
884 -> EmitResult<PreparedScope> {
885 switch (CT->getTag()) {
886 case dwarf::DW_TAG_array_type:
899 return emitDebugTypeVector(CT, MAI);
900 return emitDebugTypeArray(CT, MAI);
901 case dwarf::DW_TAG_structure_type:
902 case dwarf::DW_TAG_class_type:
903 case dwarf::DW_TAG_union_type:
904 return emitDebugTypeComposite(CT, VoidTypeReg, I32TypeReg, ExtInstSetReg,
906 case dwarf::DW_TAG_enumeration_type:
907 return emitDebugTypeEnum(CT, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
909 return EmitResult<PreparedScope>::unsupported();
913auto SPIRVNonSemanticDebugHandler::emitDebugTypeForDerivedType(
916 -> EmitResult<PreparedScope> {
917 switch (DT->getTag()) {
918 case dwarf::DW_TAG_pointer_type:
919 return emitDebugTypePointer(DT, MAI);
920 case dwarf::DW_TAG_typedef:
921 return emitDebugTypedef(DT, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
922 case dwarf::DW_TAG_member:
923 return emitDebugTypeMember(DT, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
925 return EmitResult<PreparedScope>::unsupported();
929auto SPIRVNonSemanticDebugHandler::emitDebugTypePointer(
931 -> EmitResult<PreparedScope> {
934 if (!PT->getDWARFAddressSpace().has_value())
935 return EmitResult<PreparedScope>::unsupported();
938 if (
const DIType *BaseTy = PT->getBaseType()) {
939 EmitResult<MCRegister>
Base = getOrCreateDebugScope(BaseTy);
941 return EmitResult<PreparedScope>::failure(
Base);
948 BaseReg = CachedDebugInfoNoneReg;
951 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
953 emitOpConstantI32(transDebugFlags(PT), I32TypeReg, MAI);
958 MCRegister StorageClassReg = emitOpConstantI32(
962 return EmitResult<PreparedScope>::emitted(
963 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypePointer,
964 {
BaseReg, StorageClassReg, DebugTypePointerFlagsReg}});
967auto SPIRVNonSemanticDebugHandler::emitDebugTypeFunctionForSubroutineType(
969 -> EmitResult<PreparedScope> {
970 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
971 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
973 emitOpConstantI32(transDebugFlags(ST), I32TypeReg, MAI);
974 DITypeArray
TA =
ST->getTypeArray();
981 Ops.push_back(VoidTypeReg);
983 for (
unsigned I = 0,
E =
TA.size();
I !=
E; ++
I) {
984 bool IsReturnType = (
I == 0);
985 EmitResult<MCRegister>
Slot =
986 mapDISignatureTypeToReg(TA[
I], VoidTypeReg, IsReturnType);
990 return EmitResult<PreparedScope>::failure(Slot);
994 return EmitResult<PreparedScope>::emitted(
995 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypeFunction,
Ops});
999auto SPIRVNonSemanticDebugHandler::resolveScope(
const DIScope *Scope,
1001 -> EmitResult<MCRegister> {
1004 Scope = LBF->getScope();
1009 return getOrCreateDebugScope(Scope);
1012 auto CUResult = [](std::optional<MCRegister>
Reg) {
1013 return Reg ? EmitResult<MCRegister>::emitted(*
Reg)
1017 return CUResult(lookupOptReg(DebugScopeRegs, FallbackCU));
1019 if (CompileUnits.empty())
1020 return EmitResult<MCRegister>::unsupported();
1022 return CUResult(lookupOptReg(DebugScopeRegs, CompileUnits[0].TheCU));
1025auto SPIRVNonSemanticDebugHandler::emitDebugLexicalBlock(
1028 -> EmitResult<PreparedScope> {
1030 "S must be a DILexicalBlock or DINamespace in emitDebugLexicalBlock");
1031 EmitResult<MCRegister> Parent =
resolveScope(S->getScope());
1033 return EmitResult<PreparedScope>::failure(Parent);
1035 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1036 S->getFile(),
true);
1037 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1038 ExtInstSetReg, MAI);
1042 MCRegister LineReg = emitOpConstantI32(
static_cast<uint32_t
>(LB->getLine()),
1045 static_cast<uint32_t
>(LB->getColumn()), I32TypeReg, MAI);
1046 Ops = {SrcReg, LineReg, ColReg, *Parent.Value};
1050 MCRegister LineReg = emitOpConstantI32(0, I32TypeReg, MAI);
1051 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1052 MCRegister NameReg = getCachedOpStringReg(NS->getName());
1053 Ops = {SrcReg, LineReg, ColReg, *Parent.Value, NameReg};
1056 return EmitResult<PreparedScope>::emitted(
1057 PreparedScope{SPIRV::NonSemanticExtInst::DebugLexicalBlock,
Ops});
1060auto SPIRVNonSemanticDebugHandler::emitDebugLexicalBlockDiscriminator(
1064 assert(LBF &&
"LBF must not be null");
1065 EmitResult<MCRegister> Parent =
resolveScope(LBF->getScope());
1067 return EmitResult<PreparedScope>::failure(Parent);
1069 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1070 LBF->getFile(),
true);
1071 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1072 ExtInstSetReg, MAI);
1074 static_cast<uint32_t
>(LBF->getDiscriminator()), I32TypeReg, MAI);
1075 return EmitResult<PreparedScope>::emitted(
1076 PreparedScope{SPIRV::NonSemanticExtInst::DebugLexicalBlockDiscriminator,
1077 {SrcReg, DiscReg, *Parent.Value}});
1080MCRegister SPIRVNonSemanticDebugHandler::getOrEmitDebugInlinedAt(
1083 assert(IA &&
"IA must not be null in getOrEmitDebugInlinedAt");
1085 if (MCRegister Cached = DebugInlinedAtRegs.lookup(IA))
1088 EmitResult<MCRegister>
Scope = resolveScope(
IA->getScope());
1090 return MCRegister();
1092 MCRegister LineReg =
1093 emitOpConstantI32(
static_cast<uint32_t
>(
IA->getLine()), I32TypeReg, MAI);
1098 if (
const DILocation *Outer =
IA->getInlinedAt()) {
1099 MCRegister OuterReg = getOrEmitDebugInlinedAt(
1100 Outer, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
1102 return MCRegister();
1103 Ops.push_back(OuterReg);
1106 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugInlinedAt,
1107 VoidTypeReg, ExtInstSetReg,
Ops, MAI);
1108 DebugInlinedAtRegs[
IA] =
Reg;
1112auto SPIRVNonSemanticDebugHandler::emitDebugFunctionDeclaration(
1115 -> EmitResult<PreparedScope> {
1116 assert(SP &&
"SP must not be null in emitDebugFunctionDeclaration");
1118 "SP must not be a definition in emitDebugFunctionDeclaration");
1121 EmitResult<MCRegister> FnTy = getOrCreateDebugScope(
SP->getType());
1123 return EmitResult<PreparedScope>::failure(FnTy);
1125 EmitResult<MCRegister> Parent =
resolveScope(
SP->getScope(),
SP->getUnit());
1127 return EmitResult<PreparedScope>::failure(Parent);
1129 MCRegister FileStrReg = getCachedScopePathOpStringReg(SP);
1131 MCRegister NameReg = getCachedOpStringReg(
SP->getName());
1132 MCRegister LinkageReg = getCachedOpStringReg(
SP->getLinkageName());
1133 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1134 ExtInstSetReg, MAI);
1137 emitOpConstantI32(
static_cast<uint32_t
>(
SP->getLine()), I32TypeReg, MAI);
1138 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1140 uint32_t FlagsVal = transDebugFlags(SP);
1143 FlagsVal &= ~NSDIFlagIsDefinition;
1144 MCRegister FlagsReg = emitOpConstantI32(FlagsVal, I32TypeReg, MAI);
1146 return EmitResult<PreparedScope>::emitted(
1147 PreparedScope{SPIRV::NonSemanticExtInst::DebugFunctionDeclaration,
1148 {NameReg, *FnTy.Value, SrcReg, LineReg, ColReg,
1149 *Parent.Value, LinkageReg, FlagsReg}});
1152auto SPIRVNonSemanticDebugHandler::emitDebugFunction(
1155 -> EmitResult<PreparedScope> {
1156 assert(SP &&
"SP must not be null in emitDebugFunction");
1157 assert(
SP->isDefinition() &&
"SP must be a definition in emitDebugFunction");
1159 EmitResult<MCRegister> FnTy = getOrCreateDebugScope(
SP->getType());
1161 return EmitResult<PreparedScope>::failure(FnTy);
1163 EmitResult<MCRegister> Parent =
resolveScope(
SP->getScope(),
SP->getUnit());
1165 return EmitResult<PreparedScope>::failure(Parent);
1167 MCRegister NameReg = getCachedOpStringReg(
SP->getName());
1168 MCRegister LinkageReg = getCachedOpStringReg(
SP->getLinkageName());
1169 MCRegister FileStrReg = getCachedScopePathOpStringReg(SP);
1170 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1171 ExtInstSetReg, MAI);
1174 emitOpConstantI32(
static_cast<uint32_t
>(
SP->getLine()), I32TypeReg, MAI);
1177 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1178 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(SP), I32TypeReg, MAI);
1180 static_cast<uint32_t
>(
SP->getScopeLine()), I32TypeReg, MAI);
1183 LineReg, ColReg, *Parent.Value,
1184 LinkageReg, FlagsReg, ScopeLineReg};
1187 EmitResult<MCRegister> DeclRes = getOrCreateDebugScope(Decl);
1189 Ops.push_back(*DeclRes.Value);
1192 return EmitResult<PreparedScope>::emitted(
1193 PreparedScope{SPIRV::NonSemanticExtInst::DebugFunction,
Ops});
1196auto SPIRVNonSemanticDebugHandler::mapDISignatureTypeToReg(
1198 -> EmitResult<MCRegister> {
1201 return EmitResult<MCRegister>::emitted(VoidTypeReg);
1202 assert(CachedDebugInfoNoneReg.isValid() &&
1203 "DebugInfoNone must be emitted before DISubroutineType operands");
1204 return EmitResult<MCRegister>::emitted(CachedDebugInfoNoneReg);
1206 return getOrCreateDebugScope(Ty);
1224static std::optional<NonSemanticDebugOp>
1227 case dwarf::DW_OP_deref:
1229 case dwarf::DW_OP_plus:
1231 case dwarf::DW_OP_minus:
1233 case dwarf::DW_OP_plus_uconst:
1235 case dwarf::DW_OP_bit_piece:
1237 case dwarf::DW_OP_swap:
1239 case dwarf::DW_OP_xderef:
1241 case dwarf::DW_OP_stack_value:
1243 case dwarf::DW_OP_constu:
1248 return std::nullopt;
1254static std::optional<SmallVector<uint32_t, 3>>
1256 std::optional<NonSemanticDebugOp> NSOp =
1259 return std::nullopt;
1262 for (
unsigned I = 0,
E =
Op.getNumArgs();
I !=
E; ++
I) {
1265 return std::nullopt;
1271std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugOperation(
1277 return std::nullopt;
1279 auto [It,
Inserted] = DebugOperationCache.try_emplace(std::move(*
Key));
1284 for (uint32_t V : It->first)
1285 Operands.push_back(emitOpConstantI32(V, I32TypeReg, MAI));
1286 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugOperation,
1287 VoidTypeReg, ExtInstSetReg,
Operands, MAI);
1292std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugExpression(
1295 assert(Expr &&
"Expr must not be null in emitDebugExpression");
1298 for (
const DIExpression::ExprOperand &
Op : Expr->
expr_ops()) {
1299 std::optional<MCRegister> OpReg =
1300 emitDebugOperation(
Op, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
1302 return std::nullopt;
1307 DebugExpressionCache.try_emplace(std::move(OperationRegs));
1311 MCRegister
Reg = emitExtInst(SPIRV::NonSemanticExtInst::DebugExpression,
1312 VoidTypeReg, ExtInstSetReg, It->first, MAI);
1317std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugGlobalVariable(
1321 assert(GV &&
"GV must not be null in emitDebugGlobalVariable");
1323 EmitResult<MCRegister> Parent = resolveScope(GV->
getScope());
1325 return std::nullopt;
1327 MCRegister ParentReg = *Parent.Value;
1333 MCRegister TyReg = CachedDebugInfoNoneReg;
1334 if (
const DIType *Ty = GV->
getType()) {
1335 auto TyRegOpt = lookupOptReg(DebugScopeRegs, Ty);
1337 return std::nullopt;
1341 std::optional<MCRegister> StaticMemberRegOpt;
1344 StaticMemberRegOpt = lookupOptReg(DebugScopeRegs, SM);
1345 if (!StaticMemberRegOpt)
1346 return std::nullopt;
1349 MCRegister NameReg = getCachedOpStringReg(GV->
getName());
1350 MCRegister LinkageReg = getCachedOpStringReg(GV->
getLinkageName());
1351 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1353 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1354 ExtInstSetReg, MAI);
1356 MCRegister LineReg =
1357 emitOpConstantI32(
static_cast<uint32_t
>(GV->
getLine()), I32TypeReg, MAI);
1361 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1368 MCRegister VariableReg = CachedDebugInfoNoneReg;
1369 if (
const GlobalVariable *LLVMGV =
Info.LLVMGV) {
1372 VariableReg = GVReg;
1373 }
else if (
Info.Expr &&
Info.Expr->getNumElements() != 0) {
1374 if (
auto ExprReg = emitDebugExpression(
Info.Expr, VoidTypeReg, I32TypeReg,
1375 ExtInstSetReg, MAI))
1376 VariableReg = *ExprReg;
1379 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(GV), I32TypeReg, MAI);
1382 LineReg, ColReg, ParentReg,
1383 LinkageReg, VariableReg, FlagsReg};
1385 if (StaticMemberRegOpt)
1386 Ops.push_back(*StaticMemberRegOpt);
1388 return emitExtInst(SPIRV::NonSemanticExtInst::DebugGlobalVariable,
1389 VoidTypeReg, ExtInstSetReg,
Ops, MAI);
1392std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugLocalVariable(
1395 assert(LV &&
"LV must not be null in emitDebugLocalVariable");
1397 EmitResult<MCRegister> Parent = resolveScope(LV->
getScope());
1399 return std::nullopt;
1401 MCRegister TyReg = CachedDebugInfoNoneReg;
1402 if (
const DIType *Ty = LV->
getType()) {
1403 auto TyRegOpt = lookupOptReg(DebugScopeRegs, Ty);
1405 return std::nullopt;
1409 MCRegister NameReg = getCachedOpStringReg(LV->
getName());
1410 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1412 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1413 ExtInstSetReg, MAI);
1414 MCRegister LineReg =
1415 emitOpConstantI32(
static_cast<uint32_t
>(LV->
getLine()), I32TypeReg, MAI);
1417 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1418 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(LV), I32TypeReg, MAI);
1421 ColReg, *Parent.Value, FlagsReg};
1422 if (
unsigned Arg = LV->
getArg())
1423 Ops.push_back(emitOpConstantI32(Arg, I32TypeReg, MAI));
1425 return emitExtInst(SPIRV::NonSemanticExtInst::DebugLocalVariable, VoidTypeReg,
1426 ExtInstSetReg,
Ops, MAI);
1429auto SPIRVNonSemanticDebugHandler::emitDebugTypeVector(
1431 -> EmitResult<PreparedScope> {
1434 return EmitResult<PreparedScope>::unsupported();
1438 DINodeArray
Elements = VT->getElements();
1440 return EmitResult<PreparedScope>::unsupported();
1444 return EmitResult<PreparedScope>::unsupported();
1446 EmitResult<MCRegister>
Base = getOrCreateDebugScope(BaseTy);
1448 return EmitResult<PreparedScope>::failure(
Base);
1450 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
1452 static_cast<uint32_t
>(CI->getZExtValue()), I32TypeReg, MAI);
1453 return EmitResult<PreparedScope>::emitted(PreparedScope{
1454 SPIRV::NonSemanticExtInst::DebugTypeVector, {*
Base.Value, CountReg}});
1457auto SPIRVNonSemanticDebugHandler::emitDebugTypeArray(
1459 -> EmitResult<PreparedScope> {
1462 EmitResult<MCRegister>
Base = getOrCreateDebugScope(AT->getBaseType());
1464 return EmitResult<PreparedScope>::failure(
Base);
1466 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
1474 for (
const DINode *Element : AT->getElements()) {
1486 if (
Value.getActiveBits() <= 32)
1487 Count =
static_cast<uint32_t
>(
Value.getZExtValue());
1489 Ops.push_back(emitOpConstantI32(
Count, I32TypeReg, MAI));
1492 return EmitResult<PreparedScope>::emitted(
1493 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypeArray,
Ops});
1496auto SPIRVNonSemanticDebugHandler::emitDebugTypeMember(
1499 -> EmitResult<PreparedScope> {
1500 EmitResult<MCRegister> Ty = getOrCreateDebugScope(
M->getBaseType());
1502 return EmitResult<PreparedScope>::failure(Ty);
1505 return EmitResult<PreparedScope>::unsupported();
1507 MCRegister NameReg = getCachedOpStringReg(
M->getName());
1508 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1509 M->getFile(),
true);
1510 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1511 ExtInstSetReg, MAI);
1513 emitOpConstantI32(
static_cast<uint32_t
>(
M->getLine()), I32TypeReg, MAI);
1516 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1518 static_cast<uint32_t
>(
M->getOffsetInBits()), I32TypeReg, MAI);
1520 static_cast<uint32_t
>(
M->getSizeInBits()), I32TypeReg, MAI);
1521 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(M), I32TypeReg, MAI);
1532 return EmitResult<PreparedScope>::emitted(
1533 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypeMember,
1534 {NameReg, *Ty.Value, SrcReg, LineReg, ColReg, OffsetReg,
1535 SizeReg, FlagsReg}});
1538auto SPIRVNonSemanticDebugHandler::emitDebugTypeComposite(
1541 -> EmitResult<PreparedScope> {
1544 EmitResult<MCRegister> Parent =
resolveScope(CT->getScope());
1546 return EmitResult<PreparedScope>::failure(Parent);
1549 return EmitResult<PreparedScope>::unsupported();
1552 for (
const DINode *Element : CT->getElements()) {
1554 if (!M ||
M->getTag() != dwarf::DW_TAG_member)
1556 EmitResult<MCRegister>
Member = getOrCreateDebugScope(M);
1561 MCRegister NameReg = getCachedOpStringReg(CT->getName());
1562 MCRegister LinkageReg = getCachedOpStringReg(CT->getIdentifier());
1563 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1564 CT->getFile(),
true);
1565 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1566 ExtInstSetReg, MAI);
1569 emitOpConstantI32(mapCompositeTypeTag(CT->getTag()), I32TypeReg, MAI);
1571 emitOpConstantI32(
static_cast<uint32_t
>(CT->getLine()), I32TypeReg, MAI);
1572 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1576 if (!CT->isForwardDecl())
1577 SizeReg = emitOpConstantI32(
static_cast<uint32_t
>(CT->getSizeInBits()),
1580 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(CT), I32TypeReg, MAI);
1583 LineReg, ColReg, *Parent.Value,
1584 LinkageReg, SizeReg, FlagsReg};
1586 return EmitResult<PreparedScope>::emitted(
1587 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypeComposite,
Ops});
1590auto SPIRVNonSemanticDebugHandler::emitDebugTypeEnum(
1593 -> EmitResult<PreparedScope> {
1597 return EmitResult<PreparedScope>::unsupported();
1599 MCRegister UnderlyingReg = CachedDebugInfoNoneReg;
1600 if (
const DIType *BaseTy = ET->getBaseType()) {
1601 EmitResult<MCRegister>
Base = getOrCreateDebugScope(BaseTy);
1603 return EmitResult<PreparedScope>::failure(
Base);
1604 UnderlyingReg = *
Base.Value;
1607 EmitResult<MCRegister> Parent =
1608 resolveScope(ET->getScope(), EnumCompileUnits.lookup(ET));
1610 return EmitResult<PreparedScope>::failure(Parent);
1612 MCRegister NameReg = getCachedOpStringReg(ET->getName());
1613 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1614 ET->getFile(),
true);
1615 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1616 ExtInstSetReg, MAI);
1618 emitOpConstantI32(
static_cast<uint32_t
>(ET->getLine()), I32TypeReg, MAI);
1620 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1622 emitOpConstantI32(
static_cast<uint32_t
>(
Size), I32TypeReg, MAI);
1623 MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(ET), I32TypeReg, MAI);
1626 ColReg, *Parent.Value, SizeReg, FlagsReg};
1631 for (
const DINode *Element : ET->getElements()) {
1636 if (
E->isUnsigned() ? !
Value.isIntN(32) : !
Value.isSignedIntN(32))
1638 uint32_t
Bits =
E->isUnsigned()
1639 ?
static_cast<uint32_t
>(
Value.getZExtValue())
1640 :
static_cast<uint32_t
>(
Value.getSExtValue());
1641 Ops.push_back(emitOpConstantI32(Bits, I32TypeReg, MAI));
1642 Ops.push_back(getCachedOpStringReg(
E->getName()));
1645 return EmitResult<PreparedScope>::emitted(
1646 PreparedScope{SPIRV::NonSemanticExtInst::DebugTypeEnum,
Ops});
1649auto SPIRVNonSemanticDebugHandler::emitDebugTypedef(
1652 -> EmitResult<PreparedScope> {
1653 EmitResult<MCRegister>
Base = getOrCreateDebugScope(TD->getBaseType());
1655 return EmitResult<PreparedScope>::failure(
Base);
1657 MCRegister NameReg = getCachedOpStringReg(TD->getName());
1658 MCRegister FileStrReg = getCachedScopePathOpStringReg(
1659 TD->getFile(),
true);
1660 MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg,
1661 ExtInstSetReg, MAI);
1663 emitOpConstantI32(
static_cast<uint32_t
>(TD->getLine()), I32TypeReg, MAI);
1665 MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI);
1670 EmitResult<MCRegister> Parent =
resolveScope(TD->getScope());
1672 return EmitResult<PreparedScope>::failure(Parent);
1674 return EmitResult<PreparedScope>::emitted(PreparedScope{
1675 SPIRV::NonSemanticExtInst::DebugTypedef,
1676 {NameReg, *
Base.Value, SrcReg, LineReg, ColReg, *Parent.Value}});
1681 if (CompileUnits.empty())
1689 for (
const CompileUnitInfo &Info : CompileUnits) {
1691 MCRegister PathReg = emitOpStringIfNew(Info.FilePath, MAI);
1692 ScopeToPathOpStringReg[Info.TheCU] = PathReg;
1693 if (
const DIFile *
F = Info.TheCU->getFile())
1694 ScopeToPathOpStringReg[
F] = PathReg;
1699 emitOpStringIfNew(SP->getName(), MAI);
1700 emitOpStringIfNew(SP->getLinkageName(), MAI);
1701 emitAndCacheScopePathOpStringReg(SP, MAI);
1704 for (
const DIType *Ty : DebugTypes) {
1706 emitOpStringIfNew(
BT->getName(), MAI);
1712 if (CT->getTag() == dwarf::DW_TAG_enumeration_type) {
1713 emitOpStringIfNew(CT->getName(), MAI);
1714 emitAndCacheScopePathOpStringReg(CT->getFile(), MAI);
1715 for (
const DINode *Element : CT->getElements())
1717 emitOpStringIfNew(E->getName(), MAI);
1723 if (CT->getTag() != dwarf::DW_TAG_structure_type &&
1724 CT->getTag() != dwarf::DW_TAG_class_type &&
1725 CT->getTag() != dwarf::DW_TAG_union_type)
1727 emitOpStringIfNew(CT->getName(), MAI);
1728 emitOpStringIfNew(CT->getIdentifier(), MAI);
1729 emitAndCacheScopePathOpStringReg(CT->getFile(), MAI);
1730 for (
const DINode *Element : CT->getElements()) {
1732 if (!M || M->getTag() != dwarf::DW_TAG_member)
1734 emitOpStringIfNew(M->getName(), MAI);
1735 emitAndCacheScopePathOpStringReg(M->getFile(), MAI);
1741 if (TD && TD->getTag() == dwarf::DW_TAG_typedef) {
1742 emitOpStringIfNew(TD->getName(), MAI);
1743 emitAndCacheScopePathOpStringReg(TD->getFile(), MAI);
1747 for (
const auto &[GV,
_] : GlobalVariableDebugInfoMap) {
1748 emitOpStringIfNew(GV->
getName(), MAI);
1750 emitAndCacheScopePathOpStringReg(GV->
getFile(), MAI);
1754 emitOpStringIfNew(LV->
getName(), MAI);
1755 emitAndCacheScopePathOpStringReg(LV->
getFile(), MAI);
1758 for (
const DIScope *S : LexicalBlocks) {
1759 emitAndCacheScopePathOpStringReg(S->getFile(), MAI);
1761 emitOpStringIfNew(NS->getName(), MAI);
1765 emitAndCacheScopePathOpStringReg(
DL->getScope(), MAI);
1767 CachedEmptyStringReg = emitOpStringIfNew(
"", MAI);
1770 NonSemanticOpStringsSectionEmitted =
true;
1774void SPIRVNonSemanticDebugHandler::emitDebugFunctionDefinition(
1778 "DebugFunctionDefinition operands must be valid");
1779 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1781 emitExtInst(SPIRV::NonSemanticExtInst::DebugFunctionDefinition, VoidTypeReg,
1782 ExtInstSetReg, {DebugFunctionReg, OpFunctionReg}, MAI);
1785void SPIRVNonSemanticDebugHandler::resetPerFunctionDebugState() {
1786 CurrentMF =
nullptr;
1787 LastFunctionOpVariable =
nullptr;
1788 DebugFunctionDefinitionEmitted =
false;
1789 LastLineMI =
nullptr;
1790 LastScopeMI =
nullptr;
1794void SPIRVNonSemanticDebugHandler::preparePerFunctionDebug(
1796 resetPerFunctionDebugState();
1797 if (!GlobalNSDIEnabled || !CurrentMAI)
1808 if (!SP || !
SP->isDefinition())
1813 LastFunctionOpVariable =
1814 findLastFunctionOpVariableDeclaration(*MF, *CurrentMAI);
1816 analyzeDebugRecords(*MF);
1819void SPIRVNonSemanticDebugHandler::tryEmitDebugFunctionDefinition(
1821 if (DebugFunctionDefinitionEmitted || !GlobalNSDIEnabled)
1824 assert(CurrentMF &&
"no current MachineFunction");
1825 const Function &
F = CurrentMF->getFunction();
1826 const DISubprogram *
SP =
F.getSubprogram();
1827 if (!SP || !
SP->isDefinition())
1830 auto DFIt = DebugScopeRegs.find(SP);
1831 if (DFIt == DebugScopeRegs.end())
1838 emitDebugFunctionDefinition(DFIt->second, OpFunctionReg, MAI);
1839 DebugFunctionDefinitionEmitted =
true;
1844 preparePerFunctionDebug(MF);
1849 resetPerFunctionDebugState();
1856 if (!DebugFunctionDefinitionEmitted)
1859 emitAnalyzedRecords(
MI);
1861 std::optional<const MachineInstr *>
Target = resolveDebugLocTarget(
MI);
1865 (void)emitDebugScopeForInstruction(*
Target);
1866 emitDebugLineForInstruction(*
Target);
1876static std::optional<Register>
1880 if (!
MI.isIndirectDebugValue())
1881 return std::nullopt;
1885 Register LocReg =
MI.getDebugOperand(0).getReg();
1887 return std::nullopt;
1898 const MachineInstr *Def =
MI.getMF()->getRegInfo().getUniqueVRegDef(LocReg);
1899 if (!Def || Def->getOpcode() != SPIRV::OpVariable)
1900 return std::nullopt;
1905void SPIRVNonSemanticDebugHandler::emitDebugBinding(
1906 SPIRV::NonSemanticExtInst::NonSemanticExtInst Opcode,
1908 assert(DebugFunctionDefinitionEmitted &&
1909 "DebugFunctionDefinition must be emitted");
1910 assert(CurrentMAI &&
"CurrentMAI must be set");
1912 auto VarRegOpt = lookupOptReg(DebugLocalVariableRegs,
MI->getDebugVariable());
1916 auto ExprRegOpt = lookupOptReg(DebugExpressionRegs,
MI->getDebugExpression());
1920 if (!emitDebugScopeForInstruction(
MI))
1922 emitDebugLineForInstruction(
MI);
1924 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
1925 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
1927 emitExtInst(Opcode, VoidTypeReg, ExtInstSetReg,
1928 {*VarRegOpt, LocationReg, *ExprRegOpt}, MAI);
1933static std::optional<std::pair<const DIBasicType *, uint64_t>>
1935 if (!
MI.isNonListDebugValue() ||
MI.isIndirectDebugValue())
1936 return std::nullopt;
1940 return std::nullopt;
1945 return std::nullopt;
1950 else if (
Value.isCImm())
1954 return std::make_pair(
BT, Bits);
1957std::optional<MCRegister> SPIRVNonSemanticDebugHandler::getConstantValueReg(
1959 std::optional<std::pair<const DIBasicType *, uint64_t>>
Const =
1962 return std::nullopt;
1964 auto It = ConstantValueRegs.find(*Const);
1965 if (It == ConstantValueRegs.end() || !It->second.isValid())
1966 return std::nullopt;
1971 if (!
MI.isNonListDebugValue() ||
MI.isIndirectDebugValue())
1972 return std::nullopt;
1976 return std::nullopt;
1980 return std::nullopt;
1982 const MachineInstr *Def =
MI.getMF()->getRegInfo().getUniqueVRegDef(ValueReg);
1983 if (!Def || (Def->isPseudo() && !Def->isPHI()) || Def->isMetaInstruction() ||
1984 Def->getNumOperands() == 0 || !Def->getOperand(0).isReg() ||
1985 !Def->getOperand(0).isDef() || Def->getOperand(0).getReg() != ValueReg)
1986 return std::nullopt;
1992 return Opcode == SPIRV::OpSelectionMerge || Opcode == SPIRV::OpLoopMerge ||
1993 Opcode == SPIRV::OpLoopControlINTEL;
2005 switch (
MI->getOpcode()) {
2006 case SPIRV::OpFunction:
2007 case SPIRV::OpFunctionParameter:
2008 case SPIRV::OpFunctionEnd:
2009 case SPIRV::OpLabel:
2010 case TargetOpcode::PHI:
2021 :
MI->getPrevNode();
2022 Adj; Adj = Forward ? Adj->getNextNode() : Adj->getPrevNode()) {
2030std::optional<const MachineInstr *>
2031SPIRVNonSemanticDebugHandler::resolveDebugLocTarget(
const MachineInstr *
MI) {
2032 assert(CurrentMAI &&
"CurrentMAI must be set");
2033 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
2038 return std::nullopt;
2046 return std::nullopt;
2052 assert(
MI &&
"Merge instruction must be followed by a terminator");
2056 return std::nullopt;
2062void SPIRVNonSemanticDebugHandler::resolveDebugRecord(
2065 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
2071 const MachineInstr *Anchor =
2081 placeRecord(SPIRV::NonSemanticExtInst::DebugDeclare,
MI, StorageReg,
2086 if (std::optional<MCRegister> ConstReg = getConstantValueReg(
MI)) {
2087 placeRecord(SPIRV::NonSemanticExtInst::DebugValue,
MI, *ConstReg, Anchor);
2107 if (ModuleScopeIds.contains(ValueReg) ||
2109 placeRecord(SPIRV::NonSemanticExtInst::DebugValue,
MI, ValueReg, Anchor);
2112void SPIRVNonSemanticDebugHandler::analyzeDebugRecords(
2114 assert(CurrentMAI &&
"CurrentMAI must be set");
2118 std::optional<MachineDominatorTree> DomTree;
2120 for (
const MachineBasicBlock &
MBB : MF) {
2121 const MachineInstr *LastEmitted =
nullptr;
2122 for (
const MachineInstr &
MI :
MBB) {
2123 if (
MI.isDebugValueLike()) {
2126 resolveDebugRecord(
MI, LastEmitted, *DomTree);
2135void SPIRVNonSemanticDebugHandler::placeRecord(
2136 SPIRV::NonSemanticExtInst::NonSemanticExtInst Opcode,
2139 Records[Anchor].push_back({&
MI, Opcode, LocationReg});
2142void SPIRVNonSemanticDebugHandler::emitAnalyzedRecords(
2144 auto It = Records.find(Anchor);
2145 if (It == Records.end())
2147 for (
const DebugRecord &R : It->second)
2148 emitDebugBinding(
R.Opcode,
R.MI,
R.LocationReg);
2151bool SPIRVNonSemanticDebugHandler::emitDebugScopeForInstruction(
2153 assert(DebugFunctionDefinitionEmitted &&
2154 "DebugFunctionDefinition must be emitted");
2155 assert(CurrentMAI &&
"CurrentMAI must be set");
2160 if (LastScopeMI &&
MI->getParent() != LastScopeMI->getParent())
2161 LastScopeMI =
nullptr;
2163 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
2164 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
2167 const DILocation *CurDL =
MI->getDebugLoc().get();
2172 emitExtInst(SPIRV::NonSemanticExtInst::DebugNoScope, VoidTypeReg,
2173 ExtInstSetReg, {}, MAI);
2174 LastScopeMI =
nullptr;
2179 const DIScope *CurScope = CurDL->getScope();
2180 const DILocation *CurInlinedAt = CurDL->getInlinedAt();
2183 const DILocation *LastDL = LastScopeMI->getDebugLoc().get();
2184 if (LastDL->getScope() == CurScope &&
2185 LastDL->getInlinedAt() == CurInlinedAt)
2189 EmitResult<MCRegister> CurScopeRes = resolveScope(CurScope);
2196 MCRegister InlinedReg = DebugInlinedAtRegs.lookup(CurInlinedAt);
2199 Ops.push_back(InlinedReg);
2203 emitExtInst(SPIRV::NonSemanticExtInst::DebugScope, VoidTypeReg, ExtInstSetReg,
2210void SPIRVNonSemanticDebugHandler::emitDebugLineForInstruction(
2212 assert(DebugFunctionDefinitionEmitted &&
2213 "DebugFunctionDefinition must be emitted");
2214 assert(CurrentMAI &&
"CurrentMAI must be set");
2219 if (LastLineMI &&
MI->getParent() != LastLineMI->getParent())
2220 LastLineMI =
nullptr;
2222 SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
2223 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
2226 const DILocation *
DL =
MI->getDebugLoc().get();
2231 emitExtInst(SPIRV::NonSemanticExtInst::DebugNoLine, VoidTypeReg,
2232 ExtInstSetReg, {}, MAI);
2233 LastLineMI =
nullptr;
2243 MCRegister FileStrReg = getCachedScopePathOpStringReg(
2244 DL->getScope(),
true);
2245 unsigned Line =
DL->getLine();
2246 unsigned Col =
DL->getColumn();
2248 unsigned I32TypeId = CachedOpTypeInt32Reg.id();
2249 MCRegister SrcReg = DebugSourceRegByFileStr.lookup(FileStrReg.
id());
2250 MCRegister LineReg = ScalarConstantCache.lookup({I32TypeId,
Line});
2251 MCRegister ColStartReg = ScalarConstantCache.lookup({I32TypeId, Col});
2252 MCRegister ColEndReg = ScalarConstantCache.lookup({I32TypeId, Col + 1});
2264 if (LastLineMI &&
MI->getDebugLoc() == LastLineMI->getDebugLoc())
2268 emitExtInst(SPIRV::NonSemanticExtInst::DebugLine, VoidTypeReg, ExtInstSetReg,
2269 {SrcReg, LineReg, LineReg, ColStartReg, ColEndReg}, MAI);
2278 if (!
MI || !GlobalNSDIEnabled || !CurrentMF)
2281 if (DebugFunctionDefinitionEmitted ||
MI != LastFunctionOpVariable)
2287 assert(CurrentMAI &&
"CurrentMAI must be set");
2288 tryEmitDebugFunctionDefinition(*CurrentMAI);
2293 if (!GlobalNSDIEnabled || DebugFunctionDefinitionEmitted || !CurrentMF)
2296 assert(CurrentMF == &MF &&
2297 "notification does not match the current MachineFunction");
2299 if (LastFunctionOpVariable)
2305 tryEmitDebugFunctionDefinition(*CurrentMAI);
2308void SPIRVNonSemanticDebugHandler::collectDebugExpressions(
2312 Out.insert(
MI->getDebugExpression());
2317 if (GlobalDIEmitted)
2320 GlobalDIEmitted =
true;
2322 if (CompileUnits.empty()) {
2323 GlobalNSDIEnabled =
false;
2329 if (!ExtInstSetReg.
isValid()) {
2330 GlobalNSDIEnabled =
false;
2335 assert(NonSemanticOpStringsSectionEmitted &&
2336 "emitNonSemanticDebugStrings() must run before "
2337 "emitNonSemanticGlobalDebugInfo()");
2342 MCRegister VoidTypeReg = getOrEmitOpTypeVoidReg(MAI);
2343 MCRegister I32TypeReg = getOrEmitOpTypeInt32Reg(MAI);
2345 CachedDebugInfoNoneReg = emitExtInst(SPIRV::NonSemanticExtInst::DebugInfoNone,
2346 VoidTypeReg, ExtInstSetReg, {}, MAI);
2358 MCRegister DebugInfoVersionReg = emitOpConstantI32(100, I32TypeReg, MAI);
2360 emitOpConstantI32(
static_cast<uint32_t>(DwarfVersion), I32TypeReg, MAI);
2365 map_to_vector(CompileUnits, [&](
const CompileUnitInfo &Info) {
2366 return emitOpConstantI32(Info.SpirvSourceLanguage, I32TypeReg, MAI);
2370 for (
auto [Info, SrcLangReg] :
llvm::zip(CompileUnits, SrcLangRegs)) {
2371 MCRegister FileStrReg = ScopeToPathOpStringReg.lookup(Info.TheCU);
2373 "CU path OpString must be emitted in emitNonSemanticDebugStrings");
2374 MCRegister DebugSourceReg = getOrEmitDebugSourceForFileStrReg(
2375 FileStrReg, VoidTypeReg, ExtInstSetReg, MAI);
2377 SPIRV::NonSemanticExtInst::DebugCompilationUnit, VoidTypeReg,
2379 {DebugInfoVersionReg, DwarfVersionReg, DebugSourceReg, SrcLangReg},
2382 DebugScopeRegs[Info.TheCU] = CUDbgReg;
2387 getOrCreateDebugScope(S);
2392 if (
auto LVReg = emitDebugLocalVariable(LV, VoidTypeReg, I32TypeReg,
2393 ExtInstSetReg, MAI))
2394 DebugLocalVariableRegs[LV] = *LVReg;
2401 collectDebugExpressions(MAI, Expressions);
2403 if (
auto ExprReg = emitDebugExpression(Expr, VoidTypeReg, I32TypeReg,
2404 ExtInstSetReg, MAI))
2405 DebugExpressionRegs[Expr] = *ExprReg;
2408 for (
const auto &[GV, Info] : GlobalVariableDebugInfoMap)
2409 emitDebugGlobalVariable(GV, Info, VoidTypeReg, I32TypeReg, ExtInstSetReg,
2415 getOrEmitDebugInlinedAt(IA, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI);
2420 std::optional<std::pair<const DIBasicType *, uint64_t>> Const =
2424 if (!DebugLocalVariableRegs.contains(
MI->getDebugVariable()) ||
2425 !DebugExpressionRegs.contains(
MI->getDebugExpression()))
2427 auto [It, Inserted] = ConstantValueRegs.try_emplace(*Const,
MCRegister());
2429 It->second = findOrEmitScalarConstant(Const->first, Const->second, MAI);
2430 if (!It->second.isValid())
2431 ConstantValueRegs.erase(It);
2435 emitOpConstantI32(
DL->getLine(), I32TypeReg, MAI);
2436 emitOpConstantI32(
DL->getColumn(), I32TypeReg, MAI);
2437 emitOpConstantI32(
DL->getColumn() + 1, I32TypeReg, MAI);
2439 getCachedScopePathOpStringReg(
DL->getScope(),
2441 getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg, ExtInstSetReg,
2445 GlobalNSDIEnabled =
true;
2449SPIRVNonSemanticDebugHandler::getDebugFullPath(
const DIScope *Scope)
const {
2459 Out.assign(Dir.
begin(), Dir.
end());
2465MCRegister SPIRVNonSemanticDebugHandler::getOrEmitDebugSourceForFileStrReg(
2468 const unsigned Key = FileStrReg.
id();
2469 auto It = DebugSourceRegByFileStr.find(
Key);
2470 if (It != DebugSourceRegByFileStr.end())
2473 MCRegister
DS = emitExtInst(SPIRV::NonSemanticExtInst::DebugSource,
2474 VoidTypeReg, ExtInstSetReg, {FileStrReg}, MAI);
2475 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 NVPTX::Scope resolveScope(NVPTX::Scope S, const NVPTXSubtarget *T)
static constexpr StringLiteral Filename
static cl::opt< bool > SPIRVDebugLexicalBlockDiscriminatorScope("spirv-debug-lexical-block-discriminator-scope", cl::desc("Use a DebugLexicalBlockDiscriminator as a DebugScope"), cl::init(false))
static const MachineInstr * findAdjacentEmittedInstruction(const MachineInstr *MI, SPIRV::ModuleAnalysisInfo &MAI, bool Forward)
static std::optional< SmallVector< uint32_t, 3 > > mapExprOperand(const DIExpression::ExprOperand &Op)
static bool scalarTypeNeedsCapability(const DIBasicType *BT)
static bool isBooleanType(const DIBasicType *BT)
static bool constantHasValue(const MachineInstr &MI, uint64_t Value, bool IsWide)
static void collectLexicalBlockChain(const DIScope *S, SetVector< const DIScope * > &Out)
static bool isMergeInstruction(unsigned Opcode)
static std::optional< std::pair< const DIBasicType *, uint64_t > > getConstantDbgValueBits(const MachineInstr &MI)
static MCRegister getResultId(const MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI)
static bool isEmitted(const MachineInstr *MI, SPIRV::ModuleAnalysisInfo &MAI)
static std::optional< Register > getDebugValueReg(const MachineInstr &MI)
static bool isDebugLocTarget(const MachineInstr *MI, SPIRV::ModuleAnalysisInfo &MAI)
static uint64_t constantBits(uint64_t Value, const DIBasicType *BT)
static std::optional< Register > getDebugDeclareStorageReg(const MachineInstr &MI)
static std::optional< NonSemanticDebugOp > mapDwarfOpToNonSemanticOp(uint64_t DwarfOp)
static const DIBasicType * stripToScalarType(const DIType *Ty)
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.
This file defines the SmallPtrSet class.
Class for arbitrary precision integers.
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.
bool isValid() const
Return true if the attribute is any kind of attribute.
Basic type, like 'int' or 'float'.
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.
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 setFlags(unsigned F)
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
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
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.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
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.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
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.
initializer< Ty > init(const Ty &Val)
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
NodeAddr< DefNode * > Def
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
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.
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)
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
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)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
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.
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)
SmallVector< const MachineInstr * > DebugValueMIs
MCRegister getNextIDRegister()
void addExtension(Extension::Extension ToAdd)