From eab6e94f912d014e6f19e1737ef81e36e4601faf Mon Sep 17 00:00:00 2001 From: Chih-Ping Chen Date: Wed, 6 Apr 2022 08:22:49 -0400 Subject: [PATCH] [DebugInfo] Add a TargetFuncName field in DISubprogram for specifying DW_AT_trampoline as a string. Also update the signature of DIBuilder::createFunction to reflect this addition. Differential Revision: https://reviews.llvm.org/D123697 --- llvm/docs/SourceLevelDebugging.rst | 23 +++++++- llvm/include/llvm/IR/DIBuilder.h | 5 +- llvm/include/llvm/IR/DebugInfoMetadata.h | 26 +++++--- llvm/lib/AsmParser/LLParser.cpp | 6 +- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 6 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 1 + llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 3 + llvm/lib/IR/AsmWriter.cpp | 1 + llvm/lib/IR/DIBuilder.cpp | 5 +- llvm/lib/IR/DebugInfoMetadata.cpp | 24 +++++--- llvm/lib/IR/LLVMContextImpl.h | 12 ++-- llvm/test/Assembler/disubprogram-targetfuncname.ll | 35 +++++++++++ llvm/test/DebugInfo/X86/disubprogram-trampoline.ll | 39 ++++++++++++ llvm/unittests/IR/MetadataTest.cpp | 69 +++++++++++++++------- 14 files changed, 206 insertions(+), 49 deletions(-) create mode 100644 llvm/test/Assembler/disubprogram-targetfuncname.ll create mode 100644 llvm/test/DebugInfo/X86/disubprogram-trampoline.ll diff --git a/llvm/docs/SourceLevelDebugging.rst b/llvm/docs/SourceLevelDebugging.rst index ae26268..a9ce600 100644 --- a/llvm/docs/SourceLevelDebugging.rst +++ b/llvm/docs/SourceLevelDebugging.rst @@ -1086,8 +1086,8 @@ a Fortran front-end would generate the following descriptors: !DILocalVariable(name: "string", arg: 1, scope: !10, file: !3, line: 4, type: !15) !DIStringType(name: "character(*)!2", stringLength: !16, stringLengthExpression: !DIExpression(), size: 32) - -A fortran deferred-length character can also contain the information of raw storage of the characters in addition to the length of the string. This information is encoded in the stringLocationExpression field. Based on this information, DW_AT_data_location attribute is emitted in a DW_TAG_string_type debug info. + +A fortran deferred-length character can also contain the information of raw storage of the characters in addition to the length of the string. This information is encoded in the stringLocationExpression field. Based on this information, DW_AT_data_location attribute is emitted in a DW_TAG_string_type debug info. !DIStringType(name: "character(*)!2", stringLengthExpression: !DIExpression(), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), size: 32) @@ -1105,6 +1105,25 @@ and this will materialize in DWARF tags as: ... DW_AT_artificial (true) +A Fortran front-end may need to generate a *trampoline* function to call a +function defined in a different compilation unit. In this case, the front-end +can emit the following descriptor for the trampoline function: + +.. code-block:: text + + !DISubprogram(name: "sub1_.t0p", linkageName: "sub1_.t0p", scope: !4, file: !4, type: !5, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !7, retainedNodes: !24, targetFuncName: "sub1_") + +The targetFuncName field is the name of the function that the trampoline +calls. This descriptor results in the following DWARF tag: + +.. code-block:: text + + DW_TAG_subprogram + ... + DW_AT_linkage_name ("sub1_.t0p") + DW_AT_name ("sub1_.t0p") + DW_AT_trampoline ("sub1_") + Debugging information format ============================ diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index c635659..9afa715 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -752,6 +752,8 @@ namespace llvm { /// \param TParams Function template parameters. /// \param ThrownTypes Exception types this function may throw. /// \param Annotations Attribute Annotations. + /// \param TargetFuncName The name of the target function if this is + /// a trampoline. DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, @@ -760,7 +762,8 @@ namespace llvm { DITemplateParameterArray TParams = nullptr, DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr, - DINodeArray Annotations = nullptr); + DINodeArray Annotations = nullptr, + StringRef TargetFuncName = ""); /// Identical to createFunction, /// except that the resulting DbgNode is meant to be RAUWed. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index c6ef69e..bc916fe 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1851,13 +1851,14 @@ private: DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, DINodeArray RetainedNodes, DITypeArray ThrownTypes, - DINodeArray Annotations, StorageType Storage, - bool ShouldCreate = true) { + DINodeArray Annotations, StringRef TargetFuncName, + 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); } static DISubprogram * @@ -1867,7 +1868,8 @@ private: int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, - StorageType Storage, bool ShouldCreate = true); + MDString *TargetFuncName, StorageType Storage, + bool ShouldCreate = true); TempDISubprogram cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), @@ -1875,7 +1877,8 @@ private: getContainingType(), getVirtualIndex(), getThisAdjustment(), getFlags(), getSPFlags(), getUnit(), getTemplateParams(), getDeclaration(), - getRetainedNodes(), getThrownTypes(), getAnnotations()); + getRetainedNodes(), getThrownTypes(), getAnnotations(), + getTargetFuncName()); } public: @@ -1887,10 +1890,11 @@ public: DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr, - DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr), + DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr, + StringRef TargetFuncName = ""), (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes, Annotations)) + Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) DEFINE_MDNODE_GET( DISubprogram, @@ -1900,10 +1904,10 @@ public: DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr, - Metadata *Annotations = nullptr), + Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr), (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes, Annotations)) + Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) TempDISubprogram clone() const { return cloneImpl(); } @@ -2012,6 +2016,9 @@ public: DINodeArray getAnnotations() const { return cast_or_null(getRawAnnotations()); } + StringRef getTargetFuncName() const { + return (getRawTargetFuncName()) ? getStringOperand(12) : StringRef(); + } Metadata *getRawScope() const { return getOperand(1); } MDString *getRawName() const { return getOperandAs(2); } @@ -2032,6 +2039,9 @@ public: Metadata *getRawAnnotations() const { return getNumOperands() > 11 ? getOperandAs(11) : nullptr; } + MDString *getRawTargetFuncName() const { + return getNumOperands() > 12 ? getOperandAs(12) : nullptr; + } void replaceRawLinkageName(MDString *LinkageName) { replaceOperandWith(3, LinkageName); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 04e6514..c723d71 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4822,7 +4822,8 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { OPTIONAL(declaration, MDField, ); \ OPTIONAL(retainedNodes, MDField, ); \ OPTIONAL(thrownTypes, MDField, ); \ - OPTIONAL(annotations, MDField, ); + OPTIONAL(annotations, MDField, ); \ + OPTIONAL(targetFuncName, MDStringField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4841,7 +4842,8 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, 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)); + declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val, + targetFuncName.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 420df9b4..f5166a7 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1698,6 +1698,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( bool HasThisAdj = true; bool HasThrownTypes = true; bool HasAnnotations = false; + bool HasTargetFuncName = false; unsigned OffsetA = 0; unsigned OffsetB = 0; if (!HasSPFlags) { @@ -1711,6 +1712,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( HasThrownTypes = Record.size() >= 21; } else { HasAnnotations = Record.size() >= 19; + HasTargetFuncName = Record.size() >= 20; } Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]); DISubprogram *SP = GET_OR_DISTINCT( @@ -1735,7 +1737,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( HasThrownTypes ? getMDOrNull(Record[17 + OffsetB]) : nullptr, // thrownTypes HasAnnotations ? getMDOrNull(Record[18 + OffsetB]) - : nullptr // annotations + : nullptr, // annotations + HasTargetFuncName ? getMDString(Record[19 + OffsetB]) + : nullptr // targetFuncName )); MetadataList.assignValue(SP, NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 79c7685..84f60f4 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1822,6 +1822,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N, Record.push_back(N->getThisAdjustment()); Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); + Record.push_back(VE.getMetadataOrNullID(N->getRawTargetFuncName())); Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index c2fd61e..db3dc68 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1344,6 +1344,9 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, if (SP->isRecursive()) addFlag(SPDie, dwarf::DW_AT_recursive); + if (!SP->getTargetFuncName().empty()) + addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName()); + if (DD->getDwarfVersion() >= 5 && SP->isDeleted()) addFlag(SPDie, dwarf::DW_AT_deleted); } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 4306330..ae1ed2d 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2131,6 +2131,7 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, Printer.printMetadata("retainedNodes", N->getRawRetainedNodes()); Printer.printMetadata("thrownTypes", N->getRawThrownTypes()); Printer.printMetadata("annotations", N->getRawAnnotations()); + Printer.printString("targetFuncName", N->getTargetFuncName()); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index c2dd5fa..34ffc94 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -846,14 +846,15 @@ DISubprogram *DIBuilder::createFunction( unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams, DISubprogram *Decl, - DITypeArray ThrownTypes, DINodeArray Annotations) { + DITypeArray ThrownTypes, DINodeArray Annotations, + StringRef TargetFuncName) { 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, MDTuple::getTemporary(VMContext, None).release(), ThrownTypes, - Annotations); + Annotations, TargetFuncName); if (IsDefinition) AllSubprograms.push_back(Node); diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 033980d..b412fb8 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -978,27 +978,33 @@ DISubprogram *DISubprogram::getImpl( unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, - Metadata *ThrownTypes, Metadata *Annotations, StorageType Storage, - bool ShouldCreate) { + Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); + assert(isCanonical(TargetFuncName) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DISubprogram, (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes, Annotations)); - SmallVector Ops = { + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); + SmallVector Ops = { File, Scope, Name, LinkageName, Type, Unit, Declaration, RetainedNodes, - ContainingType, TemplateParams, ThrownTypes, Annotations}; - if (!Annotations) { + ContainingType, TemplateParams, ThrownTypes, Annotations, + TargetFuncName}; + if (!TargetFuncName) { Ops.pop_back(); - if (!ThrownTypes) { + if (!Annotations) { Ops.pop_back(); - if (!TemplateParams) { + if (!ThrownTypes) { Ops.pop_back(); - if (!ContainingType) + if (!TemplateParams) { Ops.pop_back(); + if (!ContainingType) + Ops.pop_back(); + } } } } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 50fca3a..730f64b 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -709,6 +709,7 @@ template <> struct MDNodeKeyImpl { Metadata *RetainedNodes; Metadata *ThrownTypes; Metadata *Annotations; + MDString *TargetFuncName; MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, @@ -716,14 +717,15 @@ template <> struct MDNodeKeyImpl { unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, - Metadata *ThrownTypes, Metadata *Annotations) + Metadata *ThrownTypes, Metadata *Annotations, + MDString *TargetFuncName) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), ScopeLine(ScopeLine), ContainingType(ContainingType), VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags), Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes), - Annotations(Annotations) {} + Annotations(Annotations), TargetFuncName(TargetFuncName) {} MDNodeKeyImpl(const DISubprogram *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), @@ -736,7 +738,8 @@ template <> struct MDNodeKeyImpl { Declaration(N->getRawDeclaration()), RetainedNodes(N->getRawRetainedNodes()), ThrownTypes(N->getRawThrownTypes()), - Annotations(N->getRawAnnotations()) {} + Annotations(N->getRawAnnotations()), + TargetFuncName(N->getRawTargetFuncName()) {} bool isKeyOf(const DISubprogram *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && @@ -752,7 +755,8 @@ template <> struct MDNodeKeyImpl { Declaration == RHS->getRawDeclaration() && RetainedNodes == RHS->getRawRetainedNodes() && ThrownTypes == RHS->getRawThrownTypes() && - Annotations == RHS->getRawAnnotations(); + Annotations == RHS->getRawAnnotations() && + TargetFuncName == RHS->getRawTargetFuncName(); } bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; } diff --git a/llvm/test/Assembler/disubprogram-targetfuncname.ll b/llvm/test/Assembler/disubprogram-targetfuncname.ll new file mode 100644 index 0000000..a435001 --- /dev/null +++ b/llvm/test/Assembler/disubprogram-targetfuncname.ll @@ -0,0 +1,35 @@ +; This test verifies that the targetFuncName attribute in a DISubprogram +; is assembled/disassembled correctly. +; +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; +; CHECK: !DISubprogram(name: "sub1_.t0p", linkageName: "sub1_.t0p",{{.*}}, targetFuncName: "sub1_") +; +; ModuleID = 'main.f' +source_filename = "main.f" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define internal void @sub1_.t0p(float* %arg0) #0 !dbg !23 { +wrap_start11: + call void (...) @sub1_(float* %arg0), !dbg !25 + ret void, !dbg !25 +} + +declare void @sub1_(...) + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "intel-lang"="fortran" "loopopt-pipeline"="light" "min-legal-vector-width"="0" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } + +!llvm.module.flags = !{!12, !13} +!llvm.dbg.cu = !{!7} +!omp_offload.info = !{} + +!4 = !DIFile(filename: "main.f", directory: "/dir") +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !4, producer: "Intel(R) Fortran 22.0-1483", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 2, !"Dwarf Version", i32 4} +!23 = distinct !DISubprogram(name: "sub1_.t0p", linkageName: "sub1_.t0p", scope: !4, file: !4, type: !5, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !7, retainedNodes: !24, targetFuncName: "sub1_") +!24 = !{} +!25 = !DILocation(line: 0, scope: !23) diff --git a/llvm/test/DebugInfo/X86/disubprogram-trampoline.ll b/llvm/test/DebugInfo/X86/disubprogram-trampoline.ll new file mode 100644 index 0000000..05a1461 --- /dev/null +++ b/llvm/test/DebugInfo/X86/disubprogram-trampoline.ll @@ -0,0 +1,39 @@ +; This test verifies that the proper DWARF debug info is emitted +; for a trampoline function. +; +; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s +; +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_linkage_name ("sub1_.t0p") +; CHECK-NEXT: DW_AT_name ("sub1_.t0p") +; CHECK-NEXT: DW_AT_trampoline ("sub1_") +; +; ModuleID = 'main.f' +source_filename = "main.f" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define internal void @sub1_.t0p(float* %arg0) #0 !dbg !23 { +wrap_start11: + call void (...) @sub1_(float* %arg0), !dbg !25 + ret void, !dbg !25 +} + +declare void @sub1_(...) + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "intel-lang"="fortran" "loopopt-pipeline"="light" "min-legal-vector-width"="0" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } + +!llvm.module.flags = !{!12, !13} +!llvm.dbg.cu = !{!7} +!omp_offload.info = !{} + +!4 = !DIFile(filename: "main.f", directory: "/dir") +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !4, producer: "Intel(R) Fortran 22.0-1483", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 2, !"Dwarf Version", i32 4} +!23 = distinct !DISubprogram(name: "sub1_.t0p", linkageName: "sub1_.t0p", scope: !4, file: !4, type: !5, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !7, retainedNodes: !24, targetFuncName: "sub1_") +!24 = !{} +!25 = !DILocation(line: 0, scope: !23) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index f870ec8..4297e32 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2283,6 +2283,8 @@ TEST_F(DISubprogramTest, get) { DISubprogram *Declaration = getSubprogram(); MDTuple *RetainedNodes = getTuple(); MDTuple *ThrownTypes = getTuple(); + MDTuple *Annotations = getTuple(); + StringRef TargetFuncName = "target"; DICompileUnit *Unit = getUnit(); DISubprogram::DISPFlags SPFlags = static_cast(Virtuality); @@ -2293,7 +2295,8 @@ TEST_F(DISubprogramTest, get) { auto *N = DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes); + TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations, + TargetFuncName); EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -2316,101 +2319,127 @@ TEST_F(DISubprogramTest, get) { EXPECT_EQ(Declaration, N->getDeclaration()); EXPECT_EQ(RetainedNodes, N->getRetainedNodes().get()); EXPECT_EQ(ThrownTypes, N->getThrownTypes().get()); + EXPECT_EQ(Annotations, N->getAnnotations().get()); + EXPECT_EQ(TargetFuncName, N->getTargetFuncName()); EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes)); + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes)); + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, getSubroutineType(), ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + TemplateParams, Declaration, RetainedNodes, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + TemplateParams, Declaration, RetainedNodes, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine + 1, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, getCompositeType(), VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + TemplateParams, Declaration, RetainedNodes, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex + 1, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + RetainedNodes, ThrownTypes, Annotations, + TargetFuncName)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + TemplateParams, Declaration, RetainedNodes, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, nullptr, TemplateParams, Declaration, RetainedNodes, - ThrownTypes)); + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, getTuple(), - Declaration, RetainedNodes, ThrownTypes)); + Declaration, RetainedNodes, ThrownTypes, + Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, getSubprogram(), RetainedNodes, - ThrownTypes)); + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, - TemplateParams, Declaration, getTuple())); + TemplateParams, Declaration, getTuple(), + ThrownTypes, Annotations, TargetFuncName)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, - getTuple())); + getTuple(), Annotations, TargetFuncName)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, + ThrownTypes, getTuple(), TargetFuncName)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, + ThrownTypes, Annotations, "other")); TempDISubprogram Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); -- 2.7.4