[llvm] 4948927 - [BPF] support btf_tag attribute in .BTF section

Yonghong Song via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 28 21:03:49 PDT 2021


Author: Yonghong Song
Date: 2021-08-28T21:02:27-07:00
New Revision: 4948927058e5a8e808e44583c33e472d0d8a315d

URL: https://github.com/llvm/llvm-project/commit/4948927058e5a8e808e44583c33e472d0d8a315d
DIFF: https://github.com/llvm/llvm-project/commit/4948927058e5a8e808e44583c33e472d0d8a315d.diff

LOG: [BPF] support btf_tag attribute in .BTF section

A new kind BTF_KIND_TAG is added to .BTF to encode
btf_tag attributes. The format looks like
   CommonType.name : attribute string
   CommonType.type : attached to a struct/union/func/var.
   CommonType.info : encoding BTF_KIND_TAG
                     kflag == 1 to indicate the attribute is
                     for CommonType.type, or kflag == 0
                     for struct/union member or func argument.
   one uint32_t    : to encode which member/argument starting from 0.

If one particular type or member/argument has more than one attribute,
multiple BTF_KIND_TAG will be generated.

Differential Revision: https://reviews.llvm.org/D106622

Added: 
    llvm/test/CodeGen/BPF/BTF/tag-1.ll
    llvm/test/CodeGen/BPF/BTF/tag-2.ll

Modified: 
    llvm/lib/Target/BPF/BTF.def
    llvm/lib/Target/BPF/BTF.h
    llvm/lib/Target/BPF/BTFDebug.cpp
    llvm/lib/Target/BPF/BTFDebug.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/BPF/BTF.def b/llvm/lib/Target/BPF/BTF.def
index 66cf2c90ead4..8a152cf8ea88 100644
--- a/llvm/lib/Target/BPF/BTF.def
+++ b/llvm/lib/Target/BPF/BTF.def
@@ -31,5 +31,6 @@ HANDLE_BTF_KIND(13, FUNC_PROTO)
 HANDLE_BTF_KIND(14, VAR)
 HANDLE_BTF_KIND(15, DATASEC)
 HANDLE_BTF_KIND(16, FLOAT)
+HANDLE_BTF_KIND(17, TAG)
 
 #undef HANDLE_BTF_KIND

diff  --git a/llvm/lib/Target/BPF/BTF.h b/llvm/lib/Target/BPF/BTF.h
index ad3dcc14c38a..cf29547b4249 100644
--- a/llvm/lib/Target/BPF/BTF.h
+++ b/llvm/lib/Target/BPF/BTF.h
@@ -106,14 +106,14 @@ struct CommonType {
   /// Bits 24-27: kind (e.g. int, ptr, array...etc)
   /// Bits 28-30: unused
   /// Bit     31: kind_flag, currently used by
-  ///             struct, union and fwd
+  ///             struct, union, fwd and tag
   uint32_t Info;
 
   /// "Size" is used by INT, ENUM, STRUCT and UNION.
   /// "Size" tells the size of the type it is describing.
   ///
   /// "Type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
-  /// FUNC, FUNC_PROTO and VAR.
+  /// FUNC, FUNC_PROTO, VAR and TAG.
   /// "Type" is a type_id referring to another type.
   union {
     uint32_t Size;

diff  --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index c1f8ea99b959..c13e2dcf8c6f 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -386,6 +386,27 @@ void BTFTypeFloat::completeType(BTFDebug &BDebug) {
   BTFType.NameOff = BDebug.addString(Name);
 }
 
+BTFTypeTag::BTFTypeTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag)
+    : Tag(Tag) {
+  Kind = BTF::BTF_KIND_TAG;
+  BTFType.Info = ((ComponentId < 0) << 31) | (Kind << 24);
+  BTFType.Type = BaseTypeId;
+  Info = ComponentId < 0 ? 0 : ComponentId;
+}
+
+void BTFTypeTag::completeType(BTFDebug &BDebug) {
+  if (IsCompleted)
+    return;
+  IsCompleted = true;
+
+  BTFType.NameOff = BDebug.addString(Tag);
+}
+
+void BTFTypeTag::emitType(MCStreamer &OS) {
+  BTFTypeBase::emitType(OS);
+  OS.emitInt32(Info);
+}
+
 uint32_t BTFStringTable::addString(StringRef S) {
   // Check whether the string already exists.
   for (auto &OffsetM : OffsetToIdMap) {
@@ -475,6 +496,24 @@ void BTFDebug::visitSubroutineType(
   }
 }
 
+void BTFDebug::processAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,
+                                  int ComponentId) {
+  if (!Annotations)
+     return;
+
+  for (const Metadata *Annotation : Annotations->operands()) {
+    const MDNode *MD = cast<MDNode>(Annotation);
+    const MDString *Name = cast<MDString>(MD->getOperand(0));
+    if (!Name->getString().equals("btf_tag"))
+      continue;
+
+    const MDString *Value = cast<MDString>(MD->getOperand(1));
+    auto TypeEntry = std::make_unique<BTFTypeTag>(BaseTypeId, ComponentId,
+                                                  Value->getString());
+    addType(std::move(TypeEntry));
+  }
+}
+
 /// Handle structure/union types.
 void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
                                uint32_t &TypeId) {
@@ -498,9 +537,17 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
   StructTypes.push_back(TypeEntry.get());
   TypeId = addType(std::move(TypeEntry), CTy);
 
+  // Check struct/union annotations
+  processAnnotations(CTy->getAnnotations(), TypeId, -1);
+
   // Visit all struct members.
-  for (const auto *Element : Elements)
-    visitTypeEntry(cast<DIDerivedType>(Element));
+  int FieldNo = 0;
+  for (const auto *Element : Elements) {
+    const auto Elem = cast<DIDerivedType>(Element);
+    visitTypeEntry(Elem);
+    processAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
+    FieldNo++;
+  }
 }
 
 void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
