[DebugInfo] convert btf_tag attrs to annotations for DIComposite types
authorYonghong Song <yhs@fb.com>
Thu, 19 Aug 2021 22:23:09 +0000 (15:23 -0700)
committerYonghong Song <yhs@fb.com>
Fri, 20 Aug 2021 01:01:29 +0000 (18:01 -0700)
Clang patch D106614 added attribute btf_tag support. This patch
generates btf_tag annotations for DIComposite types.
Each btf_tag annotation is represented as a 2D array of
meta strings. Each record may have more than one
btf_tag annotations.

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

clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/test/CodeGen/attr-btf_tag-dicomposite-2.c [new file with mode: 0644]
clang/test/CodeGen/attr-btf_tag-dicomposite.c [new file with mode: 0644]

index 81c910f..967fa7f 100644 (file)
@@ -2063,6 +2063,17 @@ llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
   return CollectTemplateParams(TPList, TAList.asArray(), Unit);
 }
 
+llvm::DINodeArray CGDebugInfo::CollectBTFTagAnnotations(const Decl *D) {
+  SmallVector<llvm::Metadata *, 4> Annotations;
+  for (const auto *I : D->specific_attrs<BTFTagAttr>()) {
+    llvm::Metadata *Ops[2] = {
+        llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_tag")),
+        llvm::MDString::get(CGM.getLLVMContext(), I->getBTFTag())};
+    Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
+  }
+  return DBuilder.getOrCreateArray(Annotations);
+}
+
 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
   if (VTablePtrType)
     return VTablePtrType;
@@ -3435,9 +3446,13 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
         Flags |= llvm::DINode::FlagExportSymbols;
   }
 
+  llvm::DINodeArray Annotations = nullptr;
+  if (D->hasAttr<BTFTagAttr>())
+    Annotations = CollectBTFTagAnnotations(D);
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
       getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-      Flags, Identifier);
+      Flags, Identifier, Annotations);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.
index b01165f..c0674b4 100644 (file)
@@ -292,6 +292,9 @@ class CGDebugInfo {
   CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,
                            llvm::DIFile *F);
 
+  /// A helper function to collect debug info for btf_tag annotations.
+  llvm::DINodeArray CollectBTFTagAnnotations(const Decl *D);
+
   llvm::DIType *createFieldType(StringRef name, QualType type,
                                 SourceLocation loc, AccessSpecifier AS,
                                 uint64_t offsetInBits, uint32_t AlignInBits,
diff --git a/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c b/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c
new file mode 100644 (file)
index 0000000..ed937ec
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 __tag1 __tag2 t1;
+
+int foo(struct t1 *arg) {
+  return (int)(long)arg;
+}
+
+// CHECK: define dso_local i32 @foo(
+// CHECK-NOT: annotations
diff --git a/clang/test/CodeGen/attr-btf_tag-dicomposite.c b/clang/test/CodeGen/attr-btf_tag-dicomposite.c
new file mode 100644 (file)
index 0000000..514dc4e
--- /dev/null
@@ -0,0 +1,52 @@
+// 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 __tag1 __tag2 t1;
+struct t1 {
+  int a;
+};
+
+int foo(struct t1 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT:[0-9]+]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}
+
+struct __tag1 t2;
+struct __tag2 t2 {
+  int a;
+};
+
+int foo2(struct t2 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT]])
+
+struct __tag1 t3;
+struct t3 {
+  int a;
+} __tag2;
+
+int foo3(struct t3 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t3", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT]])
+
+struct t4;
+struct t4 {
+  int a;
+} __tag1 __tag2;
+
+int foo4(struct t4 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t4", file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: ![[ANNOT]])