Skip to content

Commit 3ca1744

Browse files
authored
[DebugInfo][BPF] Add 'annotations' field for DIBasicType & DISubroutineType (#91422)
Extend `DIBasicType` and `DISubroutineType` with additional field `annotations`, e.g. as below: ``` !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !6) !6 = !{!7} !7 = !{!"btf:type_tag", !"tag1"} ``` The field would be used by BPF backend to generate DWARF attributes corresponding to `btf_type_tag` type attributes, e.g.: ``` 0x00000029: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x0000002d: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("tag1") ``` Such DWARF entries would be used to generate BTF definitions by tools like [pahole](https://github.com/acmel/dwarves). Note: similar fields with similar purposes are already present in DIDerivedType and DICompositeType. Currently "btf_type_tag" attributes are represented in debug information as 'annotations' fields in DIDerivedType with DW_TAG_pointer_type tag. The annotation on a pointer corresponds to pointee having the attributes in the final BTF. The discussion in [thread](https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/) came to conclusion, that such annotations should apply to the annotated type itself. Hence the necessity to extend `DIBasicType` & `DISubroutineType` types with 'annotations' field to represent cases like below: ``` int __attribute__((btf_type_tag("foo"))) bar; ``` This was previously tracked as differential revision: https://reviews.llvm.org/D143966
1 parent d95b82c commit 3ca1744

File tree

11 files changed

+295
-90
lines changed

11 files changed

+295
-90
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -828,40 +828,45 @@ class DIBasicType : public DIType {
828828
static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
829829
StringRef Name, uint64_t SizeInBits,
830830
uint32_t AlignInBits, unsigned Encoding,
831-
DIFlags Flags, StorageType Storage,
832-
bool ShouldCreate = true) {
831+
DIFlags Flags, DINodeArray Annotations,
832+
StorageType Storage, bool ShouldCreate = true) {
833833
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
834-
SizeInBits, AlignInBits, Encoding, Flags, Storage,
835-
ShouldCreate);
834+
SizeInBits, AlignInBits, Encoding, Flags, Annotations.get(),
835+
Storage, ShouldCreate);
836836
}
837837
static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
838838
MDString *Name, uint64_t SizeInBits,
839839
uint32_t AlignInBits, unsigned Encoding,
840-
DIFlags Flags, StorageType Storage,
841-
bool ShouldCreate = true);
840+
DIFlags Flags, Metadata *Annotations,
841+
StorageType Storage, bool ShouldCreate = true);
842842

843843
TempDIBasicType cloneImpl() const {
844844
return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
845-
getAlignInBits(), getEncoding(), getFlags());
845+
getAlignInBits(), getEncoding(), getFlags(),
846+
getAnnotations());
846847
}
847848

848849
public:
849850
DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
850-
(Tag, Name, 0, 0, 0, FlagZero))
851+
(Tag, Name, 0, 0, 0, FlagZero, {}))
851852
DEFINE_MDNODE_GET(DIBasicType,
852853
(unsigned Tag, StringRef Name, uint64_t SizeInBits),
853-
(Tag, Name, SizeInBits, 0, 0, FlagZero))
854+
(Tag, Name, SizeInBits, 0, 0, FlagZero, {}))
854855
DEFINE_MDNODE_GET(DIBasicType,
855856
(unsigned Tag, MDString *Name, uint64_t SizeInBits),
856-
(Tag, Name, SizeInBits, 0, 0, FlagZero))
857+
(Tag, Name, SizeInBits, 0, 0, FlagZero, {}))
857858
DEFINE_MDNODE_GET(DIBasicType,
858859
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
859-
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
860-
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
860+
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
861+
DINodeArray Annotations = {}),
862+
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags,
863+
Annotations))
861864
DEFINE_MDNODE_GET(DIBasicType,
862865
(unsigned Tag, MDString *Name, uint64_t SizeInBits,
863-
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
864-
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
866+
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
867+
Metadata *Annotations = nullptr),
868+
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags,
869+
Annotations))
865870

866871
TempDIBasicType clone() const { return cloneImpl(); }
867872