@@ -964,6 +1011,17 @@ void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
       std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
   uint32_t FuncTypeId = addType(std::move(FuncTypeEntry));
 
+  // Process argument annotations.
+  for (const DINode *DN : SP->getRetainedNodes()) {
+    if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
+      uint32_t Arg = DV->getArg();
+      if (Arg)
+        processAnnotations(DV->getAnnotations(), FuncTypeId, Arg - 1);
+    }
+  }
+
+  processAnnotations(SP->getAnnotations(), FuncTypeId, -1);
+
   for (const auto &TypeEntry : TypeEntries)
     TypeEntry->completeType(*this);
 
@@ -1176,11 +1234,13 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
       continue;
 
     uint32_t GVTypeId = 0;
+    DIGlobalVariable *DIGlobal = nullptr;
     for (auto *GVE : GVs) {
+      DIGlobal = GVE->getVariable();
       if (SecName.startswith(".maps"))
-        visitMapDefType(GVE->getVariable()->getType(), GVTypeId);
+        visitMapDefType(DIGlobal->getType(), GVTypeId);
       else
-        visitTypeEntry(GVE->getVariable()->getType(), GVTypeId, false, false);
+        visitTypeEntry(DIGlobal->getType(), GVTypeId, false, false);
       break;
     }
 
@@ -1212,6 +1272,8 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
         std::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
     uint32_t VarId = addType(std::move(VarEntry));
 
+    processAnnotations(DIGlobal->getAnnotations(), VarId, -1);
+
     // An empty SecName means an extern variable without section attribute.
     if (SecName.empty())
       continue;
@@ -1306,6 +1368,9 @@ void BTFDebug::processFuncPrototypes(const Function *F) {
   auto FuncTypeEntry =
       std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
   uint32_t FuncId = addType(std::move(FuncTypeEntry));
+
+  processAnnotations(SP->getAnnotations(), FuncId, -1);
+
   if (F->hasSection()) {
     StringRef SecName = F->getSection();
 

diff  --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h
index 2fdcf8500b7f..c0e672c71989 100644
--- a/llvm/lib/Target/BPF/BTFDebug.h
+++ b/llvm/lib/Target/BPF/BTFDebug.h
@@ -204,6 +204,18 @@ class BTFTypeFloat : public BTFTypeBase {
   void completeType(BTFDebug &BDebug) override;
 };
 
+/// Handle tags.
+class BTFTypeTag : public BTFTypeBase {
+  uint32_t Info;
+  StringRef Tag;
+
+public:
+  BTFTypeTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag);
+  uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }
+  void completeType(BTFDebug &BDebug) override;
+  void emitType(MCStreamer &OS) override;
+};
+
 /// String table.
 class BTFStringTable {
   /// String table size in bytes.
@@ -313,6 +325,10 @@ class BTFDebug : public DebugHandlerBase {
   /// Generate types for function prototypes.
   void processFuncPrototypes(const Function *);
 
+  /// Generate types for annotations.
+  void processAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,
+                          int ComponentId);
+
   /// 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/tag-1.ll b/llvm/test/CodeGen/BPF/BTF/tag-1.ll
new file mode 100644
index 000000000000..dd31ecf0c98c
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/tag-1.ll
@@ -0,0 +1,91 @@
+; 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 code:
+;   #define __tag1 __attribute__((btf_tag("tag1")))
+;   #define __tag2 __attribute__((btf_tag("tag2")))
+;   struct t1 {
+;     int a1;
+;     int a2 __tag1 __tag2;
+;   } __tag1 __tag2;
+;   struct t1 g1 __tag1 __tag2;
+; Compilation flag:
+;   clang -target bpf -O2 -g -S -emit-llvm t.c
+
+%struct.t1 = type { i32, i32 }
+
+ at g1 = dso_local local_unnamed_addr global %struct.t1 zeroinitializer, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!14, !15, !16, !17}
+!llvm.ident = !{!18}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g1", scope: !2, file: !3, line: 7, type: !6, isLocal: false, isDefinition: true, annotations: !11)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 825661b8e31d0b29d78178df1e518949dfec9f9a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag")
+!4 = !{}
+!5 = !{!0}
+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 3, size: 64, elements: !7, annotations: !11)
+!7 = !{!8, !10}
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !6, file: !3, line: 4, baseType: !9, size: 32)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a2", scope: !6, file: !3, line: 5, baseType: !9, size: 32, offset: 32, annotations: !11)
+!11 = !{!12, !13}
+!12 = !{!"btf_tag", !"tag1"}
+!13 = !{!"btf_tag", !"tag2"}
+!14 = !{i32 7, !"Dwarf Version", i32 4}
+!15 = !{i32 2, !"Debug Info Version", i32 3}
+!16 = !{i32 1, !"wchar_size", i32 4}
+!17 = !{i32 7, !"frame-pointer", i32 2}
+!18 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 825661b8e31d0b29d78178df1e518949dfec9f9a)"}
+
+; CHECK:             .long   1                               # BTF_KIND_STRUCT(id = 1)
+; CHECK-NEXT:        .long   67108866                        # 0x4000002
+; CHECK-NEXT:        .long   8
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   0                               # 0x0
+; CHECK-NEXT:        .long   7
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   32                              # 0x20
+; CHECK-NEXT:        .long   10                              # BTF_KIND_TAG(id = 2)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   15                              # BTF_KIND_TAG(id = 3)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   20                              # BTF_KIND_INT(id = 4)
+; CHECK-NEXT:        .long   16777216                        # 0x1000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   16777248                        # 0x1000020
+; CHECK-NEXT:        .long   10                              # BTF_KIND_TAG(id = 5)
+; CHECK-NEXT:        .long   285212672                       # 0x11000000
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   15                              # BTF_KIND_TAG(id = 6)
+; CHECK-NEXT:        .long   285212672                       # 0x11000000
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   24                              # BTF_KIND_VAR(id = 7)
+; CHECK-NEXT:        .long   234881024                       # 0xe000000
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   10                              # BTF_KIND_TAG(id = 8)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   7
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   15                              # BTF_KIND_TAG(id = 9)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   7
+; CHECK-NEXT:        .long   0
+
+; CHECK:             .ascii  "t1"                            # string offset=1
+; CHECK:             .ascii  "a1"                            # string offset=4
+; CHECK:             .ascii  "a2"                            # string offset=7
+; CHECK:             .ascii  "tag1"                          # string offset=10
+; CHECK:             .ascii  "tag2"                          # string offset=15
+; CHECK:             .ascii  "int"                           # string offset=20
+; CHECK:             .ascii  "g1"                            # string offset=24

