[llvm] f419029 - [BPF] Fix a bug in BTF_KIND_TYPE_TAG generation
Yonghong Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 14 19:45:50 PST 2022
Author: Yonghong Song
Date: 2022-02-14T19:43:57-08:00
New Revision: f419029fcdace7673c42ac01703eaaf36813356a
URL: https://github.com/llvm/llvm-project/commit/f419029fcdace7673c42ac01703eaaf36813356a
DIFF: https://github.com/llvm/llvm-project/commit/f419029fcdace7673c42ac01703eaaf36813356a.diff
LOG: [BPF] Fix a bug in BTF_KIND_TYPE_TAG generation
Kumar Kartikeya Dwivedi reported a bug ([1]) where BTF_KIND_TYPE_TAG types
are not generated.
Currently, BPF backend only generates BTF types which are used by
the program, e.g., global variables, functions and some builtin functions.
For example, suppose we have
struct task_struct {
...
struct task_group *sched_task_group;
struct mm_struct *mm;
...
pid_t pid;
pid_t tgid;
...
}
If BPF program intends to access task_struct->pid and task_struct->tgid,
there really no need to generate BTF types for struct task_group
and mm_struct.
In BPF backend, during BTF generation, when generating BTF for struct
task_struct, if types for task_group and mm_struct have not been generated
yet, a Fixup structure will be created, which will be reexamined later
to instantiate into either a full type or a forward type.
In current implementation, if we have something like
struct foo {
struct bar __tag1 *f;
};
and when generating types for struct foo, struct bar type
has not been generated, the __tag1 will be lost during later
Fixup instantiation. This patch fixed this issue by properly
handling btf_type_tag's during Fixup instantiation stage.
[1] https://lore.kernel.org/bpf/20220210232411.pmhzj7v5uptqby7r@apollo.legion/
Differential Revision: https://reviews.llvm.org/D119799
Added:
llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll
llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll
Modified:
llvm/lib/Target/BPF/BTFDebug.cpp
llvm/lib/Target/BPF/BTFDebug.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index d536aed1d2114..ff89a897a325a 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -552,6 +552,46 @@ void BTFDebug::processDeclAnnotations(DINodeArray Annotations,
}
}
+/// Generate btf_type_tag chains.
+int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) {
+ SmallVector<const MDString *, 4> MDStrs;
+ DINodeArray Annots = DTy->getAnnotations();
+ if (Annots) {
+ // For type with "int __tag1 __tag2 *p", the MDStrs will have
+ // content: [__tag1, __tag2].
+ for (const Metadata *Annotations : Annots->operands()) {
+ const MDNode *MD = cast<MDNode>(Annotations);
+ const MDString *Name = cast<MDString>(MD->getOperand(0));
+ if (!Name->getString().equals("btf_type_tag"))
+ continue;
+ MDStrs.push_back(cast<MDString>(MD->getOperand(1)));
+ }
+ }
+
+ if (MDStrs.size() == 0)
+ return -1;
+
+ // With MDStrs [__tag1, __tag2], the output type chain looks like
+ // PTR -> __tag2 -> __tag1 -> BaseType
+ // In the below, we construct BTF types with the order of __tag1, __tag2
+ // and PTR.
+ unsigned TmpTypeId;
+ std::unique_ptr<BTFTypeTypeTag> TypeEntry;
+ if (BaseTypeId >= 0)
+ TypeEntry =
+ std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
+ else
+ TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
+ TmpTypeId = addType(std::move(TypeEntry));
+
+ for (unsigned I = 1; I < MDStrs.size(); I++) {
+ const MDString *Value = MDStrs[I];
+ TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId, Value->getString());
+ TmpTypeId = addType(std::move(TypeEntry));
+ }
+ return TmpTypeId;
+}
+
/// Handle structure/union types.
void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
uint32_t &TypeId) {
@@ -684,9 +724,8 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
/// pointee type will be replaced with either a real type or
/// a forward declaration.
auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, true);
- auto &Fixup = FixupDerivedTypes[CTy->getName()];
- Fixup.first = CTag == dwarf::DW_TAG_union_type;
- Fixup.second.push_back(TypeEntry.get());
+ auto &Fixup = FixupDerivedTypes[CTy];
+ Fixup.push_back(std::make_pair(DTy, TypeEntry.get()));
TypeId = addType(std::move(TypeEntry), DTy);
return;
}
@@ -695,34 +734,8 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
}
if (Tag == dwarf::DW_TAG_pointer_type) {
- SmallVector<const MDString *, 4> MDStrs;
- DINodeArray Annots = DTy->getAnnotations();
- if (Annots) {
- // For type with "int __tag1 __tag2 *p", the MDStrs will have
- // content: [__tag1, __tag2].
- for (const Metadata *Annotations : Annots->operands()) {
- const MDNode *MD = cast<MDNode>(Annotations);
- const MDString *Name = cast<MDString>(MD->getOperand(0));
- if (!Name->getString().equals("btf_type_tag"))
- continue;
- MDStrs.push_back(cast<MDString>(MD->getOperand(1)));
- }
- }
-
- if (MDStrs.size() > 0) {
- // With MDStrs [__tag1, __tag2], the output type chain looks like
- // PTR -> __tag2 -> __tag1 -> BaseType
- // In the below, we construct BTF types with the order of __tag1, __tag2
- // and PTR.
- auto TypeEntry =
- std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
- unsigned TmpTypeId = addType(std::move(TypeEntry));
- for (unsigned I = 1; I < MDStrs.size(); I++) {
- const MDString *Value = MDStrs[I];
- TypeEntry =
- std::make_unique<BTFTypeTypeTag>(TmpTypeId, Value->getString());
- TmpTypeId = addType(std::move(TypeEntry));
- }
+ int TmpTypeId = genBTFTypeTags(DTy, -1);
+ if (TmpTypeId >= 0) {
auto TypeDEntry =
std::make_unique<BTFTypeDerived>(TmpTypeId, Tag, DTy->getName());
TypeId = addType(std::move(TypeDEntry), DTy);
@@ -1480,8 +1493,9 @@ void BTFDebug::endModule() {
// Fixups
for (auto &Fixup : FixupDerivedTypes) {
- StringRef TypeName = Fixup.first;
- bool IsUnion = Fixup.second.first;
+ const DICompositeType *CTy = Fixup.first;
+ StringRef TypeName = CTy->getName();
+ bool IsUnion = CTy->getTag() == dwarf::DW_TAG_union_type;
// Search through struct types
uint32_t StructTypeId = 0;
@@ -1497,8 +1511,15 @@ void BTFDebug::endModule() {
StructTypeId = addType(std::move(FwdTypeEntry));
}
- for (auto &DType : Fixup.second.second) {
- DType->setPointeeType(StructTypeId);
+ for (auto &TypeInfo : Fixup.second) {
+ const DIDerivedType *DTy = TypeInfo.first;
+ BTFTypeDerived *BDType = TypeInfo.second;
+
+ int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
+ if (TmpTypeId >= 0)
+ BDType->setPointeeType(TmpTypeId);
+ else
+ BDType->setPointeeType(StructTypeId);
}
}
diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h
index 7c30675c553cb..e328b19e6c9c2 100644
--- a/llvm/lib/Target/BPF/BTFDebug.h
+++ b/llvm/lib/Target/BPF/BTFDebug.h
@@ -289,7 +289,8 @@ class BTFDebug : public DebugHandlerBase {
std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
std::vector<BTFTypeStruct *> StructTypes;
std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;
- std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
+ std::map<const DICompositeType *,
+ std::vector<std::pair<const DIDerivedType *, BTFTypeDerived *>>>
FixupDerivedTypes;
std::set<const Function *>ProtoFunctions;
@@ -341,6 +342,13 @@ class BTFDebug : public DebugHandlerBase {
void processDeclAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,
int ComponentId);
+ /// Generate BTF type_tag's. If BaseTypeId is nonnegative, the last
+ /// BTF type_tag in the chain points to BaseTypeId. Otherwise, it points to
+ /// the base type of DTy. Return the type id of the first BTF type_tag
+ /// in the chain. If no type_tag's are generated, a negative value
+ /// is returned.
+ int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId);
+
/// Generate one field relocation record.
void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
const GlobalVariable *, bool IsAma);
diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll
new file mode 100644
index 0000000000000..90ee124634c26
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll
@@ -0,0 +1,131 @@
+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
+;
+; Source:
+; #define __tag1 __attribute__((btf_type_tag("tag1")))
+; #define __tag2 __attribute__((btf_type_tag("tag2")))
+;
+; struct foo;
+; struct map_value {
+; struct foo __tag2 __tag1 *ptr;
+; };
+; void func(struct map_value *);
+; void test(void)
+; {
+; struct map_value v = {};
+; func(&v);
+; }
+; Compilation flag:
+; clang -target bpf -O2 -g -S -emit-llvm test.c
+
+%struct.map_value = type { %struct.foo* }
+%struct.foo = type opaque
+
+; Function Attrs: nounwind
+define dso_local void @test() local_unnamed_addr #0 !dbg !7 {
+entry:
+ %v = alloca %struct.map_value, align 8
+ %0 = bitcast %struct.map_value* %v to i8*, !dbg !20
+ call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !20
+ call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !21
+ %1 = bitcast %struct.map_value* %v to i64*, !dbg !21
+ store i64 0, i64* %1, align 8, !dbg !21
+ call void @func(%struct.map_value* noundef nonnull %v) #4, !dbg !22
+ call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23
+ ret void, !dbg !23
+}
+
+; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1)
+; CHECK-NEXT: .long 218103808 # 0xd000000
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2)
+; CHECK-NEXT: .long 201326593 # 0xc000001
+; CHECK-NEXT: .long 1
+; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3)
+; CHECK-NEXT: .long 218103809 # 0xd000001
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 4
+; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4)
+; CHECK-NEXT: .long 33554432 # 0x2000000
+; CHECK-NEXT: .long 5
+; CHECK-NEXT: .long 62 # BTF_KIND_STRUCT(id = 5)
+; CHECK-NEXT: .long 67108865 # 0x4000001
+; CHECK-NEXT: .long 8
+; CHECK-NEXT: .long 72
+; CHECK-NEXT: .long 8
+; CHECK-NEXT: .long 0 # 0x0
+; CHECK-NEXT: .long 76 # BTF_KIND_TYPE_TAG(id = 6)
+; CHECK-NEXT: .long 301989888 # 0x12000000
+; CHECK-NEXT: .long 9
+; CHECK-NEXT: .long 81 # BTF_KIND_TYPE_TAG(id = 7)
+; CHECK-NEXT: .long 301989888 # 0x12000000
+; CHECK-NEXT: .long 6
+; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 8)
+; CHECK-NEXT: .long 33554432 # 0x2000000
+; CHECK-NEXT: .long 7
+; CHECK-NEXT: .long 86 # BTF_KIND_FWD(id = 9)
+; CHECK-NEXT: .long 117440512 # 0x7000000
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 90 # BTF_KIND_FUNC(id = 10)
+; CHECK-NEXT: .long 201326594 # 0xc000002
+; CHECK-NEXT: .long 3
+
+; CHECK: .ascii "test" # string offset=1
+; CHECK: .ascii "map_value" # string offset=62
+; CHECK: .ascii "ptr" # string offset=72
+; CHECK: .ascii "tag2" # string offset=76
+; CHECK: .ascii "tag1" # string offset=81
+; CHECK: .ascii "foo" # string offset=86
+; CHECK: .ascii "func" # string offset=90
+
+; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
+
+; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
+
+declare !dbg !24 dso_local void @func(%struct.map_value* noundef) local_unnamed_addr #3
+
+; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
+
+attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn }
+attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn }
+attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #4 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "7735a89e98603fee29d352a8e9db5acb")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 7, !"frame-pointer", i32 2}
+!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"}
+!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !8, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !{!11}
+!11 = !DILocalVariable(name: "v", scope: !7, file: !1, line: 11, type: !12)
+!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 5, size: 64, elements: !13)
+!13 = !{!14}
+!14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 6, baseType: !15, size: 64)
+!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !17)
+!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, flags: DIFlagFwdDecl)
+!17 = !{!18, !19}
+!18 = !{!"btf_type_tag", !"tag2"}
+!19 = !{!"btf_type_tag", !"tag1"}
+!20 = !DILocation(line: 11, column: 9, scope: !7)
+!21 = !DILocation(line: 11, column: 26, scope: !7)
+!22 = !DILocation(line: 12, column: 9, scope: !7)
+!23 = !DILocation(line: 13, column: 1, scope: !7)
+!24 = !DISubprogram(name: "func", scope: !1, file: !1, line: 8, type: !25, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !28)
+!25 = !DISubroutineType(types: !26)
+!26 = !{null, !27}
+!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
+!28 = !{}
diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll
new file mode 100644
index 0000000000000..b12e2c78f04a0
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll
@@ -0,0 +1,151 @@
+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
+;
+; Source:
+; #define __tag1 __attribute__((btf_type_tag("tag1")))
+; #define __tag2 __attribute__((btf_type_tag("tag2")))
+;
+; struct foo {
+; int i;
+; };
+; struct map_value {
+; struct foo __tag2 __tag1 *ptr;
+; };
+; void func(struct map_value *, struct foo *);
+; void test(void)
+; {
+; struct map_value v = {};
+; func(&v, v.ptr);
+; }
+; Compilation flag:
+; clang -target bpf -O2 -g -S -emit-llvm test.c
+
+%struct.map_value = type { %struct.foo* }
+%struct.foo = type { i32 }
+
+; Function Attrs: nounwind
+define dso_local void @test() local_unnamed_addr #0 !dbg !7 {
+entry:
+ %v = alloca %struct.map_value, align 8
+ %0 = bitcast %struct.map_value* %v to i8*, !dbg !23
+ call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23
+ call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !24
+ %1 = bitcast %struct.map_value* %v to i64*, !dbg !24
+ store i64 0, i64* %1, align 8, !dbg !24
+ call void @func(%struct.map_value* noundef nonnull %v, %struct.foo* noundef null) #4, !dbg !25
+ call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !26
+ ret void, !dbg !26
+}
+
+; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1)
+; CHECK-NEXT: .long 218103808 # 0xd000000
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2)
+; CHECK-NEXT: .long 201326593 # 0xc000001
+; CHECK-NEXT: .long 1
+; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3)
+; CHECK-NEXT: .long 218103810 # 0xd000002
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 4
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 7
+; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4)
+; CHECK-NEXT: .long 33554432 # 0x2000000
+; CHECK-NEXT: .long 5
+; CHECK-NEXT: .long 63 # BTF_KIND_STRUCT(id = 5)
+; CHECK-NEXT: .long 67108865 # 0x4000001
+; CHECK-NEXT: .long 8
+; CHECK-NEXT: .long 73
+; CHECK-NEXT: .long 6
+; CHECK-NEXT: .long 0 # 0x0
+; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6)
+; CHECK-NEXT: .long 33554432 # 0x2000000
+; CHECK-NEXT: .long 12
+; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 7)
+; CHECK-NEXT: .long 33554432 # 0x2000000
+; CHECK-NEXT: .long 8
+; CHECK-NEXT: .long 77 # BTF_KIND_STRUCT(id = 8)
+; CHECK-NEXT: .long 67108865 # 0x4000001
+; CHECK-NEXT: .long 4
+; CHECK-NEXT: .long 81
+; CHECK-NEXT: .long 9
+; CHECK-NEXT: .long 0 # 0x0
+; CHECK-NEXT: .long 83 # BTF_KIND_INT(id = 9)
+; CHECK-NEXT: .long 16777216 # 0x1000000
+; CHECK-NEXT: .long 4
+; CHECK-NEXT: .long 16777248 # 0x1000020
+; CHECK-NEXT: .long 87 # BTF_KIND_FUNC(id = 10)
+; CHECK-NEXT: .long 201326594 # 0xc000002
+; CHECK-NEXT: .long 3
+; CHECK-NEXT: .long 92 # BTF_KIND_TYPE_TAG(id = 11)
+; CHECK-NEXT: .long 301989888 # 0x12000000
+; CHECK-NEXT: .long 8
+; CHECK-NEXT: .long 97 # BTF_KIND_TYPE_TAG(id = 12)
+; CHECK-NEXT: .long 301989888 # 0x12000000
+; CHECK-NEXT: .long 11
+
+; CHECK: .ascii "test" # string offset=1
+; CHECK: .ascii "map_value" # string offset=63
+; CHECK: .ascii "ptr" # string offset=73
+; CHECK: .ascii "foo" # string offset=77
+; CHECK: .byte 105 # string offset=81
+; CHECK: .ascii "int" # string offset=83
+; CHECK: .ascii "func" # string offset=87
+; CHECK: .ascii "tag2" # string offset=92
+; CHECK: .ascii "tag1" # string offset=97
+
+; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
+
+; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
+
+declare !dbg !27 dso_local void @func(%struct.map_value* noundef, %struct.foo* noundef) local_unnamed_addr #3
+
+; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
+
+attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn }
+attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn }
+attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #4 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/tmp//home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "8b3b8281c3b4240403467e0c9461251d")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 7, !"frame-pointer", i32 2}
+!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"}
+!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !8, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !{!11}
+!11 = !DILocalVariable(name: "v", scope: !7, file: !1, line: 13, type: !12)
+!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 7, size: 64, elements: !13)
+!13 = !{!14}
+!14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 8, baseType: !15, size: 64)
+!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !20)
+!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17)
+!17 = !{!18}
+!18 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !16, file: !1, line: 5, baseType: !19, size: 32)
+!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!20 = !{!21, !22}
+!21 = !{!"btf_type_tag", !"tag2"}
+!22 = !{!"btf_type_tag", !"tag1"}
+!23 = !DILocation(line: 13, column: 9, scope: !7)
+!24 = !DILocation(line: 13, column: 26, scope: !7)
+!25 = !DILocation(line: 14, column: 9, scope: !7)
+!26 = !DILocation(line: 15, column: 1, scope: !7)
+!27 = !DISubprogram(name: "func", scope: !1, file: !1, line: 10, type: !28, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !32)
+!28 = !DISubroutineType(types: !29)
+!29 = !{null, !30, !31}
+!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
+!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64)
+!32 = !{}
More information about the llvm-commits
mailing list