diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -292,6 +292,9 @@ CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS, llvm::DIFile *F); + /// A helper function to collect debug info for btf_tag annotations. + llvm::DINodeArray CollectBTFTagAnnotations(const Decl *D); + llvm::DIType *createFieldType(StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS, uint64_t offsetInBits, uint32_t AlignInBits, diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2063,6 +2063,18 @@ return CollectTemplateParams(TPList, TAList.asArray(), Unit); } +llvm::DINodeArray CGDebugInfo::CollectBTFTagAnnotations(const Decl *D) { + SmallVector Annotations; + for (const auto *I : D->specific_attrs()) { + llvm::Metadata *Ops[2] = { + llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_tag")), + llvm::MDString::get(CGM.getLLVMContext(), I->getBTFTag()) + }; + Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops)); + } + return DBuilder.getOrCreateArray(Annotations); +} + llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) { if (VTablePtrType) return VTablePtrType; @@ -3468,6 +3480,9 @@ break; } + if (D->hasAttr()) + RealDecl->replaceAnnotations(CollectBTFTagAnnotations(D)); + RegionMap[Ty->getDecl()].reset(RealDecl); TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl); diff --git a/clang/test/CodeGen/attr-btf_tag-dicomposite.c b/clang/test/CodeGen/attr-btf_tag-dicomposite.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/attr-btf_tag-dicomposite.c @@ -0,0 +1,18 @@ +// REQUIRES: x86-registered-target +// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s + +#define __tag1 __attribute__((btf_tag("tag1"))) +#define __tag2 __attribute__((btf_tag("tag2"))) + +struct t1 { + int a; +} __tag1 __tag2; + +int foo(struct t1 *arg) { + return arg->a; +} + +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT:[0-9]+]]) +// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]} +// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"} +// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"} 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 @@ -1081,13 +1081,14 @@ DITemplateParameterArray TemplateParams, StringRef Identifier, DIDerivedType *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, - StorageType Storage, bool ShouldCreate = true) { + DINodeArray Annotations, StorageType Storage, + bool ShouldCreate = true) { return getImpl( Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), RuntimeLang, VTableHolder, TemplateParams.get(), getCanonicalMDString(Context, Identifier), Discriminator, DataLocation, - Associated, Allocated, Rank, Storage, ShouldCreate); + Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate); } static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, @@ -1097,7 +1098,7 @@ Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, - StorageType Storage, bool ShouldCreate = true); + Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); TempDICompositeType cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), @@ -1106,7 +1107,8 @@ getElements(), getRuntimeLang(), getVTableHolder(), getTemplateParams(), getIdentifier(), getDiscriminator(), getRawDataLocation(), - getRawAssociated(), getRawAllocated(), getRawRank()); + getRawAssociated(), getRawAllocated(), getRawRank(), + getAnnotations()); } public: @@ -1119,10 +1121,12 @@ DITemplateParameterArray TemplateParams = nullptr, StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, - Metadata *Allocated = nullptr, Metadata *Rank = nullptr), + Metadata *Allocated = nullptr, Metadata *Rank = nullptr, + DINodeArray Annotations = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation, Associated, Allocated, Rank)) + Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, + Annotations)) DEFINE_MDNODE_GET( DICompositeType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -1132,10 +1136,11 @@ Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr, Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, - Metadata *Rank = nullptr), + Metadata *Rank = nullptr, Metadata *Annotations = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation, Associated, Allocated, Rank)) + Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, + Annotations)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1154,7 +1159,7 @@ unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank); + Metadata *Rank, Metadata *Annotations); static DICompositeType *getODRTypeIfExists(LLVMContext &Context, MDString &Identifier); @@ -1175,7 +1180,7 @@ unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank); + Metadata *Allocated, Metadata *Rank, Metadata *Annotations); DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } DINodeArray getElements() const { @@ -1228,6 +1233,11 @@ return dyn_cast_or_null(getRawRank()); } + Metadata *getRawAnnotations() const { return getOperand(13); } + DINodeArray getAnnotations() const { + return cast_or_null(getRawAnnotations()); + } + /// Replace operands. /// /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision @@ -1250,6 +1260,10 @@ void replaceTemplateParams(DITemplateParameterArray TemplateParams) { replaceOperandWith(6, TemplateParams.get()); } + + void replaceAnnotations(DINodeArray Annotations) { + replaceOperandWith(13, Annotations.get()); + } /// @} static bool classof(const Metadata *MD) { 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 @@ -4615,7 +4615,8 @@ OPTIONAL(dataLocation, MDField, ); \ OPTIONAL(associated, MDField, ); \ OPTIONAL(allocated, MDField, ); \ - OPTIONAL(rank, MDSignedOrMDField, ); + OPTIONAL(rank, MDSignedOrMDField, ); \ + OPTIONAL(annotations, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4633,7 +4634,7 @@ scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, - Rank)) { + Rank, annotations.Val)) { Result = CT; return false; } @@ -4646,7 +4647,7 @@ size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, - Rank)); + Rank, 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 @@ -1461,7 +1461,7 @@ break; } case bitc::METADATA_COMPOSITE_TYPE: { - if (Record.size() < 16 || Record.size() > 21) + if (Record.size() < 16 || Record.size() > 22) return error("Invalid record"); // If we have a UUID and this is not a forward declaration, lookup the @@ -1489,6 +1489,7 @@ Metadata *Associated = nullptr; Metadata *Allocated = nullptr; Metadata *Rank = nullptr; + Metadata *Annotations = nullptr; auto *Identifier = getMDString(Record[15]); // If this module is being parsed so that it can be ThinLTO imported // into another module, composite types only need to be imported @@ -1520,6 +1521,9 @@ if (Record.size() > 20) { Rank = getMDOrNull(Record[20]); } + if (Record.size() > 21) { + Annotations = getMDOrNull(Record[21]); + } } DICompositeType *CT = nullptr; if (Identifier) @@ -1527,7 +1531,7 @@ Context, *Identifier, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Discriminator, DataLocation, Associated, - Allocated, Rank); + Allocated, Rank, Annotations); // Create a node if we didn't get a lazy ODR type. if (!CT) @@ -1536,7 +1540,7 @@ SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank)); + Allocated, Rank, Annotations)); if (!IsNotUsedInTypeRef && Identifier) MetadataList.addTypeRef(*Identifier, *cast(CT)); 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 @@ -1716,6 +1716,7 @@ Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated())); Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated())); Record.push_back(VE.getMetadataOrNullID(N->getRawRank())); + Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, 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 @@ -2073,6 +2073,7 @@ /* ShouldSkipZero */ false); else Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true); + Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; } 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 @@ -601,7 +601,8 @@ Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, StorageType Storage, bool ShouldCreate) { + Metadata *Rank, Metadata *Annotations, StorageType Storage, + bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); // Keep this in sync with buildODRType. @@ -609,11 +610,12 @@ DICompositeType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation, Associated, Allocated, Rank)); + Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, + Annotations)); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank}; + Rank, Annotations}; DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags), Ops); @@ -626,7 +628,7 @@ DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank) { + Metadata *Rank, Metadata *Annotations) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -636,7 +638,7 @@ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, - DataLocation, Associated, Allocated, Rank); + DataLocation, Associated, Allocated, Rank, Annotations); // Only mutate CT if it's a forward declaration and the new operands aren't. assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?"); @@ -649,7 +651,7 @@ Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank}; + Rank, Annotations}; assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() && "Mismatched number of operands"); for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) @@ -665,7 +667,7 @@ DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank) { + Metadata *Rank, Metadata *Annotations) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -675,7 +677,7 @@ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank); + Allocated, Rank, Annotations); return CT; } 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 @@ -569,6 +569,7 @@ Metadata *Associated; Metadata *Allocated; Metadata *Rank; + Metadata *Annotations; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, @@ -577,14 +578,15 @@ Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank) + Metadata *Allocated, Metadata *Rank, Metadata *Annotations) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), RuntimeLang(RuntimeLang), VTableHolder(VTableHolder), TemplateParams(TemplateParams), Identifier(Identifier), Discriminator(Discriminator), DataLocation(DataLocation), - Associated(Associated), Allocated(Allocated), Rank(Rank) {} + Associated(Associated), Allocated(Allocated), Rank(Rank), + Annotations(Annotations) {} MDNodeKeyImpl(const DICompositeType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), @@ -597,7 +599,7 @@ Discriminator(N->getRawDiscriminator()), DataLocation(N->getRawDataLocation()), Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()), - Rank(N->getRawRank()) {} + Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DICompositeType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && @@ -614,7 +616,8 @@ Discriminator == RHS->getRawDiscriminator() && DataLocation == RHS->getRawDataLocation() && Associated == RHS->getRawAssociated() && - Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank(); + Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() && + Annotations == RHS->getRawAnnotations(); } unsigned getHashValue() const { @@ -623,7 +626,7 @@ // collision "most of the time". There is no correctness issue in case of // collision because of the full check above. return hash_combine(Name, File, Line, BaseType, Scope, Elements, - TemplateParams); + TemplateParams, Annotations); } }; diff --git a/llvm/test/Bitcode/attr-btf_tag-dicomposite.ll b/llvm/test/Bitcode/attr-btf_tag-dicomposite.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/attr-btf_tag-dicomposite.ll @@ -0,0 +1,36 @@ +; REQUIRES: x86-registered-target +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +%struct.t = type { i32 } + +@g = dso_local global %struct.t 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: "g", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git a20bed0ba269a4f9b67e58093c50af9ef0730fd1)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "struct.c", directory: "/home/yhs/work/tests/llvm/btf_tag") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, size: 32, elements: !7, annotations: !10) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !3, line: 1, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{!11, !12} +!11 = !{!"btf_tag", !"a"} +!12 = !{!"btf_tag", !"b"} + +; CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t" +; CHECK-SAME: annotations: ![[ANNOT:[0-9]+]] +; CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]} +; CHECK: ![[TAG1]] = !{!"btf_tag", !"a"} +; CHECK: ![[TAG2]] = !{!"btf_tag", !"b"} +!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 a20bed0ba269a4f9b67e58093c50af9ef0730fd1)"}