@@ -873,6 +878,16 @@ class DIBasicType : public DIType {
873878
/// neither signed nor unsigned.
874879
std::optional<Signedness> getSignedness() const;
875880

881+
Metadata *getRawAnnotations() const { return getOperand(3); }
882+
883+
DINodeArray getAnnotations() const {
884+
return cast_or_null<MDTuple>(getRawAnnotations());
885+
}
886+
887+
void replaceAnnotations(DINodeArray Annotations) {
888+
replaceOperandWith(3, Annotations.get());
889+
}
890+
876891
static bool classof(const Metadata *MD) {
877892
return MD->getMetadataID() == DIBasicTypeKind;
878893
}
@@ -1112,6 +1127,10 @@ class DIDerivedType : public DIType {
11121127
}
11131128
Metadata *getRawAnnotations() const { return getOperand(5); }
11141129

1130+
void replaceAnnotations(DINodeArray Annotations) {
1131+
replaceOperandWith(5, Annotations.get());
1132+
}
1133+
11151134
/// Get casted version of extra data.
11161135
/// @{
11171136
DIType *getClassType() const;
@@ -1339,6 +1358,10 @@ class DICompositeType : public DIType {
13391358
return cast_or_null<MDTuple>(getRawAnnotations());
13401359
}
13411360

1361+
void replaceAnnotations(DINodeArray Annotations) {
1362+
replaceOperandWith(13, Annotations.get());
1363+
}
1364+
13421365
/// Replace operands.
13431366
///
13441367
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
@@ -1385,26 +1408,30 @@ class DISubroutineType : public DIType {
13851408

13861409
static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
13871410
uint8_t CC, DITypeRefArray TypeArray,
1388-
StorageType Storage,
1411+
DINodeArray Annotations, StorageType Storage,
13891412
bool ShouldCreate = true) {
1390-
return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
1413+
return getImpl(Context, Flags, CC, TypeArray.get(), Annotations.get(),
1414+
Storage, ShouldCreate);
13911415
}
13921416
static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
13931417
uint8_t CC, Metadata *TypeArray,
1394-
StorageType Storage,
1418+
Metadata *Annotations, StorageType Storage,
13951419
bool ShouldCreate = true);
13961420

13971421
TempDISubroutineType cloneImpl() const {
1398-
return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
1422+
return getTemporary(getContext(), getFlags(), getCC(), getTypeArray(),
1423+
getAnnotations());
13991424
}
14001425

14011426
public:
14021427
DEFINE_MDNODE_GET(DISubroutineType,
1403-
(DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
1404-
(Flags, CC, TypeArray))
1428+
(DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray,
1429+
DINodeArray Annotations = nullptr),
1430+
(Flags, CC, TypeArray, Annotations))
14051431
DEFINE_MDNODE_GET(DISubroutineType,
1406-
(DIFlags Flags, uint8_t CC, Metadata *TypeArray),
1407-
(Flags, CC, TypeArray))
1432+
(DIFlags Flags, uint8_t CC, Metadata *TypeArray,
1433+
Metadata *Annotations = nullptr),
1434+
(Flags, CC, TypeArray, Annotations))
14081435

14091436
TempDISubroutineType clone() const { return cloneImpl(); }
14101437
// Returns a new temporary DISubroutineType with updated CC
@@ -1422,6 +1449,15 @@ class DISubroutineType : public DIType {
14221449

14231450
Metadata *getRawTypeArray() const { return getOperand(3); }
14241451

1452+
Metadata *getRawAnnotations() const { return getOperand(4); }
1453+
DINodeArray getAnnotations() const {
1454+
return cast_or_null<MDTuple>(getRawAnnotations());
1455+
}
1456+
1457+
void replaceAnnotations(DINodeArray Annotations) {
1458+
replaceOperandWith(4, Annotations.get());
1459+
}
1460+
14251461
static bool classof(const Metadata *MD) {
14261462
return MD->getMetadataID() == DISubroutineTypeKind;
14271463
}

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5250,20 +5250,22 @@ bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) {
52505250

52515251
/// parseDIBasicType:
52525252
/// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32,
5253-
/// encoding: DW_ATE_encoding, flags: 0)
5253+
/// encoding: DW_ATE_encoding, flags: 0, annotations: !1)
52545254
bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
52555255
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
52565256
OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
52575257
OPTIONAL(name, MDStringField, ); \
52585258
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
52595259
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
52605260
OPTIONAL(encoding, DwarfAttEncodingField, ); \
5261-
OPTIONAL(flags, DIFlagField, );
5261+
OPTIONAL(flags, DIFlagField, ); \
5262+
OPTIONAL(annotations, MDField, );
52625263
PARSE_MD_FIELDS();
52635264
#undef VISIT_MD_FIELDS
52645265

5265-
Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val,
5266-
align.Val, encoding.Val, flags.Val));
5266+
Result = GET_OR_DISTINCT(DIBasicType,
5267+
(Context, tag.Val, name.Val, size.Val, align.Val,
5268+
encoding.Val, flags.Val, annotations.Val));
52675269
return false;
52685270
}
52695271

@@ -5400,12 +5402,13 @@ bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) {
54005402
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
54015403
OPTIONAL(flags, DIFlagField, ); \
54025404
OPTIONAL(cc, DwarfCCField, ); \
5403-
REQUIRED(types, MDField, );
5405+
REQUIRED(types, MDField, ); \
5406+
OPTIONAL(annotations, MDField, );
54045407
PARSE_MD_FIELDS();
54055408
#undef VISIT_MD_FIELDS
54065409

5407-
Result = GET_OR_DISTINCT(DISubroutineType,
5408-
(Context, flags.Val, cc.Val, types.Val));
5410+
Result = GET_OR_DISTINCT(DISubroutineType, (Context, flags.Val, cc.Val,
5411+
types.Val, annotations.Val));
54095412
return false;
54105413
}
54115414

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,18 +1527,22 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
15271527
break;
15281528
}
15291529
case bitc::METADATA_BASIC_TYPE: {
1530-
if (Record.size() < 6 || Record.size() > 7)
1530+
if (Record.size() < 6 || Record.size() > 8)
15311531
return error("Invalid record");
15321532

15331533
IsDistinct = Record[0];
15341534
DINode::DIFlags Flags = (Record.size() > 6)
15351535
? static_cast<DINode::DIFlags>(Record[6])
15361536
: DINode::FlagZero;
15371537

1538+
Metadata *Annotations = nullptr;
1539+
if (Record.size() > 7 && Record[7])
1540+
Annotations = getMDOrNull(Record[7]);
1541+
15381542
MetadataList.assignValue(
15391543
GET_OR_DISTINCT(DIBasicType,
15401544
(Context, Record[1], getMDString(Record[2]), Record[3],
1541-
Record[4], Record[5], Flags)),
1545+
Record[4], Record[5], Flags, Annotations)),
15421546
NextMetadataNo);
15431547
NextMetadataNo++;
15441548
break;
@@ -1703,7 +1707,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
17031707
break;
17041708
}
17051709
case bitc::METADATA_SUBROUTINE_TYPE: {
1706-
if (Record.size() < 3 || Record.size() > 4)
1710+
if (Record.size() < 3 || Record.size() > 5)
17071711
return error("Invalid record");
17081712
bool IsOldTypeRefArray = Record[0] < 2;
17091713
unsigned CC = (Record.size() > 3) ? Record[3] : 0;
@@ -1713,9 +1717,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
17131717
Metadata *Types = getMDOrNull(Record[2]);
17141718
if (LLVM_UNLIKELY(IsOldTypeRefArray))
17151719
Types = MetadataList.upgradeTypeRefArray(Types);
1720+
Metadata *Annotations = nullptr;
1721+
if (Record.size() > 4 && Record[4])
1722+
Annotations = getMDOrNull(Record[4]);
17161723

17171724
MetadataList.assignValue(
1718-
GET_OR_DISTINCT(DISubroutineType, (Context, Flags, CC, Types)),
1725+
GET_OR_DISTINCT(DISubroutineType,
1726+
(Context, Flags, CC, Types, Annotations)),
17191727
NextMetadataNo);
17201728
NextMetadataNo++;
17211729
break;

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,7 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
18161816
Record.push_back(N->getAlignInBits());
18171817
Record.push_back(N->getEncoding());
18181818
Record.push_back(N->getFlags());
1819+
Record.push_back(VE.getMetadataOrNullID(N->getRawAnnotations()));
18191820

18201821
Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev);
18211822
Record.clear();
@@ -1911,6 +1912,7 @@ void ModuleBitcodeWriter::writeDISubroutineType(
19111912
Record.push_back(N->getFlags());
19121913
Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get()));
19131914
Record.push_back(N->getCC());
1915+
Record.push_back(VE.getMetadataOrNullID(N->getRawAnnotations()));
19141916

