yonghong-song created this revision. yonghong-song added reviewers: dblaikie, probinson, aprantl, aaron.ballman. yonghong-song added a project: debug-info. Herald added subscribers: dexonsmith, ormris, hiraditya. yonghong-song requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
Generate btf_tag annotations for DIDrived types. More specifically, clang frontend generates the btf_tag annotations for record fields. The annotations are represented as an DINodeArray in DebugInfo. The following example illustrate how annotations are encoded in IR: distinct !DIDerivedType(tag: DW_TAG_member, ..., annotations: !10) !10 = !{!11, !12} !11 = !{!"btf_tag", !"a"} !12 = !{!"btf_tag", !"b"} Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D106616 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGen/attr-btf_tag-field.c llvm/include/llvm/IR/DebugInfoMetadata.h llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/MetadataLoader.cpp llvm/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/DebugInfoMetadata.cpp llvm/lib/IR/LLVMContextImpl.h llvm/test/Bitcode/attr-btf_tag-field.ll
Index: llvm/test/Bitcode/attr-btf_tag-field.ll =================================================================== --- /dev/null +++ llvm/test/Bitcode/attr-btf_tag-field.ll @@ -0,0 +1,36 @@ +; REQUIRES: x86-registered-target +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +%struct.t = type { i32 } + +@g = dso_local local_unnamed_addr global %struct.t zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!13, !14, !15, !16} +!llvm.ident = !{!17} + +!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 1b8d548385089fd516c11cd69d20c4ad33cae328)", isOptimized: true, 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) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !3, line: 1, baseType: !9, size: 32, annotations: !10) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{!11, !12} +!11 = !{!"btf_tag", !"a"} +!12 = !{!"btf_tag", !"b"} + +; CHECK: !DIDerivedType(tag: DW_TAG_member, name: "a" +; 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 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 1b8d548385089fd516c11cd69d20c4ad33cae328)"} Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -471,23 +471,24 @@ Optional<unsigned> DWARFAddressSpace; unsigned Flags; Metadata *ExtraData; + Metadata *Annotations; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, unsigned Flags, - Metadata *ExtraData) + Metadata *ExtraData, Metadata *Annotations) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), - Flags(Flags), ExtraData(ExtraData) {} + Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {} MDNodeKeyImpl(const DIDerivedType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()), - ExtraData(N->getRawExtraData()) {} + ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIDerivedType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && @@ -498,7 +499,8 @@ OffsetInBits == RHS->getOffsetInBits() && DWARFAddressSpace == RHS->getDWARFAddressSpace() && Flags == RHS->getFlags() && - ExtraData == RHS->getRawExtraData(); + ExtraData == RHS->getRawExtraData() && + Annotations == RHS->getRawAnnotations(); } unsigned getHashValue() const { Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -582,13 +582,13 @@ unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData, - StorageType Storage, bool ShouldCreate) { + Metadata *Annotations, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIDerivedType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData)); - Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData}; + ExtraData, Annotations)); + Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations}; DEFINE_GETIMPL_STORE( DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, Flags), Ops); Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -2040,6 +2040,7 @@ if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace()) Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace, /* ShouldSkipZero */ false); + Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; } Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1687,6 +1687,8 @@ else Record.push_back(0); + Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); + Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev); Record.clear(); } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1437,7 +1437,7 @@ break; } case bitc::METADATA_DERIVED_TYPE: { - if (Record.size() < 12 || Record.size() > 13) + if (Record.size() < 12 || Record.size() > 14) return error("Invalid record"); // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means @@ -1446,6 +1446,10 @@ if (Record.size() > 12 && Record[12]) DWARFAddressSpace = Record[12] - 1; + Metadata *Annotations = nullptr; + if (Record.size() > 13 && Record[13]) + Annotations = getMDOrNull(Record[13]); + IsDistinct = Record[0]; DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]); MetadataList.assignValue( @@ -1455,7 +1459,8 @@ getDITypeRefOrNull(Record[5]), getDITypeRefOrNull(Record[6]), Record[7], Record[8], Record[9], DWARFAddressSpace, Flags, - getDITypeRefOrNull(Record[11]))), + getDITypeRefOrNull(Record[11]), + Annotations)), NextMetadataNo); NextMetadataNo++; break; Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4578,7 +4578,8 @@ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(extraData, MDField, ); \ - OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); + OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \ + OPTIONAL(annotations, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4590,7 +4591,7 @@ (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, DWARFAddressSpace, flags.Val, - extraData.Val)); + extraData.Val, annotations.Val)); return false; } Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -936,10 +936,12 @@ unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true) { + Metadata *ExtraData, DINodeArray Annotations, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate); + DWARFAddressSpace, Flags, ExtraData, Annotations.get(), + Storage, ShouldCreate); } static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -948,13 +950,15 @@ uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData, - StorageType Storage, bool ShouldCreate = true); + Metadata *Annotations, StorageType Storage, + bool ShouldCreate = true); TempDIDerivedType cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), getScope(), getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(), - getDWARFAddressSpace(), getFlags(), getExtraData()); + getDWARFAddressSpace(), getFlags(), getExtraData(), + getAnnotations()); } public: @@ -964,19 +968,21 @@ uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData = nullptr), + Metadata *ExtraData = nullptr, + Metadata *Annotations = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData)) + ExtraData, Annotations)) DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData = nullptr), + Metadata *ExtraData = nullptr, + DINodeArray Annotations = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData)) + ExtraData, Annotations)) TempDIDerivedType clone() const { return cloneImpl(); } @@ -999,6 +1005,17 @@ Metadata *getExtraData() const { return getRawExtraData(); } Metadata *getRawExtraData() const { return getOperand(4); } + /// Get annotations associated with this derived type. + DINodeArray getAnnotations() const { + return cast_or_null<MDTuple>(getRawAnnotations()); + } + Metadata *getRawAnnotations() const { return getOperand(5); } + + /// Replace annotations operand. + void replaceAnnotations(DINodeArray Annotations) { + replaceOperandWith(5, Annotations.get()); + } + /// Get casted version of extra data. /// @{ DIType *getClassType() const { Index: clang/test/CodeGen/attr-btf_tag-field.c =================================================================== --- /dev/null +++ clang/test/CodeGen/attr-btf_tag-field.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: !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[#]], size: 32, annotations: ![[ANNOT:[0-9]+]]) +// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]} +// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"} +// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"} Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -1499,6 +1499,11 @@ OffsetInBits, Align, tunit, RecordTy, RD); } + if (field->hasAttr<BTFTagAttr>()) { + auto FType = cast<llvm::DIDerivedType>(FieldType); + FType->replaceAnnotations(CollectBTFTagAnnotations(field)); + } + elements.push_back(FieldType); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits