diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index ee5e3d68a5ffa..24deb1e56c702 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -42,6 +42,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -192,8 +193,13 @@ void CGDebugInfo::addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, } } -void CGDebugInfo::completeFunction() { - // Reset the atom group number tracker as the numbers are function-local. +void CGDebugInfo::completeFunction(llvm::Function *Fn) { + // Set DISubprogram::NextAtomGroup. + if (CGM.getCodeGenOpts().DebugKeyInstructions && + Fn->getSubprogram()->isDefinition()) + Fn->getSubprogram()->updateDILocationAtomGroupWaterline( + KeyInstructionsInfo.HighestEmittedAtom + 1); + KeyInstructionsInfo.NextAtom = 1; KeyInstructionsInfo.HighestEmittedAtom = 0; KeyInstructionsInfo.CurrentAtom = 0; @@ -1904,7 +1910,8 @@ CGDebugInfo::createInlinedSubprogram(StringRef FuncName, /*ScopeLine=*/0, /*Flags=*/llvm::DINode::FlagArtificial, /*SPFlags=*/llvm::DISubprogram::SPFlagDefinition, - /*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr); + /*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr, + nullptr, StringRef(), CGM.getCodeGenOpts().DebugKeyInstructions); } return SP; @@ -2284,7 +2291,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( llvm::DISubprogram *SP = DBuilder.createMethod( RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine, MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags, - TParamsArray.get()); + TParamsArray.get(), /*ThrownTypes*/ nullptr, + CGM.getCodeGenOpts().DebugKeyInstructions); SPCache[Method->getCanonicalDecl()].reset(SP); @@ -4350,7 +4358,9 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD, return DBuilder.createFunction( DContext, Name, LinkageName, Unit, Line, getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags, - TParamsArray.get(), getFunctionDeclaration(FD)); + TParamsArray.get(), getFunctionDeclaration(FD), /*ThrownTypes*/ nullptr, + /*Annotations*/ nullptr, /*TargetFuncName*/ "", + CGM.getCodeGenOpts().DebugKeyInstructions); } llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl( @@ -4686,8 +4696,9 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc, llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine, FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr, - Annotations); + Annotations, "", CGM.getCodeGenOpts().DebugKeyInstructions); Fn->setSubprogram(SP); + // We might get here with a VarDecl in the case we're generating // code for the initialization of globals. Do not record these decls // as they will overwrite the actual VarDecl Decl in the cache. @@ -4746,9 +4757,12 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D); llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit); + // Key Instructions: Do not set UseKeyInstructions on declarations. + assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition); llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags, - SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations); + SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations, + /*TargetFunctionName*/ "", /*UseKeyInstructions*/ false); // Preserve btf_decl_tag attributes for parameters of extern functions // for BPF target. The parameters created in this loop are attached as diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 16759f25123cd..51101991eff02 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -657,8 +657,8 @@ class CGDebugInfo { llvm::DILocation *CreateSyntheticInlineAt(llvm::DebugLoc Location, StringRef FuncName); - /// Reset internal state. - void completeFunction(); + /// Finalize some function debug info and reset per-function internal state. + void completeFunction(llvm::Function *Fn); /// Add \p KeyInstruction and an optional \p Backup instruction to the /// current atom group, created using ApplyAtomGroup. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 56562002e7194..c8ca75073a1c5 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1512,9 +1512,9 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, DebugInfo = nullptr; } // Finalize function debug info on exit. - auto Cleanup = llvm::make_scope_exit([this] { + auto Cleanup = llvm::make_scope_exit([this, Fn] { if (CGDebugInfo *DI = getDebugInfo()) - DI->completeFunction(); + DI->completeFunction(Fn); }); // The function might not have a body if we're generating thunks for a diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2d676aa0b9c8e..7446605127cf8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4609,7 +4609,7 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, } if (Args.hasFlag(options::OPT_gkey_instructions, - options::OPT_gno_key_instructions, false)) { + options::OPT_gno_key_instructions, true)) { CmdArgs.push_back("-gkey-instructions"); CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-dwarf-use-key-instructions"); diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 206f009b45f59..2cf98e4334a5c 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -573,7 +573,7 @@ set(LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING "DISABLED" CACHE STRING set_property(CACHE LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING PROPERTY STRINGS DISABLED COVERAGE) option(LLVM_EXPERIMENTAL_KEY_INSTRUCTIONS - "Add additional fields to DILocations to support Key Instructions" OFF) + "Add additional fields to DILocations to support Key Instructions" ON) set(WINDOWS_PREFER_FORWARD_SLASH_DEFAULT OFF) if (MINGW) diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index ebfe41dd59afb..d162371553b0d 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -898,6 +898,7 @@ namespace llvm { /// \param Annotations Attribute Annotations. /// \param TargetFuncName The name of the target function if this is /// a trampoline. + /// \param UseKeyInstructions Enable Key Instructions debug info. LLVM_ABI DISubprogram *createFunction( DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, @@ -905,7 +906,8 @@ namespace llvm { DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, DITemplateParameterArray TParams = nullptr, DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr, - DINodeArray Annotations = nullptr, StringRef TargetFuncName = ""); + DINodeArray Annotations = nullptr, StringRef TargetFuncName = "", + bool UseKeyInstructions = false); /// Identical to createFunction, /// except that the resulting DbgNode is meant to be RAUWed. @@ -936,15 +938,15 @@ namespace llvm { /// \param SPFlags Additional flags specific to subprograms. /// \param TParams Function template parameters. /// \param ThrownTypes Exception types this function may throw. - LLVM_ABI DISubprogram * - createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned LineNo, DISubroutineType *Ty, - unsigned VTableIndex = 0, int ThisAdjustment = 0, - DIType *VTableHolder = nullptr, - DINode::DIFlags Flags = DINode::FlagZero, - DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, - DITemplateParameterArray TParams = nullptr, - DITypeArray ThrownTypes = nullptr); + /// \param UseKeyInstructions Enable Key Instructions debug info. + LLVM_ABI DISubprogram *createMethod( + DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, + unsigned LineNo, DISubroutineType *Ty, unsigned VTableIndex = 0, + int ThisAdjustment = 0, DIType *VTableHolder = nullptr, + DINode::DIFlags Flags = DINode::FlagZero, + DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, + DITemplateParameterArray TParams = nullptr, + DITypeArray ThrownTypes = nullptr, bool UseKeyInstructions = false); /// Create common block entry for a Fortran common block. /// \param Scope Scope of this common block. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 02f0a9f677db3..25dacd6b8fd00 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1976,6 +1976,21 @@ class DISubprogram : public DILocalScope { /// negative. int ThisAdjustment; + /// Key Instructions: The next available atom group number for this function. + /// The front end is responsible for assigning source atom numbers, but + /// certain optimisations need to assign new group numbers to a set of + /// instructions. Most often code duplication optimisations like loop unroll. + /// + /// NOTE: This field doesn't contribute to the identity of the DISubprogram; + /// it's not represented in MDNodeKeyImpl. This is intentional. + /// It SHOULD ONLY be written to by distinct DISubprograms. + /// + /// Zero indicates the function doesn't use Key Instructions + /// There may be Key Instruction metadata on its instructions, e.g. from + /// inlined instructions, that's all going to be ignored for this function + /// at DWARF emission time. + uint32_t NextAtomGroup = 0; + public: /// Debug info subprogram flags. enum DISPFlags : uint32_t { @@ -2003,6 +2018,33 @@ class DISubprogram : public DILocalScope { unsigned Virtuality = SPFlagNonvirtual, bool IsMainSubprogram = false); + /// Key Instructions: get the next available atom group number and increment + /// the function-local tracker. + uint32_t incNextDILocationAtomGroup() { + assert(isDistinct() && getKeyInstructionsEnabled()); + // NOTE: This may wrap, which effectively disables Key Instructions for + // this function. As a result, instances that have already been inlined + // will also have Key Instructions disabled for them, since we look back + // to this DISubprogram to check if it's enabled during DWARF emission. + // A quirk of the implementation that only shows up in extreme edge cases. + return NextAtomGroup++; + } + + /// Key Instructions: get the next available atom group number. + uint32_t getNextDILocationAtomGroup() const { + assert(isDistinct() && getKeyInstructionsEnabled()); + return NextAtomGroup; + } + + bool getKeyInstructionsEnabled() const { return NextAtomGroup; } + + /// Key Instructions: update the highest number atom group emitted for any + /// function. + void updateDILocationAtomGroupWaterline(uint32_t NewNextGroup) { + assert(isDistinct() && getKeyInstructionsEnabled()); + NextAtomGroup = std::max(NextAtomGroup, NewNextGroup); + } + private: DIFlags Flags; DISPFlags SPFlags; @@ -2021,15 +2063,17 @@ class DISubprogram : public DILocalScope { DITemplateParameterArray TemplateParams, DISubprogram *Declaration, DINodeArray RetainedNodes, DITypeArray ThrownTypes, DINodeArray Annotations, StringRef TargetFuncName, - StorageType Storage, bool ShouldCreate = true) { + uint32_t KeyInstNextAtomGroup, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams.get(), Declaration, RetainedNodes.get(), ThrownTypes.get(), Annotations.get(), getCanonicalMDString(Context, TargetFuncName), - Storage, ShouldCreate); + KeyInstNextAtomGroup, Storage, ShouldCreate); } + LLVM_ABI static DISubprogram * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, @@ -2037,17 +2081,16 @@ class DISubprogram : public DILocalScope { int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, - MDString *TargetFuncName, StorageType Storage, - bool ShouldCreate = true); + MDString *TargetFuncName, uint32_t KeyInstNextAtomGroup, + StorageType Storage, bool ShouldCreate = true); TempDISubprogram cloneImpl() const { - return getTemporary(getContext(), getScope(), getName(), getLinkageName(), - getFile(), getLine(), getType(), getScopeLine(), - getContainingType(), getVirtualIndex(), - getThisAdjustment(), getFlags(), getSPFlags(), - getUnit(), getTemplateParams(), getDeclaration(), - getRetainedNodes(), getThrownTypes(), getAnnotations(), - getTargetFuncName()); + return getTemporary( + getContext(), getScope(), getName(), getLinkageName(), getFile(), + getLine(), getType(), getScopeLine(), getContainingType(), + getVirtualIndex(), getThisAdjustment(), getFlags(), getSPFlags(), + getUnit(), getTemplateParams(), getDeclaration(), getRetainedNodes(), + getThrownTypes(), getAnnotations(), getTargetFuncName(), NextAtomGroup); } public: @@ -2060,10 +2103,11 @@ class DISubprogram : public DILocalScope { DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr, DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr, - StringRef TargetFuncName = ""), + StringRef TargetFuncName = "", uint32_t UseKeyInstructions = 0), (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) + Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName, + UseKeyInstructions)) DEFINE_MDNODE_GET( DISubprogram, @@ -2073,10 +2117,12 @@ class DISubprogram : public DILocalScope { DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr, - Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr), + Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr, + uint32_t UseKeyInstructions = 0), (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) + Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName, + UseKeyInstructions)) TempDISubprogram clone() const { return cloneImpl(); } @@ -2245,23 +2291,24 @@ class DILocation : public MDNode { friend class LLVMContextImpl; friend class MDNode; #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS - uint64_t AtomGroup : 61; - uint64_t AtomRank : 3; + uint32_t AtomGroup : 29; + uint32_t AtomRank : 3; #endif - DILocation(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned Column, uint64_t AtomGroup, uint8_t AtomRank, - ArrayRef MDs, bool ImplicitCode); + DILocation(LLVMContext &C, StorageType Storage, + DISubprogram *SPForKeyInstructions, unsigned Line, unsigned Column, + uint32_t AtomGroup, uint8_t AtomRank, ArrayRef MDs, + bool ImplicitCode); ~DILocation() { dropAllReferences(); } LLVM_ABI static DILocation * getImpl(LLVMContext &Context, unsigned Line, unsigned Column, Metadata *Scope, - Metadata *InlinedAt, bool ImplicitCode, uint64_t AtomGroup, + Metadata *InlinedAt, bool ImplicitCode, uint32_t AtomGroup, uint8_t AtomRank, StorageType Storage, bool ShouldCreate = true); static DILocation *getImpl(LLVMContext &Context, unsigned Line, unsigned Column, DILocalScope *Scope, DILocation *InlinedAt, bool ImplicitCode, - uint64_t AtomGroup, uint8_t AtomRank, + uint32_t AtomGroup, uint8_t AtomRank, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Line, Column, static_cast(Scope), static_cast(InlinedAt), ImplicitCode, AtomGroup, @@ -2277,7 +2324,7 @@ class DILocation : public MDNode { } public: - uint64_t getAtomGroup() const { + uint32_t getAtomGroup() const { #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS return AtomGroup; #else @@ -2305,13 +2352,13 @@ class DILocation : public MDNode { DEFINE_MDNODE_GET(DILocation, (unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt = nullptr, bool ImplicitCode = false, - uint64_t AtomGroup = 0, uint8_t AtomRank = 0), + uint32_t AtomGroup = 0, uint8_t AtomRank = 0), (Line, Column, Scope, InlinedAt, ImplicitCode, AtomGroup, AtomRank)) DEFINE_MDNODE_GET(DILocation, (unsigned Line, unsigned Column, DILocalScope *Scope, DILocation *InlinedAt = nullptr, bool ImplicitCode = false, - uint64_t AtomGroup = 0, uint8_t AtomRank = 0), + uint32_t AtomGroup = 0, uint8_t AtomRank = 0), (Line, Column, Scope, InlinedAt, ImplicitCode, AtomGroup, AtomRank)) diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h index 852a3a4e2f638..012f97ebb6ba2 100644 --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -341,14 +341,6 @@ class LLVMContext { LLVM_ABI StringRef getDefaultTargetFeatures(); LLVM_ABI void setDefaultTargetFeatures(StringRef Features); - /// Key Instructions: update the highest number atom group emitted for any - /// function. - LLVM_ABI void updateDILocationAtomGroupWaterline(uint64_t G); - - /// Key Instructions: get the next free atom group number and increment - /// the global tracker. - LLVM_ABI uint64_t incNextDILocationAtomGroup(); - private: // Module needs access to the add/removeModule methods. friend class Module; diff --git a/llvm/include/llvm/IR/ValueMap.h b/llvm/include/llvm/IR/ValueMap.h index 1a11718bfcdae..16dfa16646e3c 100644 --- a/llvm/include/llvm/IR/ValueMap.h +++ b/llvm/include/llvm/IR/ValueMap.h @@ -88,7 +88,7 @@ class ValueMap { using MapT = DenseMap>; using MDMapT = DenseMap; /// Map {(InlinedAt, old atom number) -> new atom number}. - using DMAtomT = SmallDenseMap, uint64_t>; + using DMAtomT = SmallDenseMap, uint32_t>; using ExtraData = typename Config::ExtraData; MapT Map; diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h index 6b56230a6e1d4..c5078caa509e6 100644 --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -130,13 +130,14 @@ struct ClonedCodeInfo { /// but is sometimes unnecessary, causing extra work that could be avoided by /// setting the parameter to false. LLVM_ABI BasicBlock * -CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, +CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, DISubprogram *SP, const Twine &NameSuffix = "", Function *F = nullptr, ClonedCodeInfo *CodeInfo = nullptr, bool MapAtoms = true); /// Mark a cloned instruction as a new instance so that its source loc can /// be updated when remapped. -LLVM_ABI void mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap); +LLVM_ABI void mapAtomInstance(DISubprogram *Target, const DebugLoc &DL, + ValueToValueMapTy &VMap); /// Return a copy of the specified function and add it to that /// function's module. Also, any references specified in the VMap are changed diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index b933d240c4d27..d4cd41bbe5cf7 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5823,7 +5823,8 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { OPTIONAL(retainedNodes, MDField, ); \ OPTIONAL(thrownTypes, MDField, ); \ OPTIONAL(annotations, MDField, ); \ - OPTIONAL(targetFuncName, MDStringField, ); + OPTIONAL(targetFuncName, MDStringField, ); \ + OPTIONAL(nextAtomGroup, MDUnsignedField, (0, UINT32_MAX)); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5843,7 +5844,7 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val, thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val, declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val, - targetFuncName.Val)); + targetFuncName.Val, nextAtomGroup.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 31129b7e5cf77..552cb485864a6 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5086,7 +5086,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Line = Record[0], Col = Record[1]; unsigned ScopeID = Record[2], IAID = Record[3]; - bool isImplicitCode = Record.size() == 5 && Record[4]; + bool isImplicitCode = Record.size() >= 5 && Record[4]; + uint32_t AtomGroup = Record.size() == 7 ? Record[5] : 0; + uint8_t AtomRank = Record.size() == 7 ? Record[6] : 0; MDNode *Scope = nullptr, *IA = nullptr; if (ScopeID) { @@ -5101,8 +5103,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (!IA) return error("Invalid record"); } + LastLoc = DILocation::get(Scope->getContext(), Line, Col, Scope, IA, - isImplicitCode); + isImplicitCode, AtomGroup, AtomRank); I->setDebugLoc(LastLoc); I = nullptr; continue; diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 1cd1797c1092d..753de8ca5811c 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1416,7 +1416,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_LOCATION: { - if (Record.size() != 5 && Record.size() != 6) + // 5: inlinedAt, 6: isImplicit, 8: Key Instructions fields. + if (Record.size() != 5 && Record.size() != 6 && Record.size() != 8) return error("Invalid record"); IsDistinct = Record[0]; @@ -1424,10 +1425,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( unsigned Column = Record[2]; Metadata *Scope = getMD(Record[3]); Metadata *InlinedAt = getMDOrNull(Record[4]); - bool ImplicitCode = Record.size() == 6 && Record[5]; + bool ImplicitCode = Record.size() >= 6 && Record[5]; + uint32_t AtomGroup = Record.size() == 8 ? Record[6] : 0; + uint8_t AtomRank = Record.size() == 8 ? Record[7] : 0; MetadataList.assignValue( GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt, - ImplicitCode)), + ImplicitCode, AtomGroup, AtomRank)), NextMetadataNo); NextMetadataNo++; break; @@ -1857,7 +1860,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_SUBPROGRAM: { - if (Record.size() < 18 || Record.size() > 21) + if (Record.size() < 18 || Record.size() > 22) return error("Invalid record"); bool HasSPFlags = Record[0] & 4; @@ -1922,6 +1925,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( HasAnnotations = Record.size() >= 19; HasTargetFuncName = Record.size() >= 20; } + uint32_t NextAtomGroup = Record.size() >= 21 ? Record[20] : 0; Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]); DISubprogram *SP = GET_OR_DISTINCT( DISubprogram, @@ -1947,8 +1951,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( HasAnnotations ? getMDOrNull(Record[18 + OffsetB]) : nullptr, // annotations HasTargetFuncName ? getMDString(Record[19 + OffsetB]) - : nullptr // targetFuncName - )); + : nullptr, // targetFuncName + NextAtomGroup)); MetadataList.assignValue(SP, NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 628b939af19ce..43e167ce84aaa 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1799,12 +1799,15 @@ unsigned ModuleBitcodeWriter::createDILocationAbbrev() { // location (it's never more expensive than building an array size 1). auto Abbv = std::make_shared(); Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isDistinct + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // line + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // column + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // scope + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // inlinedAt + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImplicitCode + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, + 6)); // atomGroup | TODO tune the VBR size. + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // atomRank return Stream.EmitAbbrev(std::move(Abbv)); } @@ -1820,7 +1823,8 @@ void ModuleBitcodeWriter::writeDILocation(const DILocation *N, Record.push_back(VE.getMetadataID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt())); Record.push_back(N->isImplicitCode()); - + Record.push_back(N->getAtomGroup()); + Record.push_back(N->getAtomRank()); Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev); Record.clear(); } @@ -2141,7 +2145,8 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N, Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Record.push_back(VE.getMetadataOrNullID(N->getRawTargetFuncName())); - + Record.push_back( + N->getKeyInstructionsEnabled() ? N->getNextDILocationAtomGroup() : 0); Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); Record.clear(); } @@ -3710,6 +3715,8 @@ void ModuleBitcodeWriter::writeFunction( if (DILocation *DL = I.getDebugLoc()) { if (DL == LastDL) { // Just repeat the same debug loc as last time. + // TODO: Probably want to have this ignore atom-group... Experiment + // with that. Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals); } else { Vals.push_back(DL->getLine()); @@ -3717,6 +3724,8 @@ void ModuleBitcodeWriter::writeFunction( Vals.push_back(VE.getMetadataOrNullID(DL->getScope())); Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt())); Vals.push_back(DL->isImplicitCode()); + Vals.push_back(DL->getAtomGroup()); + Vals.push_back(DL->getAtomRank()); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); Vals.clear(); LastDL = DL; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5fb74a016a75e..651adda32175e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -169,8 +169,10 @@ static cl::opt MinimizeAddrInV5Option( "Stuff")), cl::init(DwarfDebug::MinimizeAddrInV5::Default)); +/// Chicken-bit that can be set to false to disable the interpretation of Key +/// Instructions metadata for is_stmt placement. static cl::opt KeyInstructionsAreStmts("dwarf-use-key-instructions", - cl::Hidden, cl::init(false)); + cl::Hidden, cl::init(true)); static constexpr unsigned ULEB128PadSize = 4; @@ -2077,8 +2079,16 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { unsigned LastAsmLine = Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine(); + // Not-Key-Instructions functions inlined into Key Instructions functions + // should fall back to default is_stmt handling. + bool ScopeUsesKeyInstructions = + KeyInstructionsAreStmts && SP->getKeyInstructionsEnabled(); + if (ScopeUsesKeyInstructions && DL && DL.getInlinedAt()) + ScopeUsesKeyInstructions = + DL->getScope()->getSubprogram()->getKeyInstructionsEnabled(); + bool IsKey = false; - if (KeyInstructionsAreStmts && DL && DL.getLine()) + if (ScopeUsesKeyInstructions && DL && DL.getLine()) IsKey = KeyInstructions.contains(MI); if (!DL && MI == PrologEndLoc) { @@ -2158,7 +2168,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { PrologEndLoc = nullptr; } - if (KeyInstructionsAreStmts) { + if (ScopeUsesKeyInstructions) { if (IsKey) Flags |= DWARF2_FLAG_IS_STMT; } else { @@ -2415,15 +2425,19 @@ void DwarfDebug::computeKeyInstructions(const MachineFunction *MF) { const auto &TII = *MI.getParent()->getParent()->getSubtarget().getInstrInfo(); bool IsCallLike = MI.isCall() || TII.isTailCall(MI); - if (IsCallLike) { + // (Group: n, Rank: 0) is a sentinel that means disregard AtomGroup and + // emit as is_stmt, typically generated while merging instructions. + bool IsKeySentinel = + MI.getDebugLoc()->getAtomGroup() && !MI.getDebugLoc()->getAtomRank(); + if (IsKeySentinel || IsCallLike) { assert(MI.getDebugLoc() && "Unexpectedly missing DL"); - // Calls are always key. Put the buoy (may not be the call) into + // These are always key. Put the buoy (may not be this inst) into // KeyInstructions directly rather than the candidate map to avoid it - // being erased (and we may not have a group number for the call). + // being erased (and we may not have a group number for a call inst). KeyInstructions.insert(Buoy); - // Avoid floating any future is_stmts up to the call. + // Avoid floating any future is_stmts up to this instruction. Buoy = nullptr; BuoyAtom = 0; @@ -2433,9 +2447,9 @@ void DwarfDebug::computeKeyInstructions(const MachineFunction *MF) { } auto *InlinedAt = MI.getDebugLoc()->getInlinedAt(); - uint64_t Group = MI.getDebugLoc()->getAtomGroup(); + uint32_t Group = MI.getDebugLoc()->getAtomGroup(); uint8_t Rank = MI.getDebugLoc()->getAtomRank(); - if (!Group || !Rank) + if (!Group) continue; // Don't let is_stmts float past instructions from different source atoms. @@ -2651,7 +2665,13 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) { PrologEndLoc = emitInitialLocDirective( *MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID()); - if (KeyInstructionsAreStmts) + // If this function wasn't built with Key Instructions but has a function + // inlined into it that was, we treat the inlined instance as if it wasn't + // built with Key Instructions. If this function was built with Key + // Instructions but a function inlined into it wasn't then we continue to use + // Key Instructions for this function and fall back to non-key behaviour for + // the inlined function (except it doesn't beneit from findForceIsStmtInstrs). + if (KeyInstructionsAreStmts && SP->getKeyInstructionsEnabled()) computeKeyInstructions(MF); else findForceIsStmtInstrs(MF); diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 3a364d5ff0d20..04a03e53bcd45 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -2332,8 +2332,8 @@ bool MIParser::parseDILocation(MDNode *&Loc) { MDNode *Scope = nullptr; MDNode *InlinedAt = nullptr; bool ImplicitCode = false; - uint64_t AtomGroup = 0; - uint64_t AtomRank = 0; + uint32_t AtomGroup = 0; + uint32_t AtomRank = 0; if (expectAndConsume(MIToken::lparen)) return true; diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 66d29cb5d65e4..abb576b64b205 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -943,8 +943,8 @@ bool WinEHPrepareImpl::cloneCommonBlocks(Function &F) { << "\'.\n"); // Create a new basic block and copy instructions into it! - BasicBlock *CBB = - CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName())); + BasicBlock *CBB = CloneBasicBlock( + BB, VMap, F.getSubprogram(), Twine(".for.", FuncletPadBB->getName())); // Insert the clone immediately after the original to ensure determinism // and to keep the same relative ordering of any funclet's blocks. CBB->insertInto(&F, BB->getNextNode()); diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index ca3d8438654dc..e59703417121b 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -5407,7 +5407,7 @@ void OpenMPIRBuilder::createIfVersion(CanonicalLoopInfo *CanonicalLoop, VMap[CanonicalLoop->getPreheader()] = ElseBlock; for (BasicBlock *Block : L->getBlocks()) { - BasicBlock *NewBB = CloneBasicBlock(Block, VMap, "", F); + BasicBlock *NewBB = CloneBasicBlock(Block, VMap, F->getSubprogram(), "", F); NewBB->moveBefore(CanonicalLoop->getExit()); VMap[Block] = NewBB; NewBlocks.push_back(NewBB); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 7223dd845d18d..b9c16c8b29f2b 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2452,6 +2452,8 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, Printer.printMetadata("thrownTypes", N->getRawThrownTypes()); Printer.printMetadata("annotations", N->getRawAnnotations()); Printer.printString("targetFuncName", N->getTargetFuncName()); + if (N->getKeyInstructionsEnabled()) + Printer.printInt("nextAtomGroup", N->getNextDILocationAtomGroup()); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 5e5ff22132e99..8528c1ed55803 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -934,14 +934,14 @@ DISubprogram *DIBuilder::createFunction( unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams, DISubprogram *Decl, - DITypeArray ThrownTypes, DINodeArray Annotations, - StringRef TargetFuncName) { + DITypeArray ThrownTypes, DINodeArray Annotations, StringRef TargetFuncName, + bool UseKeyInstructions) { bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; auto *Node = getSubprogram( /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr, - ThrownTypes, Annotations, TargetFuncName); + ThrownTypes, Annotations, TargetFuncName, UseKeyInstructions); AllSubprograms.push_back(Node); trackIfUnresolved(Node); @@ -968,7 +968,7 @@ DISubprogram *DIBuilder::createMethod( unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment, DIType *VTableHolder, DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams, - DITypeArray ThrownTypes) { + DITypeArray ThrownTypes, bool UseKeyInstructions) { assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); @@ -978,7 +978,7 @@ DISubprogram *DIBuilder::createMethod( /*IsDistinct=*/IsDefinition, VMContext, cast(Context), Name, LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment, Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr, - nullptr, ThrownTypes); + nullptr, ThrownTypes, nullptr, "", IsDefinition && UseKeyInstructions); AllSubprograms.push_back(SP); trackIfUnresolved(SP); diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 473114b99225b..fa8b84f4ba544 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -19,8 +19,10 @@ #include "llvm/IR/DebugProgramInstruction.h" #include "llvm/IR/Function.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" @@ -63,8 +65,9 @@ DebugVariableAggregate::DebugVariableAggregate(const DbgVariableIntrinsic *DVI) : DebugVariable(DVI->getVariable(), std::nullopt, DVI->getDebugLoc()->getInlinedAt()) {} -DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned Column, uint64_t AtomGroup, uint8_t AtomRank, +DILocation::DILocation(LLVMContext &C, StorageType Storage, + DISubprogram *SPForKeyInstructions, unsigned Line, + unsigned Column, uint32_t AtomGroup, uint8_t AtomRank, ArrayRef MDs, bool ImplicitCode) : MDNode(C, DILocationKind, Storage, MDs) #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS @@ -75,8 +78,18 @@ DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits"); #endif - if (AtomGroup) - C.updateDILocationAtomGroupWaterline(AtomGroup + 1); + + if (AtomGroup && SPForKeyInstructions) { + // Fn might be a temporary during parsing, which sucks but there we go. + // allow null for now - probably need to verify somewhere? + // this occurs e.g. + // !1 = ... inlinedAt !2 // < temporary + // !2 = ... + // TODO: Accept temporaries, so we can work that out in here? + assert(false); + assert(SPForKeyInstructions->isDefinition()); + SPForKeyInstructions->updateDILocationAtomGroupWaterline(AtomGroup + 1); + } assert((MDs.size() == 1 || MDs.size() == 2) && "Expected a scope and optional inlined-at"); @@ -95,10 +108,31 @@ static void adjustColumn(unsigned &Column) { Column = 0; } +static DISubprogram *getResolvedInlinedAtSubprogram(Metadata *Scope, + Metadata *InlinedAt) { + auto *InlinedAtNode = dyn_cast_or_null(InlinedAt); + if (InlinedAt && (!InlinedAtNode || !InlinedAtNode->isResolved())) + return nullptr; + + auto *LS = dyn_cast(Scope); + if (!LS || !LS->isResolved()) + return nullptr; + + auto *LexicalBlockBase = dyn_cast(LS); + if (LexicalBlockBase && + !cast(LexicalBlockBase->getRawScope())->isResolved()) + return nullptr; + + if (!InlinedAt) + return LS->getSubprogram(); + + return cast(InlinedAt)->getInlinedAtScope()->getSubprogram(); +} + DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode, - uint64_t AtomGroup, uint8_t AtomRank, + uint32_t AtomGroup, uint8_t AtomRank, StorageType Storage, bool ShouldCreate) { // Fixup column. adjustColumn(Column); @@ -117,11 +151,16 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, SmallVector Ops; Ops.push_back(Scope); + if (InlinedAt) Ops.push_back(InlinedAt); - return storeImpl(new (Ops.size(), Storage) - DILocation(Context, Storage, Line, Column, AtomGroup, - AtomRank, Ops, ImplicitCode), + + DISubprogram *SPForKeyInstructions = nullptr; + // AtomGroup ? getResolvedInlinedAtSubprogram(Scope, InlinedAt) : nullptr; + // What about don't, and just verify this :---) + return storeImpl(new (Ops.size(), Storage) DILocation( + Context, Storage, SPForKeyInstructions, Line, Column, + AtomGroup, AtomRank, Ops, ImplicitCode), Storage, Context.pImpl->DILocations); } @@ -383,12 +422,11 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup(); Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank(); } else { - // If either instruction is part of a source atom, reassign it a new - // atom group. This essentially regresses to non-key-instructions - // behaviour (now that it's the only instruction in its group it'll - // probably get is_stmt applied). - Group = C.incNextDILocationAtomGroup(); - Rank = 1; + // If either instruction is part of a source atom, reassign it a sentinel + // atom rank. This causes the instruction to get is_stmt, ignoring other + // instructions in the group (and the other instructions ignore this one). + Group = L1->getAtomGroup() ? L1->getAtomGroup() : L2->getAtomGroup(); + Rank = 0; } return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode, Group, Rank); @@ -1396,7 +1434,7 @@ DISubprogram *DISubprogram::getImpl( int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName, - StorageType Storage, bool ShouldCreate) { + uint32_t NextAtomGroup, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); assert(isCanonical(TargetFuncName) && "Expected canonical MDString"); @@ -1425,10 +1463,21 @@ DISubprogram *DISubprogram::getImpl( } } } - DEFINE_GETIMPL_STORE_N( - DISubprogram, - (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, - Ops.size()); + DISubprogram *SP = [&]() { + DEFINE_GETIMPL_STORE_N( + DISubprogram, + (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, + Ops.size()); + }(); + // Key Instructions: As per DISubprogram::NextAtomGroup's doc-comment, + // NextAtomGroup doesn't contribute to the identity of the DISubprogram; it's + // not represented in MDNodeKeyImpl. Set it now, after the + // (distinct) DISubprogram has been created. + if (NextAtomGroup) { + assert(SP->isDistinct()); + SP->NextAtomGroup = NextAtomGroup; + } + return SP; } bool DISubprogram::describes(const Function *F) const { diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index 57532cd491dd6..447e5d92e0b99 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -377,11 +377,3 @@ StringRef LLVMContext::getDefaultTargetFeatures() { void LLVMContext::setDefaultTargetFeatures(StringRef Features) { pImpl->DefaultTargetFeatures = Features; } - -void LLVMContext::updateDILocationAtomGroupWaterline(uint64_t V) { - pImpl->NextAtomGroup = std::max(pImpl->NextAtomGroup, V); -} - -uint64_t LLVMContext::incNextDILocationAtomGroup() { - return pImpl->NextAtomGroup++; -} diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 87cd52e357be2..7cbe9cec18a1f 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -316,12 +316,12 @@ template <> struct MDNodeKeyImpl { Metadata *InlinedAt; bool ImplicitCode; #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS - uint64_t AtomGroup : 61; - uint64_t AtomRank : 3; + uint32_t AtomGroup : 29; + uint32_t AtomRank : 3; #endif MDNodeKeyImpl(unsigned Line, uint16_t Column, Metadata *Scope, - Metadata *InlinedAt, bool ImplicitCode, uint64_t AtomGroup, + Metadata *InlinedAt, bool ImplicitCode, uint32_t AtomGroup, uint8_t AtomRank) : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt), ImplicitCode(ImplicitCode) @@ -939,6 +939,7 @@ template <> struct MDNodeKeyImpl { Metadata *ThrownTypes; Metadata *Annotations; MDString *TargetFuncName; + // Key Instructions: Do not track NextAtomGroup. See DISubprogram for info. MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, @@ -1886,16 +1887,6 @@ class LLVMContextImpl { std::string DefaultTargetCPU; std::string DefaultTargetFeatures; - - /// The next available source atom group number. The front end is responsible - /// for assigning source atom numbers, but certain optimisations need to - /// assign new group numbers to a set of instructions. Most often code - /// duplication optimisations like loop unroll. Tracking a global maximum - /// value means we can know (cheaply) we're never using a group number that's - /// already used within this function. - /// - /// Start a 1 because 0 means the source location isn't part of an atom group. - uint64_t NextAtomGroup = 1; }; } // end namespace llvm diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 592bb6aa90613..56a45d4cd5474 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3165,6 +3165,12 @@ void Verifier::visitFunction(const Function &F) { CheckDI(SP->describes(&F), "!dbg attachment points at wrong subprogram for function", N, &F, &I, DL, Scope, SP); + + if (auto atomGroup = DL->getAtomGroup()) + CheckDI(!SP->getKeyInstructionsEnabled() || + SP->getNextDILocationAtomGroup() > atomGroup, + "DbgLoc's atomGroup should be less than SP's nextAtomGroup", DL, + atomGroup, SP, SP->getNextDILocationAtomGroup()); }; for (auto &BB : F) for (auto &I : BB) { diff --git a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp index c14bbecf0d4e1..1525c8202de82 100644 --- a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp +++ b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp @@ -1765,7 +1765,8 @@ void CHR::cloneScopeBlocks(CHRScope *Scope, for (BasicBlock *BB : RI.R->blocks()) { // This includes the blocks in the // sub-Scopes. assert(BB != PreEntryBlock && "Don't copy the preetntry block"); - BasicBlock *NewBB = CloneBasicBlock(BB, VMap, ".nonchr", &F); + BasicBlock *NewBB = + CloneBasicBlock(BB, VMap, F.getSubprogram(), ".nonchr", &F); NewBlocks.push_back(NewBB); VMap[BB] = NewBB; diff --git a/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp b/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp index 938aab5879044..a044e5245c954 100644 --- a/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp @@ -1085,8 +1085,8 @@ struct TransformDFA { DomTreeUpdater *DTU) { ValueToValueMapTy VMap; BasicBlock *NewBB = CloneBasicBlock( - BB, VMap, ".jt" + std::to_string(NextState.getLimitedValue()), - BB->getParent()); + BB, VMap, BB->getParent()->getSubprogram(), + ".jt" + std::to_string(NextState.getLimitedValue()), BB->getParent()); NewBB->moveAfter(BB); NumCloned++; diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 9449b4cb35b93..062dc47c8fb02 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -2084,7 +2084,7 @@ void JumpThreadingPass::cloneInstructions(ValueToValueMapTy &ValueMapping, NewPN->addIncoming(PN->getIncomingValueForBlock(PredBB), PredBB); ValueMapping[PN] = NewPN; if (const DebugLoc &DL = PN->getDebugLoc()) - mapAtomInstance(DL, ValueMapping); + mapAtomInstance(PN->getFunction()->getSubprogram(), DL, ValueMapping); } // Clone noalias scope declarations in the threaded block. When threading a @@ -2114,7 +2114,7 @@ void JumpThreadingPass::cloneInstructions(ValueToValueMapTy &ValueMapping, CloneAndRemapDbgInfo(New, &*BI); if (const DebugLoc &DL = New->getDebugLoc()) - mapAtomInstance(DL, ValueMapping); + mapAtomInstance(New->getFunction()->getSubprogram(), DL, ValueMapping); if (RetargetDbgValueIfPossible(New)) continue; @@ -2723,7 +2723,7 @@ bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred( // Remap debug variable operands. remapDebugVariable(ValueMapping, New); if (const DebugLoc &DL = New->getDebugLoc()) - mapAtomInstance(DL, ValueMapping); + mapAtomInstance(New->getFunction()->getSubprogram(), DL, ValueMapping); // If this instruction can be simplified after the operands are updated, // just use the simplified value instead. This frequently happens due to diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index 0bf90036b8b82..c69c8e8305cbe 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -298,10 +298,9 @@ static void buildPartialInvariantUnswitchConditionalBranch( Instruction *Inst = cast(Val); Instruction *NewInst = Inst->clone(); - if (const DebugLoc &DL = Inst->getDebugLoc()) - mapAtomInstance(DL, VMap); - NewInst->insertInto(&BB, BB.end()); + if (const DebugLoc &DL = Inst->getDebugLoc()) + mapAtomInstance(Inst->getFunction()->getSubprogram(), DL, VMap); RemapInstruction(NewInst, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); VMap[Val] = NewInst; @@ -1183,7 +1182,9 @@ static BasicBlock *buildClonedLoopBlocks( // a helper. auto CloneBlock = [&](BasicBlock *OldBB) { // Clone the basic block and insert it before the new preheader. - BasicBlock *NewBB = CloneBasicBlock(OldBB, VMap, ".us", OldBB->getParent()); + BasicBlock *NewBB = + CloneBasicBlock(OldBB, VMap, LoopPH->getParent()->getSubprogram(), + ".us", OldBB->getParent()); NewBB->moveBefore(LoopPH); // Record this block and the mapping. diff --git a/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp b/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp index ddd203f3acf71..7400cbc28924f 100644 --- a/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp +++ b/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -405,7 +405,8 @@ bool llvm::SplitIndirectBrCriticalEdges(Function &F, // block's body. Create a copy of Target that will be used by the "direct" // preds. ValueToValueMapTy VMap; - BasicBlock *DirectSucc = CloneBasicBlock(Target, VMap, ".clone", &F); + BasicBlock *DirectSucc = + CloneBasicBlock(Target, VMap, F.getSubprogram(), ".clone", &F); if (!VMap.AtomMap.empty()) for (Instruction &I : *DirectSucc) RemapSourceAtom(&I, VMap); diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 5487dbef8a434..2c10ac26257e3 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -43,11 +43,20 @@ using namespace llvm; STATISTIC(RemappedAtomMax, "Highest global NextAtomGroup (after mapping)"); -void llvm::mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap) { - auto CurGroup = DL->getAtomGroup(); +void llvm::mapAtomInstance(DISubprogram *Target, const DebugLoc &DL, + ValueToValueMapTy &VMap) { + assert(!Target || Target->isDefinition()); + if (!Target || !Target->getKeyInstructionsEnabled()) + return; + + auto CurGroup = DL.get()->getAtomGroup(); if (!CurGroup) return; +#ifdef EXPENSIVE_CHECKS + assert(Target == DL->getInlinedAtScope()->getSubprogram()); +#endif + // Try inserting a new entry. If there's already a mapping for this atom // then there's nothing to do. auto [It, Inserted] = VMap.AtomMap.insert({{DL.getInlinedAt(), CurGroup}, 0}); @@ -55,7 +64,7 @@ void llvm::mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap) { return; // Map entry to a new atom group. - uint64_t NewGroup = DL->getContext().incNextDILocationAtomGroup(); + uint32_t NewGroup = Target->incNextDILocationAtomGroup(); assert(NewGroup > CurGroup && "Next should always be greater than current"); It->second = NewGroup; @@ -111,8 +120,9 @@ MetadataPredicate createIdentityMDPredicate(const Function &F, /// See comments in Cloning.h. BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, - const Twine &NameSuffix, Function *F, - ClonedCodeInfo *CodeInfo, bool MapAtoms) { + DISubprogram *SP, const Twine &NameSuffix, + Function *F, ClonedCodeInfo *CodeInfo, + bool MapAtoms) { BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), "", F); NewBB->IsNewDbgInfoFormat = BB->IsNewDbgInfoFormat; if (BB->hasName()) @@ -133,7 +143,7 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, if (MapAtoms) { if (const DebugLoc &DL = NewInst->getDebugLoc()) - mapAtomInstance(DL.get(), VMap); + mapAtomInstance(SP, DL.get(), VMap); } if (isa(I) && !I.isDebugOrPseudoInst()) { @@ -238,8 +248,8 @@ void llvm::CloneFunctionBodyInto(Function &NewFunc, const Function &OldFunc, for (const BasicBlock &BB : OldFunc) { // Create a new basic block and copy instructions into it! - BasicBlock *CBB = - CloneBasicBlock(&BB, VMap, NameSuffix, &NewFunc, CodeInfo); + BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NewFunc.getSubprogram(), + NameSuffix, &NewFunc, CodeInfo); // Add basic block mapping. VMap[&BB] = CBB; @@ -1057,7 +1067,8 @@ Loop *llvm::cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, BasicBlock *OrigPH = OrigLoop->getLoopPreheader(); assert(OrigPH && "No preheader"); - BasicBlock *NewPH = CloneBasicBlock(OrigPH, VMap, NameSuffix, F); + BasicBlock *NewPH = + CloneBasicBlock(OrigPH, VMap, F->getSubprogram(), NameSuffix, F); // To rename the loop PHIs. VMap[OrigPH] = NewPH; Blocks.push_back(NewPH); @@ -1089,7 +1100,8 @@ Loop *llvm::cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, Loop *&NewLoop = LMap[CurLoop]; assert(NewLoop && "Expecting new loop to be allocated"); - BasicBlock *NewBB = CloneBasicBlock(BB, VMap, NameSuffix, F); + BasicBlock *NewBB = + CloneBasicBlock(BB, VMap, F->getSubprogram(), NameSuffix, F); VMap[BB] = NewBB; // Update LoopInfo. diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp b/llvm/lib/Transforms/Utils/Debugify.cpp index 729813a92f516..830072426a1c4 100644 --- a/llvm/lib/Transforms/Utils/Debugify.cpp +++ b/llvm/lib/Transforms/Utils/Debugify.cpp @@ -123,7 +123,9 @@ bool llvm::applyDebugifyMetadata( if (F.hasPrivateLinkage() || F.hasInternalLinkage()) SPFlags |= DISubprogram::SPFlagLocalToUnit; auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, - SPType, NextLine, DINode::FlagZero, SPFlags); + SPType, NextLine, DINode::FlagZero, SPFlags, + nullptr, nullptr, nullptr, nullptr, "", + /*UseKeyInstructions*/ ApplyAtomGroups); F.setSubprogram(SP); // Helper that inserts a dbg.value before \p InsertBefore, copying the @@ -145,7 +147,7 @@ bool llvm::applyDebugifyMetadata( for (BasicBlock &BB : F) { // Attach debug locations. for (Instruction &I : BB) { - uint64_t AtomGroup = ApplyAtomGroups ? NextLine : 0; + uint32_t AtomGroup = ApplyAtomGroups ? NextLine : 0; uint8_t AtomRank = ApplyAtomGroups ? 1 : 0; uint64_t Line = NextLine++; I.setDebugLoc(DILocation::get(Ctx, Line, 1, SP, nullptr, false, @@ -199,6 +201,7 @@ bool llvm::applyDebugifyMetadata( if (ApplyToMF) ApplyToMF(DIB, F); DIB.finalizeSubprogram(SP); + SP->updateDILocationAtomGroupWaterline(NextLine); } DIB.finalize(); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 7a9605bf5f8d4..d10b2b7d2fc3e 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1917,10 +1917,32 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, DVR->setDebugLoc(IDL); }; + // Update the atomGroup waterline (from inlined instructions) if both + // functions were built with Key Instructions. The result at DWARF emission + // is: + // + // Key Instructions before -> after inlining + // caller + callee -> caller + inlined callee + // caller only -> caller only + // callee only -> neither + // neither -> neither + // + // `callee only -> inlined callee only` isn't supported due to how + // `getKeyInstructionsEnabled` is implemented, and because it may be + // expensive to assume all functions may contain Key Instructions in + // a subset of nested scopes. + bool KeyInstructions = Fn->getSubprogram()->getKeyInstructionsEnabled(); + uint32_t MaxInlineAtom = 0; + // Iterate over all instructions, updating metadata and debug-info records. for (; FI != Fn->end(); ++FI) { for (Instruction &I : *FI) { UpdateInst(I); + + if (KeyInstructions) + if (auto &DL = I.getDebugLoc()) + MaxInlineAtom = std::max(MaxInlineAtom, DL->getAtomGroup()); + for (DbgRecord &DVR : I.getDbgRecordRange()) { UpdateDVR(&DVR); } @@ -1940,6 +1962,9 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, } } } + + if (KeyInstructions) + Fn->getSubprogram()->updateDILocationAtomGroupWaterline(MaxInlineAtom + 1); } #undef DEBUG_TYPE diff --git a/llvm/lib/Transforms/Utils/LoopConstrainer.cpp b/llvm/lib/Transforms/Utils/LoopConstrainer.cpp index 8f103153059e8..63994d66ccbec 100644 --- a/llvm/lib/Transforms/Utils/LoopConstrainer.cpp +++ b/llvm/lib/Transforms/Utils/LoopConstrainer.cpp @@ -468,7 +468,8 @@ LoopConstrainer::LoopConstrainer(Loop &L, LoopInfo &LI, void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result, const char *Tag) const { for (BasicBlock *BB : OriginalLoop.getBlocks()) { - BasicBlock *Clone = CloneBasicBlock(BB, Result.Map, Twine(".") + Tag, &F); + BasicBlock *Clone = CloneBasicBlock(BB, Result.Map, F.getSubprogram(), + Twine(".") + Tag, &F); Result.Blocks.push_back(Clone); Result.Map[BB] = Clone; } diff --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp index f343962548259..db7e2032bfeed 100644 --- a/llvm/lib/Transforms/Utils/LoopPeel.cpp +++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp @@ -848,7 +848,8 @@ static void cloneLoopBlocks( // For each block in the original loop, create a new copy, // and update the value map with the newly created values. for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) { - BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".peel", F); + BasicBlock *NewBB = + CloneBasicBlock(*BB, VMap, F->getSubprogram(), ".peel", F); NewBlocks.push_back(NewBB); // If an original block is an immediate child of the loop L, its copy diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 693b1f517f8d0..c9f7ae690071a 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -657,11 +657,11 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { // Otherwise, create a duplicate of the instruction. Instruction *C = Inst->clone(); - if (const DebugLoc &DL = C->getDebugLoc()) - mapAtomInstance(DL, ValueMap); - C->insertBefore(LoopEntryBranch->getIterator()); + if (const DebugLoc &DL = C->getDebugLoc()) + mapAtomInstance(C->getFunction()->getSubprogram(), DL, ValueMap); + ++NumInstrsDuplicated; if (LoopEntryBranch->getParent()->IsNewDbgInfoFormat && diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp index 86b268de43cf6..c92fcd42abd44 100644 --- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp @@ -717,7 +717,8 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI, for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) { ValueToValueMapTy VMap; - BasicBlock *New = CloneBasicBlock(*BB, VMap, "." + Twine(It)); + BasicBlock *New = CloneBasicBlock( + *BB, VMap, Header->getParent()->getSubprogram(), "." + Twine(It)); Header->getParent()->insert(BlockInsertPt, New); assert((*BB != Header || LI->getLoopFor(*BB) == L) && diff --git a/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp b/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp index ca90bb65f5708..900fa6d973b0f 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp @@ -369,7 +369,8 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount, for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) { ValueToValueMapTy VMap; - BasicBlock *New = CloneBasicBlock(*BB, VMap, "." + Twine(It)); + BasicBlock *New = CloneBasicBlock( + *BB, VMap, Header->getParent()->getSubprogram(), "." + Twine(It)); Header->getParent()->insert(Header->getParent()->end(), New); // Tell LI about New. diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index bf882d7406853..6ed22cdb9780c 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -355,7 +355,8 @@ CloneLoopBlocks(Loop *L, Value *NewIter, const bool UseEpilogRemainder, // For each block in the original loop, create a new copy, // and update the value map with the newly created values. for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) { - BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, "." + suffix, F); + BasicBlock *NewBB = + CloneBasicBlock(*BB, VMap, F->getSubprogram(), "." + suffix, F); NewBlocks.push_back(NewBB); addClonedBlockToLoopInfo(*BB, NewBB, LI, NewLoops); diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index e221022bb8361..b8ffd22dc7a05 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1139,7 +1139,7 @@ static void cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( // dead code caused by folding dead branches. NewBonusInst->setDebugLoc(DebugLoc()); } else if (const DebugLoc &DL = NewBonusInst->getDebugLoc()) { - mapAtomInstance(DL, VMap); + mapAtomInstance(BonusInst.getFunction()->getSubprogram(), DL, VMap); } } @@ -3606,7 +3606,7 @@ foldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, // Update operands due to translation. // Key Instructions: Remap all the atom groups. if (const DebugLoc &DL = BBI->getDebugLoc()) - mapAtomInstance(DL, TranslateMap); + mapAtomInstance(BBI->getFunction()->getSubprogram(), DL, TranslateMap); RemapInstruction(N, TranslateMap, RF_IgnoreMissingLocals | RF_NoModuleLevelChanges); diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll index 33f7f673d91c3..0d107c00247f0 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll @@ -11,6 +11,8 @@ ; CHECK: _Z1bv() ; CHECK: store i32 1, ptr @g, align 4, !dbg [[DBG:!.*]] + +; CHECK: distinct !DISubprogram(name: "b", {{.*}}nextAtomGroup: 3) ; CHECK: [[DBG]] = !DILocation(line: 3, scope: ![[#]]) @g = hidden global i32 0, align 4 @@ -36,7 +38,7 @@ entry: !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !10 = !{!"clang version 19.0.0"} -!15 = distinct !DISubprogram(name: "b", scope: !1, file: !1, line: 3, type: !16, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!15 = distinct !DISubprogram(name: "b", scope: !1, file: !1, line: 3, type: !16, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) !16 = !DISubroutineType(types: !17) !17 = !{} !18 = !DILocation(line: 3, scope: !15, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll index b9b6abdd1e9c0..a4cd790625ec3 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll @@ -8,6 +8,7 @@ ; CHECK: %add.i = add nsw i32 %mul.i, 1, !dbg [[G1R2:!.*]] ; CHECK-NEXT: store i32 %add.i, ptr %x.i, align 4, !dbg [[G1R1:!.*]] +; CHECK: distinct !DISubprogram(name: "g", {{.*}}nextAtomGroup: 2) ; CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2) ; CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) @@ -41,11 +42,10 @@ entry: !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !10 = !{!"clang version 19.0.0"} -!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !12 = !DISubroutineType(types: !13) !13 = !{} !19 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) !20 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 1) -!23 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!23 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 1) !24 = !DILocation(line: 5, scope: !23) - diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll index 612e74792fac2..3c39cc569f531 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll @@ -27,6 +27,7 @@ ; CHECK: bb.f2: ; CHECK-NEXT: store ptr @a, ptr %p, align 4, !dbg [[G4R1:!.*]] +; CHECK: distinct !DISubprogram(name: "foo", {{.*}}nextAtomGroup: 5) ; CHECK: [[G1R2]] = !DILocation(line: 1, column: 1, scope: ![[#]], atomGroup: 1, atomRank: 2) ; CHECK: [[G1R1]] = !DILocation(line: 1, column: 1, scope: ![[#]], atomGroup: 1, atomRank: 1) ; CHECK: [[G3R2]] = !DILocation(line: 1, column: 1, scope: ![[#]], atomGroup: 3, atomRank: 2) @@ -76,7 +77,7 @@ declare void @f2() !2 = !{i32 16} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) !6 = !DISubroutineType(types: !7) !7 = !{} !9 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 2) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll index 1541df3469087..1797c351b84e2 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll @@ -26,6 +26,7 @@ ; CHECK-NEXT: %C = add i32 %v2, 1, !dbg [[G1R2:!.*]] ; CHECK-NEXT: store i32 %C, ptr %p, align 4, !dbg [[G1R1:!.*]] +; CHECK: distinct !DISubprogram(name: "test1", {{.*}}nextAtomGroup: 3) ; CHECK: [[G2R2]] = !DILocation(line: 8, column: 1, scope: ![[#]], atomGroup: 2, atomRank: 2) ; CHECK: [[G2R1]] = !DILocation(line: 8, column: 1, scope: ![[#]], atomGroup: 2, atomRank: 1) ; CHECK: [[G1R2]] = !DILocation(line: 8, column: 1, scope: ![[#]], atomGroup: 1, atomRank: 2) @@ -70,7 +71,7 @@ declare void @f3() !2 = !{i32 12} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocation(line: 8, column: 1, scope: !5, atomGroup: 1, atomRank: 2) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll index 1ab1c1ac2e9f6..2acfb54ac4392 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll @@ -30,6 +30,7 @@ ; CHECK-NEXT: %C = add i32 %v2, 1, !dbg [[G2R2:!.*]] ; CHECK-NEXT: store i32 %C, ptr %p, align 4, !dbg [[G2R1:!.*]] +; CHECK: distinct !DISubprogram(name: "test5", {{.*}}nextAtomGroup: 4) ; CHECK: [[G3R2]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 2) ; CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1) ; CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) @@ -79,7 +80,7 @@ declare void @f3() !2 = !{i32 12} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "test5", linkageName: "test5", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "test5", linkageName: "test5", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/link-two-modes.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/link-two-modes.ll new file mode 100644 index 0000000000000..4ca718eef5869 --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/link-two-modes.ll @@ -0,0 +1,67 @@ +; RUN: split-file %s %t +; RUN: llvm-as %t/key-instr-enabled.ll -o %t/key-instr-enabled.bc +; RUN: llvm-as %t/key-instr-disabled.ll -o %t/key-instr-disabled.bc +; RUN: llvm-link %t/key-instr-enabled.bc %t/key-instr-disabled.bc -o - | llvm-dis | FileCheck %s + +;; Check the Key Instructions metadata is preserved correctly when linking a +;; modules with Key Instructions enabled/disabled. + +;; Key Instructions enabled. +; CHECK: void @f() !dbg [[f:!.*]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret void, !dbg [[enabled:!.*]] +; CHECK-NEXT: } + +;; Key Instructions disabled. +; CHECK: void @g() !dbg [[g:!.*]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret void, !dbg [[disabled:!.*]] +; CHECK-NEXT: } + +; CHECK: !llvm.dbg.cu = !{!0, !2} +; CHECK-NEXT: !llvm.module.flags = !{!4} + +; CHECK: [[file1:!.*]] = !DIFile(filename: "key-instr-enabled.cpp", directory: "/") +; CHECK: [[file2:!.*]] = !DIFile(filename: "key-instr-disabled.cpp", directory: "/") +; CHECK: [[f]] = distinct !DISubprogram(name: "f", scope: [[file1]]{{.*}}, nextAtomGroup: 2) +; CHECK: [[enabled]] = !DILocation(line: 1, column: 11, scope: [[f]], atomGroup: 1, atomRank: 1) +; CHECK: [[g]] = distinct !DISubprogram(name: "g", scope: [[file2]] +; CHECK-NOT: nextAtomGroup +; CHECK-SAME: ) +; CHECK: [[disabled]] = !DILocation(line: 1, column: 11, scope: [[g]]) + +;--- key-instr-enabled.ll +define dso_local void @f() !dbg !10 { +entry: + ret void, !dbg !13 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "key-instr-enabled.cpp", directory: "/") +!3 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 21.0.0git"} +!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, nextAtomGroup: 2) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !DILocation(line: 1, column: 11, scope: !10, atomGroup: 1, atomRank: 1) + +;--- key-instr-disabled.ll +define dso_local void @g() !dbg !10 { +entry: + ret void, !dbg !13 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "key-instr-disabled.cpp", directory: "/") +!3 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 21.0.0git"} +!10 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !DILocation(line: 1, column: 11, scope: !10) \ No newline at end of file diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll index 6da7146b5b07a..352706dd2a8fd 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll @@ -25,6 +25,7 @@ ; CHECK: [[CMP:%.*]] = icmp slt i32 {{.*}}, 100, !dbg [[G2R2:![0-9]+]] ; CHECK: br i1 [[CMP]], label %for.body, label %for.end, !dbg [[G2R1:![0-9]+]] ; +; CHECK: distinct !DISubprogram(name: "test1", {{.*}}nextAtomGroup: 5) ; CHECK: [[G3R1]] = !DILocation(line: 4{{.*}}, atomGroup: 3, atomRank: 1) ; CHECK: [[G4R1]] = !DILocation(line: 6{{.*}}, atomGroup: 4, atomRank: 1) ; CHECK: [[G1R1]] = !DILocation(line: 4{{.*}}, atomGroup: 1, atomRank: 1) @@ -40,9 +41,9 @@ entry: for.cond: ; preds = %for.body, %entry %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] - store i32 %i.0, ptr @glob, align 16, !dbg !DILocation(line: 4, scope: !5, atomGroup: 1, atomRank: 1) - %cmp = icmp slt i32 %i.0, 100, !dbg !DILocation(line: 5, scope: !5, atomGroup: 2, atomRank: 2) - br i1 %cmp, label %for.body, label %for.end, !dbg !DILocation(line: 6, scope: !5, atomGroup: 2, atomRank: 1) + store i32 %i.0, ptr @glob, align 16, !dbg !8 + %cmp = icmp slt i32 %i.0, 100, !dbg !9 + br i1 %cmp, label %for.body, label %for.end, !dbg !10 for.body: ; preds = %for.cond %inc = add nsw i32 %i.0, 1 @@ -69,6 +70,9 @@ attributes #1 = { noduplicate } !2 = !{i32 12} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) !6 = !DISubroutineType(types: !7) !7 = !{} +!8 = !DILocation(line: 4, scope: !5, atomGroup: 1, atomRank: 1) +!9 = !DILocation(line: 5, scope: !5, atomGroup: 2, atomRank: 2) +!10 = !DILocation(line: 6, scope: !5, atomGroup: 2, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll index 6deb04cc00f8d..06deab8be50a6 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll @@ -25,6 +25,7 @@ ; CHECK-NEXT: store i64 %indvars.iv.next.2, ptr %p, align 4, !dbg [[G7R1:!.*]] ; CHECK-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4 +; CHECK: distinct !DISubprogram(name: "unroll", {{.*}}nextAtomGroup: 8) ; CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1) ; CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1) ; CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1) @@ -63,7 +64,7 @@ for.body: ; preds = %for.body, %for.body !2 = !{i32 17} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "unroll", linkageName: "unroll", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "unroll", linkageName: "unroll", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll index 557e8387e5bc5..2eb07d9fc738c 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll @@ -41,7 +41,7 @@ attributes #0 = { nounwind ssp uwtable } !2 = !{i32 8} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} !11 = !DILocation(line: 4, column: 1, scope: !5, atomGroup: 1, atomRank: 2) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll index 557950439ef3b..2752330650200 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll @@ -125,7 +125,7 @@ declare void @clobber() !2 = !{i32 13} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "partial_unswitch_true_successor_hoist_invariant", linkageName: "partial_unswitch_true_successor_hoist_invariant", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "partial_unswitch_true_successor_hoist_invariant", linkageName: "partial_unswitch_true_successor_hoist_invariant", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 14) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocation(line: 1, scope: !5, atomGroup: 1, atomRank: 1) @@ -142,6 +142,7 @@ declare void @clobber() !19 = !DILocation(line: 12, scope: !5, atomGroup: 12, atomRank: 1) !20 = !DILocation(line: 13, scope: !5, atomGroup: 13, atomRank: 1) ;. +; CHECK: distinct !DISubprogram(name: "partial_unswitch_true_successor_hoist_invariant", {{.*}}nextAtomGroup: 27) ; CHECK: [[DBG8]] = !DILocation(line: 3{{.*}}, atomGroup: 24, atomRank: 1) ; CHECK: [[DBG9]] = !DILocation(line: 4{{.*}}, atomGroup: 25, atomRank: 1) ; CHECK: [[DBG10]] = !DILocation(line: 5{{.*}}, atomGroup: 26, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll index 33219a582fee8..2232b84e47e83 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll @@ -1,5 +1,6 @@ ; RUN: opt %s -o - -S| FileCheck %s +; CHECK: distinct !DISubprogram(name: "f", {{.*}}nextAtomGroup: 2) ; CHECK: !DILocation(line: 1, column: 11, scope: ![[#]], atomGroup: 1, atomRank: 1) define dso_local void @f() !dbg !10 { @@ -13,7 +14,7 @@ entry: !1 = !DIFile(filename: "test.cpp", directory: "/") !3 = !{i32 2, !"Debug Info Version", i32 3} !9 = !{!"clang version 21.0.0git"} -!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) +!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, nextAtomGroup: 2) !11 = !DISubroutineType(types: !12) !12 = !{null} !13 = !DILocation(line: 1, column: 11, scope: !10, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/roundtrip.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/roundtrip.ll new file mode 100644 index 0000000000000..a84cb4e3e7135 --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/roundtrip.ll @@ -0,0 +1,82 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt %s -o - -S | llvm-as - | llvm-dis - | FileCheck %s + +; Key Instructions enabled. +define dso_local void @f() !dbg !5 { +; CHECK-LABEL: define dso_local void @f( +; CHECK-SAME: ) !dbg [[DBG5:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void, !dbg [[DBG8:![0-9]+]] +; +entry: + ret void, !dbg !8 ; atomGroup: 1, atomRank: 1 +} + +; Key Instructions enabled, atomGroup > 1 and forward-ref scope in DILocation. +define dso_local void @g() !dbg !10 { +; CHECK-LABEL: define dso_local void @g( +; CHECK-SAME: ) !dbg [[DBG9:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void, !dbg [[DBG10:![0-9]+]] +; +entry: + ret void, !dbg !9 ; atomGroup: 2, atomRank: 2 +} + +; Key Instructions not enabled. +define dso_local void @h() !dbg !11 { +; CHECK-LABEL: define dso_local void @h( +; CHECK-SAME: ) !dbg [[DBG11:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void, !dbg [[DBG12:![0-9]+]] +; +entry: + ret void, !dbg !12 ; atomGroup: 0, atomRank: 0 +} + +; Key Instructions, inlined instruction (from g). +define dso_local void @i() !dbg !13 { +; CHECK-LABEL: define dso_local void @i( +; CHECK-SAME: ) !dbg [[DBG13:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void, !dbg [[DBG14:![0-9]+]] +; +entry: + ret void, !dbg !14 ; scope g, inlinedAt i:4, atomGroup: 2, atomRank: 0 +} + +!llvm.dbg.cu = !{!0} +!llvm.debugify = !{!2, !3} +!llvm.module.flags = !{!4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) +!1 = !DIFile(filename: "roundtrip.ll", directory: "/") +!2 = !{i32 2} +!3 = !{i32 0} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) +!6 = !DISubroutineType(types: !7) +!7 = !{} +!8 = !DILocation(line: 1, scope: !5, atomGroup: 1, atomRank: 1) +!9 = !DILocation(line: 2, scope: !10, atomGroup: 2, atomRank: 2) ; fwd-ref scope. +!10 = distinct !DISubprogram(name: "g", linkageName: "g", scope: null, file: !1, line: 2, type: !6, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) +!11 = distinct !DISubprogram(name: "h", linkageName: "h", scope: null, file: !1, line: 3, type: !6, scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!12 = !DILocation(line: 3, scope: !11) +!13 = distinct !DISubprogram(name: "i", linkageName: "i", scope: null, file: !1, line: 4, type: !6, scopeLine: 4, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) +!14 = !DILocation(line: 2, scope: !10, inlinedAt: !15, atomGroup: 2, atomRank: 1) ; fwd-ref inlinedAt. +!15 = distinct !DILocation(line: 4, scope: !13) +;. +; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) +; CHECK: [[META1]] = !DIFile(filename: "{{.*}}roundtrip.ll", directory: {{.*}}) +; CHECK: [[DBG5]] = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: [[META1]], line: 1, type: [[META6:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], nextAtomGroup: 2) +; CHECK: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]]) +; CHECK: [[META7]] = !{} +; CHECK: [[DBG8]] = !DILocation(line: 1, scope: [[DBG5]], atomGroup: 1, atomRank: 1) +; CHECK: [[DBG9]] = distinct !DISubprogram(name: "g", linkageName: "g", scope: null, file: [[META1]], line: 2, type: [[META6]], scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], nextAtomGroup: 3) +; CHECK: [[DBG10]] = !DILocation(line: 2, scope: [[DBG9]], atomGroup: 2, atomRank: 2) +; CHECK: [[DBG11]] = distinct !DISubprogram(name: "h", linkageName: "h", scope: null, file: [[META1]], line: 3, type: [[META6]], scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]]) +; CHECK: [[DBG12]] = !DILocation(line: 3, scope: [[DBG11]]) +; CHECK: [[DBG13]] = distinct !DISubprogram(name: "i", linkageName: "i", scope: null, file: [[META1]], line: 4, type: [[META6]], scopeLine: 4, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], nextAtomGroup: 3) +; CHECK: [[DBG14]] = !DILocation(line: 2, scope: [[DBG9]], inlinedAt: [[META15:![0-9]+]], atomGroup: 2, atomRank: 1) +; CHECK: [[META15]] = distinct !DILocation(line: 4, scope: [[DBG13]]) +;. diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll index 75a05ad931707..98d91f4eba00a 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll @@ -70,7 +70,7 @@ f: !4 = !{i32 0} !5 = !{i32 2, !"Debug Info Version", i32 3} !7 = !DISubroutineType(types: !2) -!17 = distinct !DISubprogram(name: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!17 = distinct !DISubprogram(name: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2, nextAtomGroup: 3) !18 = !DILocation(line: 10, column: 10, scope: !17) !19 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 1, atomRank: 2) !20 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 2, atomRank: 2) @@ -79,7 +79,7 @@ f: ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: [[META2:![0-9]+]]) ; CHECK: [[META1]] = !DIFile(filename: "a.ll", directory: {{.*}}) ; CHECK: [[META2]] = !{} -; CHECK: [[DBG6]] = distinct !DISubprogram(name: "f", scope: null, file: [[META1]], line: 1, type: [[META7:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META2]]) +; CHECK: [[DBG6]] = distinct !DISubprogram(name: "f", scope: null, file: [[META1]], line: 1, type: [[META7:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META2]], nextAtomGroup: 7) ; CHECK: [[META7]] = !DISubroutineType(types: [[META2]]) ; CHECK: [[DBG8]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 5, atomRank: 2) ; CHECK: [[DBG9]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 6, atomRank: 2) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll index f8477600c6418..0fe31fdcfc51e 100644 --- a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll @@ -13,6 +13,8 @@ ; CHECK: store i32 1{{.*}}, !dbg [[DBG1:!.*]] ; CHECK: if.end.1.critedge: ; CHECK: store i32 1{{.*}}, !dbg [[DBG2:!.*]] +; +; CHECK: distinct !DISubprogram(name: "bar", {{.*}}nextAtomGroup: 3) ; CHECK: [[DBG1]] = !DILocation(line: 1{{.*}}, atomGroup: 1 ; CHECK: [[DBG2]] = !DILocation(line: 1{{.*}}, atomGroup: 2 @@ -56,7 +58,7 @@ declare void @foo() !2 = !{i32 15} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "bar", linkageName: "bar", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "bar", linkageName: "bar", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll b/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll index a21b1da15a45d..3b67005fddced 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll +++ b/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll @@ -9,6 +9,7 @@ ; CHECK: while.body.clone: ; CHECK-NEXT: %dest.sroa.clone = phi i32 [ %1, %.split ], [ poison, %if.else ], !dbg [[G2R1:!.*]] +; CHECK: distinct !DISubprogram(name: "test", {{.*}}nextAtomGroup: 3) ; CHECK: [[G1R1]] = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1) ; CHECK: [[G2R1]] = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 2, atomRank: 1) @@ -46,7 +47,7 @@ if.else1: ; preds = %if.else1, %preheade !2 = !{i32 11} !3 = !{i32 0} !4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DISubprogram(name: "test", linkageName: "test", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!5 = distinct !DISubprogram(name: "test", linkageName: "test", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} !12 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll index 6988a6fb2ec3f..496d5532e4d0e 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll @@ -47,10 +47,10 @@ target triple = "x86_64-unknown-linux-gnu" define hidden noundef i32 @_Z1fPiii(ptr %a, i32 %b, i32 %c) local_unnamed_addr !dbg !11 { entry: - tail call void @_Z12prologue_endv(), !dbg !DILocation(line: 4, scope: !11) - %add = add nsw i32 %c, %b, !dbg !DILocation(line: 6, scope: !11, atomGroup: 1, atomRank: 2) - store i32 %add, ptr %a, align 4, !dbg !DILocation(line: 5, scope: !11, atomGroup: 1, atomRank: 1) - ret i32 %add, !dbg !DILocation(line: 7, scope: !11, atomGroup: 2, atomRank: 1) + tail call void @_Z12prologue_endv(), !dbg !14 ; !DILocation(line: 4, scope: !11) + %add = add nsw i32 %c, %b, !dbg !15 ; !DILocation(line: 6, scope: !11, atomGroup: 1, atomRank: 2) + store i32 %add, ptr %a, align 4, !dbg !16 ; !DILocation(line: 5, scope: !11, atomGroup: 1, atomRank: 1) + ret i32 %add, !dbg !17 ; !DILocation(line: 7, scope: !11, atomGroup: 2, atomRank: 1) } declare void @_Z12prologue_endv() local_unnamed_addr #1 @@ -64,6 +64,10 @@ declare void @_Z12prologue_endv() local_unnamed_addr #1 !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !10 = !{!"clang version 19.0.0"} -!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) !12 = !DISubroutineType(types: !13) !13 = !{} +!14 = !DILocation(line: 4, scope: !11) +!15 = !DILocation(line: 6, scope: !11, atomGroup: 1, atomRank: 2) +!16 = !DILocation(line: 5, scope: !11, atomGroup: 1, atomRank: 1) +!17 = !DILocation(line: 7, scope: !11, atomGroup: 2, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll index ba38bb2ffe903..298e11c7b0f88 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll @@ -36,14 +36,14 @@ target triple = "x86_64-unknown-linux-gnu" define hidden noundef i32 @_Z1fi(i32 noundef %a) local_unnamed_addr !dbg !11 { entry: - %add = add nsw i32 %a, 1, !dbg !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) - ret i32 %add, !dbg !DILocation(line: 3, scope: !11, atomGroup: 3, atomRank: 1) + %add = add nsw i32 %a, 1, !dbg !19 ; !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) + ret i32 %add, !dbg !20 ; !DILocation(line: 3, scope: !11, atomGroup: 3, atomRank: 1) } define hidden noundef i32 @_Z1gi(i32 noundef %b) local_unnamed_addr !dbg !16 { entry: - %add.i = add nsw i32 %b, 1, !dbg !DILocation(line: 2, scope: !11, inlinedAt: !18, atomGroup: 1, atomRank: 2) - ret i32 %add.i, !dbg !DILocation(line: 6, scope: !16, atomGroup: 1, atomRank: 1) + %add.i = add nsw i32 %b, 1, !dbg !21 ; !DILocation(line: 2, scope: !11, inlinedAt: !18, atomGroup: 1, atomRank: 2) + ret i32 %add.i, !dbg !22 ; !DILocation(line: 6, scope: !16, atomGroup: 1, atomRank: 1) } !llvm.dbg.cu = !{!0} @@ -55,8 +55,12 @@ entry: !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !10 = !{!"clang version 19.0.0"} -!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 4) !12 = !DISubroutineType(types: !13) !13 = !{} -!16 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 5, type: !12, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!16 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 5, type: !12, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !18 = distinct !DILocation(line: 6, scope: !16) +!19 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) +!20 = !DILocation(line: 3, scope: !11, atomGroup: 3, atomRank: 1) +!21 = !DILocation(line: 2, scope: !11, inlinedAt: !18, atomGroup: 1, atomRank: 2) +!22 = !DILocation(line: 6, scope: !16, atomGroup: 1, atomRank: 1) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir index 3b7d5850e7e83..fda74ccd35534 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir @@ -48,7 +48,7 @@ !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{!"clang version 19.0.0"} - !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) + !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 4) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 1, type: !7) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir index 3aff5e22326ec..56a180db58bfb 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir @@ -44,7 +44,7 @@ !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{!"clang version 19.0.0"} - !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) + !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 1, type: !7) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll index 14dfa8a6a9ccb..3fc29899d3996 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll @@ -77,24 +77,24 @@ target triple = "x86_64-unknown-linux-gnu" define hidden i32 @fun() local_unnamed_addr !dbg !11 { entry: - %b = load i32, ptr @a, !dbg !DILocation(line: 2, scope: !11) + %b = load i32, ptr @a, !dbg !14 ; !DILocation(line: 2, scope: !11) ;; Test A: - tail call void @f(), !dbg !DILocation(line: 3, scope: !11) + tail call void @f(), !dbg !15 ; !DILocation(line: 3, scope: !11) ;; Test B: - %x = tail call i32 @g(), !dbg !DILocation(line: 4, scope: !11, atomGroup: 1, atomRank: 2) - %y = add i32 %x, %b, !dbg !DILocation(line: 4, scope: !11, atomGroup: 1, atomRank: 1) + %x = tail call i32 @g(), !dbg !16 ; !DILocation(line: 4, scope: !11, atomGroup: 1, atomRank: 2) + %y = add i32 %x, %b, !dbg !17 ; !DILocation(line: 4, scope: !11, atomGroup: 1, atomRank: 1) ;; Test C: - store i32 1, ptr @z, !dbg !DILocation(line: 5, scope: !11, atomGroup: 2, atomRank: 2) - tail call void @f(), !dbg !DILocation(line: 5, scope: !11, atomGroup: 2, atomRank: 1) + store i32 1, ptr @z, !dbg !18 ; !DILocation(line: 5, scope: !11, atomGroup: 2, atomRank: 2) + tail call void @f(), !dbg !19 ; !DILocation(line: 5, scope: !11, atomGroup: 2, atomRank: 1) ;; Test D: - store i32 2, ptr @z, !dbg !DILocation(line: 6, scope: !11, atomGroup: 3, atomRank: 2) - tail call void @f(), !dbg !DILocation(line: 7, scope: !11, atomGroup: 3, atomRank: 1) + store i32 2, ptr @z, !dbg !20 ; !DILocation(line: 6, scope: !11, atomGroup: 3, atomRank: 2) + tail call void @f(), !dbg !21 ; !DILocation(line: 7, scope: !11, atomGroup: 3, atomRank: 1) ;; Test E: - store i32 3, ptr @z, !dbg !DILocation(line: 8, scope: !11, atomGroup: 4, atomRank: 2) - tail call void @f(), !dbg !DILocation(line: 8, scope: !11, atomGroup: 4, atomRank: 1) - store i32 4, ptr @z, !dbg !DILocation(line: 9, scope: !11, atomGroup: 5, atomRank: 1) - tail call void @f(), !dbg !DILocation(line: 9, scope: !11, atomGroup: 5, atomRank: 1) - ret i32 %y, !dbg !DILocation(line: 10, scope: !11) + store i32 3, ptr @z, !dbg !22 ; !DILocation(line: 8, scope: !11, atomGroup: 4, atomRank: 2) + tail call void @f(), !dbg !23 ; !DILocation(line: 8, scope: !11, atomGroup: 4, atomRank: 1) + store i32 4, ptr @z, !dbg !24 ; !DILocation(line: 9, scope: !11, atomGroup: 5, atomRank: 1) + tail call void @f(), !dbg !25 ; !DILocation(line: 9, scope: !11, atomGroup: 5, atomRank: 1) + ret i32 %y, !dbg !26 ; !DILocation(line: 10, scope: !11) } declare void @f() local_unnamed_addr @@ -109,6 +109,19 @@ declare i32 @g() local_unnamed_addr !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !10 = !{!"clang version 19.0.0"} -!11 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!11 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 6) !12 = !DISubroutineType(types: !13) !13 = !{} +!14 = !DILocation(line: 2, scope: !11) +!15 = !DILocation(line: 3, scope: !11) +!16 = !DILocation(line: 4, scope: !11, atomGroup: 1, atomRank: 2) +!17 = !DILocation(line: 4, scope: !11, atomGroup: 1, atomRank: 1) +!18 = !DILocation(line: 5, scope: !11, atomGroup: 2, atomRank: 2) +!19 = !DILocation(line: 5, scope: !11, atomGroup: 2, atomRank: 1) +!20 = !DILocation(line: 6, scope: !11, atomGroup: 3, atomRank: 2) +!21 = !DILocation(line: 7, scope: !11, atomGroup: 3, atomRank: 1) +!22 = !DILocation(line: 8, scope: !11, atomGroup: 4, atomRank: 2) +!23 = !DILocation(line: 8, scope: !11, atomGroup: 4, atomRank: 1) +!24 = !DILocation(line: 9, scope: !11, atomGroup: 5, atomRank: 1) +!25 = !DILocation(line: 9, scope: !11, atomGroup: 5, atomRank: 1) +!26 = !DILocation(line: 10, scope: !11) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-key-sentinel.mir b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-key-sentinel.mir new file mode 100644 index 0000000000000..b4c184333a329 --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-key-sentinel.mir @@ -0,0 +1,63 @@ +# RUN: llc %s --start-after=livedebugvalues --dwarf-use-key-instructions --filetype=obj -o - \ +# RUN: | llvm-objdump -d - --no-show-raw-insn \ +# RUN: | FileCheck %s --check-prefix=OBJ + +# RUN: llc %s --start-after=livedebugvalues --dwarf-use-key-instructions --filetype=obj -o - \ +# RUN: | llvm-dwarfdump - --debug-line \ +# RUN: | FileCheck %s --check-prefix=DBG + +# OBJ: 0000000000000000 : +# OBJ-NEXT: 0: movl $0x0, %eax +# OBJ-NEXT: 5: movl $0x1, %eax +# OBJ-NEXT: a: movl $0x2, %eax +# OBJ-NEXT: f: movl $0x3, %eax +# OBJ-NEXT: 14: retq + +# DBG: Address Line Column File ISA Discriminator OpIndex Flags +# DBG-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- +# DBG-NEXT: 0x0000000000000000 1 0 0 0 0 0 is_stmt prologue_end +# DBG-NEXT: 0x0000000000000005 2 0 0 0 0 0 is_stmt +# DBG-NEXT: 0x000000000000000f 2 0 0 0 0 0 is_stmt +# DBG-NEXT: 0x0000000000000014 2 0 0 0 0 0 is_stmt + +## (atomGroup: n, atomRank: 0) is a sentinel that means "ignore the group and +## this is always Key. Check the is_stmt for `MOV32ri 2` (0xa) floats up to +## `MOV32ri 1` (0x5), and that the subsequent sentinel and normal key +## instruction get is_stmt. As per usual, is_stmts can't float up past other +## is_stmts. + +--- | + target triple = "x86_64-unknown-linux-gnu" + + define hidden noundef i32 @f() local_unnamed_addr !dbg !5 { + entry: + ret i32 3 + } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2, !3} + !llvm.ident = !{!4} + + !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_17, file: !1, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "test.cpp", directory: "/") + !2 = !{i32 7, !"Dwarf Version", i32 5} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{!"clang version 19.0.0"} + !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) + !6 = !DISubroutineType(types: !7) + !7 = !{} + +... +--- +name: f +alignment: 16 +body: | + bb.0.entry: + + $eax = MOV32ri 0, debug-location !DILocation(line: 1, scope: !5) + $eax = MOV32ri 1, debug-location !DILocation(line: 2, scope: !5) + $eax = MOV32ri 2, debug-location !DILocation(line: 2, scope: !5, atomGroup: 1, atomRank: 0) + $eax = MOV32ri 3, debug-location !DILocation(line: 2, scope: !5, atomGroup: 1, atomRank: 0) + RET64 $eax, debug-location !DILocation(line: 2, scope: !5, atomGroup: 1, atomRank: 1) + +... diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll index cd840ecce07f5..20502368e69dd 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll +++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll @@ -35,18 +35,18 @@ target triple = "x86_64-unknown-linux-gnu" define hidden noundef i32 @_Z1fPiii(ptr %a, i32 %b, i32 %c, i1 %cond) local_unnamed_addr !dbg !11 { entry: - tail call void @_Z12prologue_endv(), !dbg !DILocation(line: 1, scope: !11) - %add = add nsw i32 %c, %b, !dbg !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) - br i1 %cond, label %bb1, label %bb2, !dbg !DILocation(line: 1, scope: !11) + tail call void @_Z12prologue_endv(), !dbg !14 ; !DILocation(line: 1, scope: !11) + %add = add nsw i32 %c, %b, !dbg !15 ; !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) + br i1 %cond, label %bb1, label %bb2, !dbg !16 ; !DILocation(line: 1, scope: !11) bb1: - store i32 %add, ptr %a, align 4, !dbg !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) - ret i32 %add, !dbg !DILocation(line: 1, scope: !11) + store i32 %add, ptr %a, align 4, !dbg !17 ; !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) + ret i32 %add, !dbg !18 ; !DILocation(line: 1, scope: !11) bb2: - store i32 %b, ptr %a, align 4, !dbg !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) - store i32 %c, ptr %a, align 4, !dbg !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) - ret i32 %add, !dbg !DILocation(line: 1, scope: !11) + store i32 %b, ptr %a, align 4, !dbg !19 ; !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) + store i32 %c, ptr %a, align 4, !dbg !20 ; !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) + ret i32 %add, !dbg !21 ; !DILocation(line: 1, scope: !11) } declare void @_Z12prologue_endv() local_unnamed_addr #1 @@ -60,6 +60,14 @@ declare void @_Z12prologue_endv() local_unnamed_addr #1 !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !10 = !{!"clang version 19.0.0"} -!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 3) !12 = !DISubroutineType(types: !13) !13 = !{} +!14 = !DILocation(line: 1, scope: !11) +!15 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2) +!16 = !DILocation(line: 1, scope: !11) +!17 = !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) +!18 = !DILocation(line: 1, scope: !11) +!19 = !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) +!20 = !DILocation(line: 3, scope: !11, atomGroup: 1, atomRank: 1) +!21 = !DILocation(line: 1, scope: !11) diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir b/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir index 45cc23831412c..65ac199fd96ef 100644 --- a/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir +++ b/llvm/test/DebugInfo/KeyInstructions/X86/parse.mir @@ -2,6 +2,7 @@ ## Check the MIR parser understands atomGroup and atomRank. +# CHECK: distinct !DISubprogram(name: "p", {{.*}}nextAtomGroup: 2) # CHECK: RET64 $eax, debug-location !DILocation(line: 2, scope: ![[#]], atomGroup: 1, atomRank: 2) --- | @@ -22,7 +23,7 @@ !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{!"clang version 19.0.0"} - !5 = distinct !DISubprogram(name: "p", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) + !5 = distinct !DISubprogram(name: "p", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, nextAtomGroup: 2) !6 = !DISubroutineType(types: !7) !7 = !{} diff --git a/llvm/test/DebugInfo/KeyInstructions/debugify.ll b/llvm/test/DebugInfo/KeyInstructions/debugify.ll index 881375873f324..3cfcb6f1d5694 100644 --- a/llvm/test/DebugInfo/KeyInstructions/debugify.ll +++ b/llvm/test/DebugInfo/KeyInstructions/debugify.ll @@ -38,9 +38,12 @@ define i32 @boom() { ret i32 %retval } +; CHECK: distinct !DISubprogram(name: "foo", {{.*}}nextAtomGroup: 2) ; CHECK-DAG: ![[RET1]] = !DILocation(line: 1, {{.*}}, atomGroup: 1, atomRank: 1 +; CHECK: distinct !DISubprogram(name: "bar", {{.*}}nextAtomGroup: 5) ; CHECK-DAG: ![[CALL1]] = !DILocation(line: 2, {{.*}}, atomGroup: 2, atomRank: 1 ; CHECK-DAG: ![[ADD1]] = !DILocation(line: 3, {{.*}}, atomGroup: 3, atomRank: 1 ; CHECK-DAG: ![[RET2]] = !DILocation(line: 4, {{.*}}, atomGroup: 4, atomRank: 1 +; CHECK: distinct !DISubprogram(name: "boom", {{.*}}nextAtomGroup: 7) ; CHECK-DAG: ![[musttail]] = !DILocation(line: 5, {{.*}}, atomGroup: 5, atomRank: 1 ; CHECK-DAG: ![[musttailRes]] = !DILocation(line: 6, {{.*}}, atomGroup: 6, atomRank: 1 diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp index cb1a56a26f063..ae4887af570a3 100644 --- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp +++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp @@ -154,7 +154,7 @@ TEST(BasicBlockDbgInfoTest, DropSourceAtomOnSplit) { std::unique_ptr M = parseIR(C, R"---( define dso_local void @func() !dbg !10 { %1 = alloca i32, align 4 - ret void, !dbg !DILocation(line: 3, column: 2, scope: !10, atomGroup: 1, atomRank: 1) + ret void, !dbg !16 } !llvm.dbg.cu = !{!0} @@ -164,12 +164,13 @@ TEST(BasicBlockDbgInfoTest, DropSourceAtomOnSplit) { !1 = !DIFile(filename: "dummy", directory: "dummy") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} - !10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !13) + !10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !13, nextAtomGroup: 2) !11 = !DISubroutineType(types: !12) !12 = !{null} !13 = !{} !14 = !DILocalVariable(name: "a", scope: !10, file: !1, line: 2, type: !15) !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) + !16 = !DILocation(line: 3, column: 2, scope: !10, atomGroup: 1, atomRank: 1) )---"); ASSERT_TRUE(M); diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index df415602cef59..0bd0c3b3e3443 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -92,9 +92,10 @@ class MetadataTest : public testing::Test { getNode(nullptr)); } DISubprogram *getSubprogram(DIFile *F = nullptr) { - return DISubprogram::getDistinct(Context, nullptr, "", "", F, 0, nullptr, 0, - nullptr, 0, 0, DINode::FlagZero, - DISubprogram::SPFlagZero, nullptr); + return DISubprogram::getDistinct( + Context, nullptr, "", "", F, 0, nullptr, 0, nullptr, 0, 0, + DINode::FlagZero, DISubprogram::SPFlagDefinition, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "", /*UseKeyInstructions*/ true); } DIFile *getFile() { return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); @@ -1592,15 +1593,19 @@ TEST_F(DILocationTest, Merge) { // Partially equal inlined-at chain but different atoms. Generate a new atom // group (if either have a group number). This configuration seems unlikely - // to occur as line numbers must match, but isn't impossible. + // to occur as line numbers must match, but isn't impossible. AtomRank=0 is + // a sentinel that indicates the instruction is in its own undefined atom + // group. { - // Reset global counter to ensure EXPECT numbers line up. - Context.pImpl->NextAtomGroup = 1; // x1 -> y2 -> z4 // y3 -> z4 auto *FX = getSubprogram(); auto *FY = getSubprogram(); auto *FZ = getSubprogram(); + EXPECT_EQ(FX->getNextDILocationAtomGroup(), 1); + EXPECT_EQ(FY->getNextDILocationAtomGroup(), 1); + EXPECT_EQ(FZ->getNextDILocationAtomGroup(), 1); + auto *Z4 = DILocation::get(Context, 1, 4, FZ); auto *Y3IntoZ4 = DILocation::get(Context, 1, 3, FY, Z4, false, /*AtomGroup*/ 1, /*AtomRank*/ 1); @@ -1609,7 +1614,7 @@ TEST_F(DILocationTest, Merge) { auto *M = DILocation::getMergedLocation(X1IntoY2, Y3IntoZ4); EXPECT_EQ(M->getScope(), FY); EXPECT_EQ(M->getInlinedAt()->getScope(), FZ); - EXPECT_ATOM(M, /*AtomGroup*/ 2u, /*AtomRank*/ 1u); + EXPECT_ATOM(M, /*AtomGroup*/ 1u, /*AtomRank*/ 0u); // This swapped merge will produce a new atom group too. M = DILocation::getMergedLocation(Y3IntoZ4, X1IntoY2); @@ -1618,9 +1623,9 @@ TEST_F(DILocationTest, Merge) { auto *X1IntoY2SameAtom = DILocation::get(Context, 1, 1, FX, Y2IntoZ4, false, /*AtomGroup*/ 1, /*AtomRank*/ 1); M = DILocation::getMergedLocation(X1IntoY2SameAtom, Y3IntoZ4); - EXPECT_ATOM(M, /*AtomGroup*/ 4u, /*AtomRank*/ 1u); + EXPECT_ATOM(M, /*AtomGroup*/ 1u, /*AtomRank*/ 0u); M = DILocation::getMergedLocation(Y3IntoZ4, X1IntoY2SameAtom); - EXPECT_ATOM(M, /*AtomGroup*/ 5u, /*AtomRank*/ 1u); + EXPECT_ATOM(M, /*AtomGroup*/ 1u, /*AtomRank*/ 0u); } #undef EXPECT_ATOM } @@ -1748,11 +1753,11 @@ TEST_F(DILocationTest, discriminatorSpecialCases) { } TEST_F(DILocationTest, KeyInstructions) { - Context.pImpl->NextAtomGroup = 1; + DISubprogram *SP = getSubprogram(); + uint32_t NextGroup = SP->getNextDILocationAtomGroup(); + EXPECT_EQ(NextGroup, 1u); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 1u); - DILocation *A1 = - DILocation::get(Context, 1, 0, getSubprogram(), nullptr, false, 1, 2); + DILocation *A1 = DILocation::get(Context, 1, 0, SP, nullptr, false, 1, 2); // The group is only applied to the DILocation if we've built LLVM with // EXPERIMENTAL_KEY_INSTRUCTIONS. #ifdef EXPERIMENTAL_KEY_INSTRUCTIONS @@ -1764,26 +1769,26 @@ TEST_F(DILocationTest, KeyInstructions) { #endif // Group number 1 has been "used" so next available is 2. - EXPECT_EQ(Context.pImpl->NextAtomGroup, 2u); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 2u); // Set a group number higher than current + 1, then check the waterline. - DILocation::get(Context, 2, 0, getSubprogram(), nullptr, false, 5, 1); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u); + DILocation::get(Context, 2, 0, SP, nullptr, false, 5, 1); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 6u); // The waterline should be unchanged (group <= next). - DILocation::get(Context, 3, 0, getSubprogram(), nullptr, false, 4, 1); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u); - DILocation::get(Context, 3, 0, getSubprogram(), nullptr, false, 5, 1); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u); + DILocation::get(Context, 3, 0, SP, nullptr, false, 4, 1); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 6u); + DILocation::get(Context, 3, 0, SP, nullptr, false, 5, 1); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 6u); // Check the waterline gets incremented by 1. - EXPECT_EQ(Context.incNextDILocationAtomGroup(), 6u); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 7u); + EXPECT_EQ(SP->incNextDILocationAtomGroup(), 6u); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 7u); - Context.updateDILocationAtomGroupWaterline(8); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 8u); - Context.updateDILocationAtomGroupWaterline(7); - EXPECT_EQ(Context.pImpl->NextAtomGroup, 8u); + SP->updateDILocationAtomGroupWaterline(8); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 8u); + SP->updateDILocationAtomGroupWaterline(7); + EXPECT_EQ(SP->getNextDILocationAtomGroup(), 8u); } typedef MetadataTest GenericDINodeTest; diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp index 09b32bf09df0e..077ec0b2168dd 100644 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -1223,7 +1223,7 @@ TEST_F(CloneInstruction, cloneKeyInstructions) { ValueToValueMapTy VM; // Store1 and Store2 have the same atomGroup number, but have different // inlining scopes, so only Store1 should change group. - mapAtomInstance(Store1->getDebugLoc(), VM); + mapAtomInstance(F->getSubprogram(), Store1->getDebugLoc(), VM); for (Instruction &I : *BB) RemapSourceAtom(&I, VM); EXPECT_ATOM(Store1, 3); @@ -1233,7 +1233,7 @@ TEST_F(CloneInstruction, cloneKeyInstructions) { VM.clear(); // Store2 and Store3 have the same group number; both should get remapped. - mapAtomInstance(Store2->getDebugLoc(), VM); + mapAtomInstance(F->getSubprogram(), Store2->getDebugLoc(), VM); for (Instruction &I : *BB) RemapSourceAtom(&I, VM); EXPECT_ATOM(Store1, 3); @@ -1243,8 +1243,8 @@ TEST_F(CloneInstruction, cloneKeyInstructions) { VM.clear(); // Cloning BB with MapAtoms=false should clone the atom numbers. - BasicBlock *BB2 = - CloneBasicBlock(BB, VM, "", nullptr, nullptr, /*MapAtoms*/ false); + BasicBlock *BB2 = CloneBasicBlock(BB, VM, F->getSubprogram(), "", nullptr, + nullptr, /*MapAtoms*/ false); for (Instruction &I : *BB2) RemapSourceAtom(&I, VM); Store1 = &*BB2->begin(); @@ -1259,8 +1259,8 @@ TEST_F(CloneInstruction, cloneKeyInstructions) { delete BB2; // Cloning BB with MapAtoms=true should map the atom numbers. - BasicBlock *BB3 = - CloneBasicBlock(BB, VM, "", nullptr, nullptr, /*MapAtoms*/ true); + BasicBlock *BB3 = CloneBasicBlock(BB, VM, F->getSubprogram(), "", nullptr, + nullptr, /*MapAtoms*/ true); for (Instruction &I : *BB3) RemapSourceAtom(&I, VM); Store1 = &*BB3->begin();