diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -641,7 +641,8 @@ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool IsLocalToUnit, bool isDefined = true, DIExpression *Expr = nullptr, MDNode *Decl = nullptr, - MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0); + MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0, + DINodeArray Annotations = nullptr); /// Identical to createGlobalVariable /// except that the resulting DbgNode is temporary and meant to be RAUWed. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2962,25 +2962,28 @@ StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, - uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) { + uint32_t AlignInBits, DINodeArray Annotations, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - cast_or_null(TemplateParams), AlignInBits, Storage, - ShouldCreate); + cast_or_null(TemplateParams), AlignInBits, + Annotations.get(), Storage, ShouldCreate); } static DIGlobalVariable * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true); + uint32_t AlignInBits, Metadata *Annotations, StorageType Storage, + bool ShouldCreate = true); TempDIGlobalVariable cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getStaticDataMemberDeclaration(), - getTemplateParams(), getAlignInBits()); + getTemplateParams(), getAlignInBits(), + getAnnotations()); } public: @@ -2989,19 +2992,21 @@ DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, - MDTuple *TemplateParams, uint32_t AlignInBits), + MDTuple *TemplateParams, uint32_t AlignInBits, + DINodeArray Annotations), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, TemplateParams, - AlignInBits)) + AlignInBits, Annotations)) DEFINE_MDNODE_GET(DIGlobalVariable, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, - Metadata *TemplateParams, uint32_t AlignInBits), + Metadata *TemplateParams, uint32_t AlignInBits, + Metadata *Annotations), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, TemplateParams, - AlignInBits)) + AlignInBits, Annotations)) TempDIGlobalVariable clone() const { return cloneImpl(); } @@ -3012,11 +3017,15 @@ DIDerivedType *getStaticDataMemberDeclaration() const { return cast_or_null(getRawStaticDataMemberDeclaration()); } + DINodeArray getAnnotations() const { + return cast_or_null(getRawAnnotations()); + } MDString *getRawLinkageName() const { return getOperandAs(5); } Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); } Metadata *getRawTemplateParams() const { return getOperand(7); } MDTuple *getTemplateParams() const { return getOperandAs(7); } + Metadata *getRawAnnotations() const { return getOperand(8); } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DIGlobalVariableKind; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4946,7 +4946,8 @@ OPTIONAL(isDefinition, MDBoolField, (true)); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ - OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); + OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(annotations, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4954,7 +4955,8 @@ GET_OR_DISTINCT(DIGlobalVariable, (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, type.Val, isLocal.Val, isDefinition.Val, - declaration.Val, templateParams.Val, align.Val)); + declaration.Val, templateParams.Val, align.Val, + annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1873,13 +1873,18 @@ unsigned Version = Record[0] >> 1; if (Version == 2) { + Metadata *Annotations = nullptr; + if (Record.size() > 12) + Annotations = getMDOrNull(Record[12]); + MetadataList.assignValue( GET_OR_DISTINCT( DIGlobalVariable, (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11])), + getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11], + Annotations)), NextMetadataNo); NextMetadataNo++; @@ -1892,7 +1897,8 @@ getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, Record[11])), + getMDOrNull(Record[10]), nullptr, Record[11], + nullptr)), NextMetadataNo); NextMetadataNo++; @@ -1925,7 +1931,7 @@ (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, AlignInBits)); + getMDOrNull(Record[10]), nullptr, AlignInBits, nullptr)); DIGlobalVariableExpression *DGVE = nullptr; if (Attach || Expr) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1962,6 +1962,7 @@ Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); Record.push_back(N->getAlignInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2299,6 +2299,7 @@ Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printInt("align", N->getAlignInBits()); + Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -705,13 +705,14 @@ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined, DIExpression *Expr, - MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits) { + MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits, + DINodeArray Annotations) { checkGlobalVariableScope(Context); auto *GV = DIGlobalVariable::getDistinct( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, isDefined, cast_or_null(Decl), - TemplateParams, AlignInBits); + TemplateParams, AlignInBits, Annotations); if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); @@ -728,7 +729,8 @@ return DIGlobalVariable::getTemporary( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, false, - cast_or_null(Decl), TemplateParams, AlignInBits) + cast_or_null(Decl), TemplateParams, AlignInBits, + nullptr) .release(); } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -984,13 +984,15 @@ Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, uint32_t AlignInBits, - StorageType Storage, bool ShouldCreate) { + Metadata *Annotations, StorageType Storage, + bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - TemplateParams, AlignInBits)); + TemplateParams, AlignInBits, + Annotations)); Metadata *Ops[] = {Scope, Name, File, @@ -998,7 +1000,8 @@ Name, LinkageName, StaticDataMemberDeclaration, - TemplateParams}; + TemplateParams, + Annotations}; DEFINE_GETIMPL_STORE(DIGlobalVariable, (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -984,17 +984,19 @@ Metadata *StaticDataMemberDeclaration; Metadata *TemplateParams; uint32_t AlignInBits; + Metadata *Annotations; MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits) + uint32_t AlignInBits, Metadata *Annotations) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), StaticDataMemberDeclaration(StaticDataMemberDeclaration), - TemplateParams(TemplateParams), AlignInBits(AlignInBits) {} + TemplateParams(TemplateParams), AlignInBits(AlignInBits), + Annotations(Annotations) {} MDNodeKeyImpl(const DIGlobalVariable *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), @@ -1002,7 +1004,7 @@ IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), TemplateParams(N->getRawTemplateParams()), - AlignInBits(N->getAlignInBits()) {} + AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIGlobalVariable *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && @@ -1013,7 +1015,8 @@ StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && TemplateParams == RHS->getRawTemplateParams() && - AlignInBits == RHS->getAlignInBits(); + AlignInBits == RHS->getAlignInBits() && + Annotations == RHS->getRawAnnotations(); } unsigned getHashValue() const { @@ -1026,7 +1029,7 @@ // TODO: make hashing work fine with such situations return hash_combine(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, /* AlignInBits, */ - StaticDataMemberDeclaration); + StaticDataMemberDeclaration, Annotations); } }; diff --git a/llvm/test/Bitcode/attr-btf_tag-diglobalvariable.ll b/llvm/test/Bitcode/attr-btf_tag-diglobalvariable.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/attr-btf_tag-diglobalvariable.ll @@ -0,0 +1,37 @@ +; REQUIRES: x86-registered-target +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +%struct.t1 = type { i32 } + +@g1 = dso_local global %struct.t1 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!13, !14, !15, !16, !17} +!llvm.ident = !{!18} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "g1", scope: !2, file: !3, line: 7, type: !6, isLocal: false, isDefinition: true, annotations: !10) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 47af5574a87dc298b5c6c36ff6a969c8c77c8499)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/work/tests/llvm/btf_tag") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 4, size: 32, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !3, line: 5, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{!11, !12} +!11 = !{!"btf_tag", !"tag1"} +!12 = !{!"btf_tag", !"tag2"} + +; CHECK: distinct !DIGlobalVariable(name: "g1" +; CHECK-SAME: annotations: ![[ANNOT:[0-9]+]] +; CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]} +; CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"} +; CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"} + +!13 = !{i32 7, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{i32 7, !"uwtable", i32 1} +!17 = !{i32 7, !"frame-pointer", i32 2} +!18 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 47af5574a87dc298b5c6c36ff6a969c8c77c8499)"} diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2574,7 +2574,8 @@ auto *N = DIGlobalVariable::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, + nullptr); EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -2591,52 +2592,54 @@ EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get( Context, getSubprogram(), Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, templateParams, AlignInBits)); + StaticDataMemberDeclaration, templateParams, AlignInBits, + nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(), Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, getDerivedType(), IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, cast(getDerivedType()), - templateParams, AlignInBits)); + templateParams, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, nullptr, - AlignInBits)); + AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, (AlignInBits << 1))); + templateParams, (AlignInBits << 1), + nullptr)); TempDIGlobalVariable Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -2662,10 +2665,12 @@ auto *Var = DIGlobalVariable::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, + nullptr); auto *Var2 = DIGlobalVariable::get( Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, + nullptr); auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); EXPECT_EQ(Var, N->getVariable());