diff  --git a/llvm/test/CodeGen/BPF/BTF/tag-2.ll b/llvm/test/CodeGen/BPF/BTF/tag-2.ll
new file mode 100644
index 000000000000..9be1db672aaf
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/tag-2.ll
@@ -0,0 +1,125 @@
+; 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 code:
+;   #define __tag1 __attribute__((btf_tag("tag1")))
+;   #define __tag2 __attribute__((btf_tag("tag2")))
+;   extern int bar(int a1, int a2) __tag1 __tag2;
+;   int __tag1 foo(int arg1, int *arg2 __tag1) {
+; ;   return arg1 + *arg2 + bar(arg1, arg1 + 1);
+;   }
+; Compilation flag:
+;   clang -target bpf -O2 -g -S -emit-llvm t.c
+
+; Function Attrs: nounwind
+define dso_local i32 @foo(i32 %arg1, i32* nocapture readonly %arg2) local_unnamed_addr #0 !dbg !8 {
+entry:
+  call void @llvm.dbg.value(metadata i32 %arg1, metadata !14, metadata !DIExpression()), !dbg !18
+  call void @llvm.dbg.value(metadata i32* %arg2, metadata !15, metadata !DIExpression()), !dbg !18
+  %0 = load i32, i32* %arg2, align 4, !dbg !19, !tbaa !20
+  %add = add nsw i32 %0, %arg1, !dbg !24
+  %add1 = add nsw i32 %arg1, 1, !dbg !25
+  %call = tail call i32 @bar(i32 %arg1, i32 %add1) #3, !dbg !26
+  %add2 = add nsw i32 %add, %call, !dbg !27
+  ret i32 %add2, !dbg !28
+}
+
+declare !dbg !29 dso_local i32 @bar(i32, i32) local_unnamed_addr #1
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2
+
+attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { nofree nosync nounwind readnone speculatable willreturn }
+attributes #3 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 4be11596b26383c6666f471f07463a3f79e11964)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 7, !"frame-pointer", i32 2}
+!7 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 4be11596b26383c6666f471f07463a3f79e11964)"}
+!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !9, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13, annotations: !16)
+!9 = !DISubroutineType(types: !10)
+!10 = !{!11, !11, !12}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
+!13 = !{!14, !15}
+!14 = !DILocalVariable(name: "arg1", arg: 1, scope: !8, file: !1, line: 4, type: !11)
+!15 = !DILocalVariable(name: "arg2", arg: 2, scope: !8, file: !1, line: 4, type: !12, annotations: !16)
+!16 = !{!17}
+!17 = !{!"btf_tag", !"tag1"}
+!18 = !DILocation(line: 0, scope: !8)
+!19 = !DILocation(line: 5, column: 17, scope: !8)
+!20 = !{!21, !21, i64 0}
+!21 = !{!"int", !22, i64 0}
+!22 = !{!"omnipotent char", !23, i64 0}
+!23 = !{!"Simple C/C++ TBAA"}
+!24 = !DILocation(line: 5, column: 15, scope: !8)
+!25 = !DILocation(line: 5, column: 40, scope: !8)
+!26 = !DILocation(line: 5, column: 25, scope: !8)
+!27 = !DILocation(line: 5, column: 23, scope: !8)
+!28 = !DILocation(line: 5, column: 3, scope: !8)
+!29 = !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !30, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2, annotations: !32)
+!30 = !DISubroutineType(types: !31)
+!31 = !{!11, !11, !11}
+!32 = !{!17, !33}
+!33 = !{!"btf_tag", !"tag2"}
+
+; CHECK:             .long   1                               # BTF_KIND_INT(id = 1)
+; CHECK-NEXT:        .long   16777216                        # 0x1000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   16777248                        # 0x1000020
+; CHECK-NEXT:        .long   0                               # BTF_KIND_PTR(id = 2)
+; CHECK-NEXT:        .long   33554432                        # 0x2000000
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0                               # BTF_KIND_FUNC_PROTO(id = 3)
+; CHECK-NEXT:        .long   218103810                       # 0xd000002
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   5
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   10
+; CHECK-NEXT:        .long   2
+; CHECK-NEXT:        .long   15                              # BTF_KIND_FUNC(id = 4)
+; CHECK-NEXT:        .long   201326593                       # 0xc000001
+; CHECK-NEXT:        .long   3
+; CHECK-NEXT:        .long   19                              # BTF_KIND_TAG(id = 5)
+; CHECK-NEXT:        .long   285212672                       # 0x11000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   19                              # BTF_KIND_TAG(id = 6)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   0                               # BTF_KIND_FUNC_PROTO(id = 7)
+; CHECK-NEXT:        .long   218103810                       # 0xd000002
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   72                              # BTF_KIND_FUNC(id = 8)
+; CHECK-NEXT:        .long   201326594                       # 0xc000002
+; CHECK-NEXT:        .long   7
+; CHECK-NEXT:        .long   19                              # BTF_KIND_TAG(id = 9)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   8
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   76                              # BTF_KIND_TAG(id = 10)
+; CHECK-NEXT:        .long   2432696320                      # 0x91000000
+; CHECK-NEXT:        .long   8
+
+; CHECK:             .ascii  "int"                           # string offset=1
+; CHECK:             .ascii  "arg1"                          # string offset=5
+; CHECK:             .ascii  "arg2"                          # string offset=10
+; CHECK:             .ascii  "foo"                           # string offset=15
+; CHECK:             .ascii  "tag1"                          # string offset=19
+; CHECK:             .ascii  "bar"                           # string offset=72
+; CHECK:             .ascii  "tag2"                          # string offset=76


        


More information about the llvm-commits mailing list