[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