https://github.com/jmmartinez created https://github.com/llvm/llvm-project/pull/219927
None From f4e9d1d50c8acc7b18a5d0dac4d08790e126ab7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <[email protected]> Date: Mon, 31 Aug 2026 11:34:00 +0200 Subject: [PATCH] [NFC][SPIRV] Converge different DIScope to MCRegister maps into a single one --- .../SPIRV/SPIRVNonSemanticDebugHandler.cpp | 87 ++++++++----------- .../SPIRV/SPIRVNonSemanticDebugHandler.h | 47 ++++------ 2 files changed, 54 insertions(+), 80 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp index 26c071fe2e18d..e53f8cc9061f5 100644 --- a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp @@ -311,13 +311,9 @@ void SPIRVNonSemanticDebugHandler::beginModule(Module *M) { UniqueDebugLocations.clear(); GlobalVariableDebugInfoMap.clear(); LexicalBlocks.clear(); - DebugFunctionDeclarationRegs.clear(); - DebugFunctionRegs.clear(); - DebugLexicalBlockRegs.clear(); + DebugScopeRegs.clear(); ScopeToPathOpStringReg.clear(); - CUToCompilationUnitDbgReg.clear(); DebugSourceRegByFileStr.clear(); - DebugTypeRegs.clear(); OpStringContentCache.clear(); I32ConstantCache.clear(); DebugTypeFunctionCache.clear(); @@ -602,8 +598,8 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypePointer( I32TypeReg, MAI); if (const DIType *BaseTy = PT->getBaseType()) { - auto BaseIt = DebugTypeRegs.find(BaseTy); - if (BaseIt != DebugTypeRegs.end()) + auto BaseIt = DebugScopeRegs.find(BaseTy); + if (BaseIt != DebugScopeRegs.end()) return emitExtInst( SPIRV::NonSemanticExtInst::DebugTypePointer, VoidTypeReg, ExtInstSetReg, @@ -653,23 +649,18 @@ SPIRVNonSemanticDebugHandler::emitDebugTypeFunctionForSubroutineType( // Match SPIRV-LLVM-Translator's selection logic for the Parent operand. std::optional<MCRegister> SPIRVNonSemanticDebugHandler::resolveScope( const DIScope *Scope, const DICompileUnit *FallbackCU) const { - if (const auto *Ty = dyn_cast_or_null<DIType>(Scope)) - return lookupOptReg(DebugTypeRegs, Ty); - if (isa_and_nonnull<DILexicalBlock, DINamespace>(Scope)) - return lookupOptReg(DebugLexicalBlockRegs, Scope); - - if (const auto *SP = dyn_cast_or_null<DISubprogram>(Scope)) - return lookupOptReg(DebugFunctionRegs, SP); + if (isa_and_nonnull<DIType, DILexicalBlock, DINamespace, DISubprogram>(Scope)) + return lookupOptReg(DebugScopeRegs, Scope); // For a file, compile-unit, or absent scope, fall back to a compile unit. if (FallbackCU) - return lookupOptReg(CUToCompilationUnitDbgReg, FallbackCU); + return lookupOptReg(DebugScopeRegs, FallbackCU); if (CompileUnits.empty()) return std::nullopt; - return lookupOptReg(CUToCompilationUnitDbgReg, CompileUnits[0].TheCU); + return lookupOptReg(DebugScopeRegs, CompileUnits[0].TheCU); } std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugLexicalBlock( @@ -717,7 +708,7 @@ SPIRVNonSemanticDebugHandler::emitDebugFunctionDeclaration( // The IR verifier already enforces that this cannot be null. const DISubroutineType *ST = SP->getType(); - auto FnTyRegOpt = lookupOptReg(DebugTypeRegs, ST); + auto FnTyRegOpt = lookupOptReg(DebugScopeRegs, ST); if (!FnTyRegOpt) return std::nullopt; MCRegister FnTyReg = *FnTyRegOpt; @@ -741,7 +732,7 @@ SPIRVNonSemanticDebugHandler::emitDebugFunctionDeclaration( uint32_t FlagsVal = transDebugFlags(SP); // TODO: When composite scopes are DebugFunctionDeclaration parents (available - // in DebugTypeRegs), sync declaration Flags with SPIRV-LLVM-Translator. + // in DebugScopeRegs), sync declaration Flags with SPIRV-LLVM-Translator. FlagsVal &= ~NSDIFlagIsDefinition; MCRegister FlagsReg = emitOpConstantI32(FlagsVal, I32TypeReg, MAI); @@ -759,7 +750,7 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugFunction( assert(SP->isDefinition() && "SP must be a definition in emitDebugFunction"); const DISubroutineType *ST = SP->getType(); - auto FnTyRegOpt = lookupOptReg(DebugTypeRegs, ST); + auto FnTyRegOpt = lookupOptReg(DebugScopeRegs, ST); if (!FnTyRegOpt) return std::nullopt; @@ -787,7 +778,7 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugFunction( LinkageReg, FlagsReg, ScopeLineReg}; if (const DISubprogram *Decl = SP->getDeclaration()) { - if (auto DeclRegOpt = lookupOptReg(DebugFunctionDeclarationRegs, Decl)) + if (auto DeclRegOpt = lookupOptReg(DebugScopeRegs, Decl)) Ops.push_back(*DeclRegOpt); } @@ -804,7 +795,7 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::mapDISignatureTypeToReg( "DebugInfoNone must be emitted before DISubroutineType operands"); return CachedDebugInfoNoneReg; } - return lookupOptReg(DebugTypeRegs, Ty); + return lookupOptReg(DebugScopeRegs, Ty); } // Unimplemented no-op; see emitDebugExpression declaration. @@ -832,7 +823,7 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugGlobalVariable( // verifier). MCRegister TyReg = CachedDebugInfoNoneReg; if (const DIType *Ty = GV->getType()) { - auto TyRegOpt = lookupOptReg(DebugTypeRegs, Ty); + auto TyRegOpt = lookupOptReg(DebugScopeRegs, Ty); if (!TyRegOpt) return std::nullopt; TyReg = *TyRegOpt; @@ -840,7 +831,7 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugGlobalVariable( std::optional<MCRegister> StaticMemberRegOpt; if (const DIDerivedType *SM = GV->getStaticDataMemberDeclaration()) { - StaticMemberRegOpt = lookupOptReg(DebugTypeRegs, SM); + StaticMemberRegOpt = lookupOptReg(DebugScopeRegs, SM); if (!StaticMemberRegOpt) return std::nullopt; } @@ -891,8 +882,8 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeVector( const auto *BaseTy = dyn_cast_or_null<DIBasicType>(VT->getBaseType()); if (!BaseTy) return std::nullopt; - auto BTIt = DebugTypeRegs.find(BaseTy); - if (BTIt == DebugTypeRegs.end()) + auto BTIt = DebugScopeRegs.find(BaseTy); + if (BTIt == DebugScopeRegs.end()) return std::nullopt; // DebugTypeVector models only 1D vectors (multi-subrange types cannot be @@ -916,9 +907,9 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeVector( std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeArray( const DICompositeType *AT, MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI) { - // The element (base) type must already be in DebugTypeRegs. Unlike + // The element (base) type must already be in DebugScopeRegs. Unlike // DebugTypeVector, the element may be any debug type, not only a basic type. - auto BaseRegOpt = lookupOptReg(DebugTypeRegs, AT->getBaseType()); + auto BaseRegOpt = lookupOptReg(DebugScopeRegs, AT->getBaseType()); if (!BaseRegOpt) return std::nullopt; @@ -956,8 +947,8 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeArray( std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeMember( const DIDerivedType *M, MCRegister VoidTypeReg, MCRegister I32TypeReg, MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI) { - // The member type must already be in DebugTypeRegs. - auto TyRegOpt = lookupOptReg(DebugTypeRegs, M->getBaseType()); + // The member type must already be in DebugScopeRegs. + auto TyRegOpt = lookupOptReg(DebugScopeRegs, M->getBaseType()); if (!TyRegOpt) return std::nullopt; @@ -1033,8 +1024,8 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeComposite( std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypedef( const DIDerivedType *TD, MCRegister VoidTypeReg, MCRegister I32TypeReg, MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI) { - // The underlying (base) type must already be in DebugTypeRegs. - auto BaseRegOpt = lookupOptReg(DebugTypeRegs, TD->getBaseType()); + // The underlying (base) type must already be in DebugScopeRegs. + auto BaseRegOpt = lookupOptReg(DebugScopeRegs, TD->getBaseType()); if (!BaseRegOpt) return std::nullopt; @@ -1188,8 +1179,8 @@ void SPIRVNonSemanticDebugHandler::tryEmitDebugFunctionDefinition( if (!SP || !SP->isDefinition()) return; - auto DFIt = DebugFunctionRegs.find(SP); - if (DFIt == DebugFunctionRegs.end()) + auto DFIt = DebugScopeRegs.find(SP); + if (DFIt == DebugScopeRegs.end()) return; MCRegister OpFunctionReg = MAI.getGlobalObjReg(&F); @@ -1435,15 +1426,13 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( {DebugInfoVersionReg, DwarfVersionReg, DebugSourceReg, SrcLangReg}, MAI); if (Info.TheCU) - CUToCompilationUnitDbgReg[Info.TheCU] = CUDbgReg; + DebugScopeRegs[Info.TheCU] = CUDbgReg; } // Zero constant used as the Flags operand in DebugTypeBasic and // DebugTypePointer. Cached with other i32 constants. MCRegister I32ZeroReg = emitOpConstantI32(0, I32TypeReg, MAI); - DebugTypeRegs.clear(); - for (const DIBasicType *BT : BasicTypes) { MCRegister NameReg = getCachedOpStringReg(BT->getName()); MCRegister SizeReg = emitOpConstantI32( @@ -1480,19 +1469,19 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( MCRegister BTReg = emitExtInst( SPIRV::NonSemanticExtInst::DebugTypeBasic, VoidTypeReg, ExtInstSetReg, {NameReg, SizeReg, EncodingReg, I32ZeroReg}, MAI); - DebugTypeRegs[BT] = BTReg; + DebugScopeRegs[BT] = BTReg; } // Emit DebugTypeVector for each collected vector type. for (const DICompositeType *VT : VectorTypes) { if (auto VecReg = emitDebugTypeVector(VT, ExtInstSetReg, MAI)) - DebugTypeRegs[VT] = *VecReg; + DebugScopeRegs[VT] = *VecReg; } // Emit DebugTypePointer for each referenced pointer type. for (const DIDerivedType *PT : PointerTypes) { if (auto PtrReg = emitDebugTypePointer(PT, ExtInstSetReg, MAI)) - DebugTypeRegs[PT] = *PtrReg; + DebugScopeRegs[PT] = *PtrReg; } // Emit DebugTypeArray for each collected array type. Placed after the basic, @@ -1500,14 +1489,14 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( // element id. An array whose element type was not emitted is skipped. for (const DICompositeType *AT : ArrayTypes) { if (auto ArrReg = emitDebugTypeArray(AT, ExtInstSetReg, MAI)) - DebugTypeRegs[AT] = *ArrReg; + DebugScopeRegs[AT] = *ArrReg; } // Emit DebugTypeFunction for each distinct DISubroutineType. for (const DISubroutineType *ST : SubroutineTypes) { if (auto FnTyReg = emitDebugTypeFunctionForSubroutineType(ST, ExtInstSetReg, MAI)) - DebugTypeRegs[ST] = *FnTyReg; + DebugScopeRegs[ST] = *FnTyReg; } // Emit DebugLexicalBlock for each collected DINamespace, in parent-before- @@ -1516,12 +1505,12 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( // their Parent operand can reference an already-emitted DebugLexicalBlock. // DINamespace never chains through a DISubprogram (DINamespace::getScope() // returns DIScope, not DILocalScope), so this never depends on - // DebugFunctionRegs. + // DebugScopeRegs. for (const DIScope *S : make_filter_range(LexicalBlocks, IsaPred<DINamespace>)) { if (auto LBReg = emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI)) - DebugLexicalBlockRegs[S] = *LBReg; + DebugScopeRegs[S] = *LBReg; } // Emit DebugTypedef for each typedef. Placed after the other type loops so a @@ -1532,20 +1521,20 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( for (const DIDerivedType *TD : TypedefTypes) { if (auto TDReg = emitDebugTypedef(TD, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI)) - DebugTypeRegs[TD] = *TDReg; + DebugScopeRegs[TD] = *TDReg; } // Emit DebugFunctionDeclaration for DISubprogram declarations. for (const DISubprogram *SP : SubprogramDeclarations) { if (auto DeclReg = emitDebugFunctionDeclaration(SP, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI)) - DebugFunctionDeclarationRegs[SP] = *DeclReg; + DebugScopeRegs[SP] = *DeclReg; } // Emit DebugTypeMember and DebugTypeComposite for each struct, class, or // union. Each member is emitted before the composite that lists it, so the // Members operand references already-defined ids. A member whose type is not - // in DebugTypeRegs is skipped. + // in DebugScopeRegs is skipped. for (const DICompositeType *CT : CompositeTypes) { SmallVector<MCRegister> MemberRegs; for (const DINode *Element : CT->getElements()) { @@ -1558,14 +1547,14 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( } if (auto CompReg = emitDebugTypeComposite(CT, MemberRegs, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI)) - DebugTypeRegs[CT] = *CompReg; + DebugScopeRegs[CT] = *CompReg; } // Emit DebugFunction for DISubprogram definitions. for (const DISubprogram *SP : SubprogramDefinitions) { if (auto FnReg = emitDebugFunction(SP, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI)) - DebugFunctionRegs[SP] = *FnReg; + DebugScopeRegs[SP] = *FnReg; } // Emit DebugLexicalBlock for each collected DILexicalBlock, in parent- @@ -1576,7 +1565,7 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( make_filter_range(LexicalBlocks, IsaPred<DILexicalBlock>)) { if (auto LBReg = emitDebugLexicalBlock(S, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI)) - DebugLexicalBlockRegs[S] = *LBReg; + DebugScopeRegs[S] = *LBReg; } // Emit DebugGlobalVariable for each collected DIGlobalVariable. diff --git a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h index 04faf612df920..ecb23450517c7 100644 --- a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h +++ b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h @@ -82,9 +82,8 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { // DebugTypedef emission. SmallVector<const DIDerivedType *> TypedefTypes; - // Filled in emitNonSemanticGlobalDebugInfo(): DI types to their result - // registers. - DenseMap<const DIType *, MCRegister> DebugTypeRegs; + // NonSemantic debug instruction result id per emitted scope. + DenseMap<const DIScope *, MCRegister> DebugScopeRegs; // DISubprogram nodes that are declarations only (!isDefinition()), collected // in beginModule() for DebugFunctionDeclaration emission. @@ -109,26 +108,12 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { // order, collected in beginModule() for DebugLexicalBlock emission. SetVector<const DIScope *> LexicalBlocks; - // DebugFunctionDeclaration result id per emitted declaration DISubprogram - // (only entries where emission succeeded). - DenseMap<const DISubprogram *, MCRegister> DebugFunctionDeclarationRegs; - - // DebugFunction result id per emitted definition DISubprogram (only entries - // where emission succeeded). - DenseMap<const DISubprogram *, MCRegister> DebugFunctionRegs; - - // DebugLexicalBlock result id per emitted DILexicalBlock/DINamespace. - DenseMap<const DIScope *, MCRegister> DebugLexicalBlockRegs; - // Path \c OpString result id per \c DIScope (CU, \c DIFile, declaration // \c DISubprogram, …). Filled during \c emitNonSemanticDebugStrings() using // \c getDebugFullPath + \c emitOpStringIfNew; section 10 uses it for // \c DebugSource without recomputing path text. DenseMap<const DIScope *, MCRegister> ScopeToPathOpStringReg; - // DebugCompilationUnit result id per DICompileUnit (for Parent operands). - DenseMap<const DICompileUnit *, MCRegister> CUToCompilationUnitDbgReg; - // DebugSource result id keyed by path \c OpString id (\c MCRegister::id()), // deduplicating when the same file string is reused. DenseMap<unsigned, MCRegister> DebugSourceRegByFileStr; @@ -310,9 +295,9 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// \returns The result id register on success. Returns \c std::nullopt and /// emits nothing if \p PT has no DWARF address space (needed to pick the /// SPIR-V storage class), or if \p PT has a non-null base DI type that is not - /// yet in \c DebugTypeRegs (the pointee was not emitted as a debug type). + /// yet in \c DebugScopeRegs (the pointee was not emitted as a debug type). /// - /// Base Type operand: the register from \c DebugTypeRegs for \p PT's base + /// Base Type operand: the register from \c DebugScopeRegs for \p PT's base /// type when it is set and mapped; \c DebugInfoNone when there is no base /// type (e.g. \c void * in IR), consistent with SPIRV-LLVM-Translator. std::optional<MCRegister> @@ -332,7 +317,7 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// \returns The result id register on success. Returns \c std::nullopt and /// emits nothing if \p SP is null, is a definition, has no \c /// DISubroutineType type, the signature type was not emitted in \c - /// DebugTypeRegs, no path + /// DebugScopeRegs, no path /// \c OpString was recorded for \p SP in section 7, or /// \c resolveScope returns no id for the \c Parent operand. std::optional<MCRegister> @@ -363,8 +348,8 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// /// \returns The result id register on success. Returns \c std::nullopt and /// emits nothing if a non-null \p GV type was not emitted in \c - /// DebugTypeRegs, or \p GV has a static data member declaration that was not - /// emitted in \c DebugTypeRegs. + /// DebugScopeRegs, or \p GV has a static data member declaration that was not + /// emitted in \c DebugScopeRegs. std::optional<MCRegister> emitDebugGlobalVariable( const DIGlobalVariable *GV, const GlobalVariableDebugInfo &Info, MCRegister VoidTypeReg, MCRegister I32TypeReg, MCRegister ExtInstSetReg, @@ -398,7 +383,7 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// /// \returns The result id register on success. Returns \c std::nullopt and /// emits nothing if \p AT's element type has not been emitted into - /// \c DebugTypeRegs. + /// \c DebugScopeRegs. std::optional<MCRegister> emitDebugTypeArray(const DICompositeType *AT, MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI); @@ -409,7 +394,7 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// enclosing \c DebugTypeComposite references its members, not the reverse. /// /// \returns The result id register on success. Returns \c std::nullopt and - /// emits nothing if \p M's type has not been emitted into \c DebugTypeRegs. + /// emits nothing if \p M's type has not been emitted into \c DebugScopeRegs. std::optional<MCRegister> emitDebugTypeMember(const DIDerivedType *M, MCRegister VoidTypeReg, MCRegister I32TypeReg, @@ -435,7 +420,7 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// /// \returns The result id register on success. Returns \c std::nullopt and /// emits nothing if \p TD's base type has not been emitted into \c - /// DebugTypeRegs. + /// DebugScopeRegs. std::optional<MCRegister> emitDebugTypedef(const DIDerivedType *TD, MCRegister VoidTypeReg, MCRegister I32TypeReg, @@ -444,8 +429,8 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// Map a \c DISubroutineType::getTypeArray() element to an operand register /// for - /// \c DebugTypeFunction. Non-null \p Ty resolves via \c DebugTypeRegs; if the - /// type was never emitted, returns \c std::nullopt. + /// \c DebugTypeFunction. Non-null \p Ty resolves via \c DebugScopeRegs; if + /// the type was never emitted, returns \c std::nullopt. /// /// LLVM encodes a void return as a null first element (and may use null in /// later slots). NonSemantic \c DebugTypeFunction @@ -478,10 +463,10 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { /// Map \p Scope to the NonSemantic debug id used as a \c Parent operand. /// - /// Checks \c DebugTypeRegs, \c DebugLexicalBlockRegs, and \c - /// DebugFunctionRegs in order. When \p Scope is null, a \c DIFile, or - /// another scope without a dedicated debug instruction, falls back to \p - /// FallbackCU or the first module \c DebugCompilationUnit. + /// Checks \c DebugScopeRegs in order by scope kind. When \p Scope is null, a + /// \c DIFile, or another scope without a dedicated debug instruction, falls + /// back to \p FallbackCU or the first module \c DebugCompilationUnit + /// recorded in \c DebugScopeRegs. /// /// \returns \c std::nullopt when \p Scope names an emitted scope that has /// not been recorded yet, or when no fallback compile unit is available. _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