19151917
Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev);
19161918
Record.clear();

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
712712
if (!Name.empty())
713713
addString(Buffer, dwarf::DW_AT_name, Name);
714714

715-
// An unspecified type only has a name attribute.
715+
addAnnotation(Buffer, BTy->getAnnotations());
716+
717+
// An unspecified type only has a name attribute & annotations.
716718
if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)
717719
return;
718720

@@ -881,6 +883,8 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {
881883

882884
if (CTy->isRValueReference())
883885
addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
886+
887+
addAnnotation(Buffer, CTy->getAnnotations());
884888
}
885889

886890
void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) {

llvm/lib/IR/AsmWriter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,9 +2122,9 @@ static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
21222122
}
21232123

21242124
static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
2125-
AsmWriterContext &) {
2125+
AsmWriterContext &WriterCtx) {
21262126
Out << "!DIBasicType(";
2127-
MDFieldPrinter Printer(Out);
2127+
MDFieldPrinter Printer(Out, WriterCtx);
21282128
if (N->getTag() != dwarf::DW_TAG_base_type)
21292129
Printer.printTag(N);
21302130
Printer.printString("name", N->getName());
@@ -2133,6 +2133,7 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
21332133
Printer.printDwarfEnum("encoding", N->getEncoding(),
21342134
dwarf::AttributeEncodingString);
21352135
Printer.printDIFlags("flags", N->getFlags());
2136+
Printer.printMetadata("annotations", N->getRawAnnotations());
21362137
Out << ")";
21372138
}
21382139

@@ -2228,6 +2229,7 @@ static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
22282229
Printer.printDwarfEnum("cc", N->getCC(), dwarf::ConventionString);
22292230
Printer.printMetadata("types", N->getRawTypeArray(),
22302231
/* ShouldSkipNull */ false);
2232+
Printer.printMetadata("annotations", N->getRawAnnotations());
22312233
Out << ")";
22322234
}
22332235

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,12 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
663663
DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
664664
MDString *Name, uint64_t SizeInBits,
665665
uint32_t AlignInBits, unsigned Encoding,
666-
DIFlags Flags, StorageType Storage,
667-
bool ShouldCreate) {
666+
DIFlags Flags, Metadata *Annotations,
667+
StorageType Storage, bool ShouldCreate) {
668668
assert(isCanonical(Name) && "Expected canonical MDString");
669-
DEFINE_GETIMPL_LOOKUP(DIBasicType,
670-
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));
671-
Metadata *Ops[] = {nullptr, nullptr, Name};
669+
DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits,
670+
Encoding, Flags, Annotations));
671+
Metadata *Ops[] = {nullptr, nullptr, Name, Annotations};
672672
DEFINE_GETIMPL_STORE(DIBasicType,
673673
(Tag, SizeInBits, AlignInBits, Encoding, Flags), Ops);
674674
}
@@ -872,10 +872,11 @@ DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
872872

873873
DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
874874
uint8_t CC, Metadata *TypeArray,
875+
Metadata *Annotations,
875876
StorageType Storage,
876877
bool ShouldCreate) {
877-
DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray));
878-
Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray};
878+
DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray, Annotations));
879+
Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray, Annotations};
879880
DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
880881
}
881882

0 commit comments

Comments
 (0)