[llvm] Add DILabel functions for LLVM-C (PR #112840)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 18 20:11:38 PDT 2024


https://github.com/tf2spi updated https://github.com/llvm/llvm-project/pull/112840

>From 01f2dabcd61f306da2c4265113eaac61715f5f26 Mon Sep 17 00:00:00 2001
From: Misomosi <misomosispi at gmail.com>
Date: Fri, 18 Oct 2024 01:22:51 -0400
Subject: [PATCH 1/2] Add DILabel functions for LLVM-C

---
 llvm/include/llvm-c/DebugInfo.h | 46 +++++++++++++++++++++++++++++++++
 llvm/lib/IR/DebugInfo.cpp       | 41 +++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h
index 6d8891e7057722..0a3ccbb9613587 100644
--- a/llvm/include/llvm-c/DebugInfo.h
+++ b/llvm/include/llvm-c/DebugInfo.h
@@ -1415,6 +1415,52 @@ LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst);
  */
 void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc);
 
+/**
+ * Create a new descriptor for a label
+ *
+ * \param Builder         The DIBuilder.
+ * \param Scope           The scope to create the label in.
+ * \param Name            Variable name.
+ * \param NameLen         Length of variable name.
+ * \param File            The file to create the label in.
+ * \param LineNo          Line Number.
+ * \param AlwaysPreserve  Preserve the label even if the optimizer wants to remove it.
+ *
+ * @see llvm::DIBuilder::createLabel()
+ */
+LLVMMetadataRef LLVMDIBuilderCreateLabel(
+    LLVMDIBuilderRef Builder,
+    LLVMMetadataRef Context, const char *Name, size_t NameLen,
+    LLVMMetadataRef File, unsigned LineNo, LLVMBool AlwaysPreserve);
+
+/**
+ * Insert a new llvm.dbg.label intrinsic call
+ *
+ * \param Builder         The DIBuilder.
+ * \param LabelInfo       The Label's debug info descriptor
+ * \param Location        The debug info location
+ * \param InsertBefore    Location for the new intrinsic.
+ *
+ * @see llvm::DIBuilder::insertLabel()
+ */
+LLVMDbgRecordRef LLVMDIBuilderInsertLabelBefore(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef LabelInfo,
+    LLVMMetadataRef Location, LLVMValueRef InsertBefore);
+
+/**
+ * Insert a new llvm.dbg.label intrinsic call
+ *
+ * \param Builder         The DIBuilder.
+ * \param LabelInfo       The Label's debug info descriptor
+ * \param Location        The debug info location
+ * \param InsertAtEnd     Location for the new intrinsic.
+ *
+ * @see llvm::DIBuilder::insertLabel()
+ */
+LLVMDbgRecordRef LLVMDIBuilderInsertLabelAtEnd(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef LabelInfo,
+    LLVMMetadataRef Location, LLVMBasicBlockRef InsertAtEnd);
+
 /**
  * Obtain the enumerated type of a Metadata instance.
  *
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 50b29ae4f41676..e20a0f053481ed 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -1799,6 +1799,47 @@ void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc) {
     unwrap<Instruction>(Inst)->setDebugLoc(DebugLoc());
 }
 
+LLVMMetadataRef LLVMDIBuilderCreateLabel(
+    LLVMDIBuilderRef Builder,
+    LLVMMetadataRef Context, const char *Name, size_t NameLen,
+    LLVMMetadataRef File, unsigned LineNo, LLVMBool AlwaysPreserve) {
+  return wrap(unwrap(Builder)->createLabel(
+    unwrapDI<DIScope>(Context), StringRef(Name, NameLen),
+    unwrapDI<DIFile>(File), LineNo, AlwaysPreserve));
+}
+
+LLVMDbgRecordRef LLVMDIBuilderInsertLabelBefore(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef LabelInfo,
+    LLVMMetadataRef Location, LLVMValueRef InsertBefore) {
+  DbgInstPtr DbgInst = unwrap(Builder)->insertLabel(
+    unwrapDI<DILabel>(LabelInfo), unwrapDI<DILocation>(Location),
+    unwrap<Instruction>(InsertBefore));
+  // This assert will fail if the module is in the old debug info format.
+  // This function should only be called if the module is in the new
+  // debug info format.
+  // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,
+  // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.
+  assert(isa<DbgRecord *>(DbgInst) &&
+         "Function unexpectedly in old debug info format");
+  return wrap(cast<DbgRecord *>(DbgInst));
+}
+
+LLVMDbgRecordRef LLVMDIBuilderInsertLabelAtEnd(
+    LLVMDIBuilderRef Builder, LLVMMetadataRef LabelInfo,
+    LLVMMetadataRef Location, LLVMBasicBlockRef InsertAtEnd) {
+  DbgInstPtr DbgInst = unwrap(Builder)->insertLabel(
+    unwrapDI<DILabel>(LabelInfo), unwrapDI<DILocation>(Location),
+    unwrap(InsertAtEnd));
+  // This assert will fail if the module is in the old debug info format.
+  // This function should only be called if the module is in the new
+  // debug info format.
+  // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes,
+  // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info.
+  assert(isa<DbgRecord *>(DbgInst) &&
+         "Function unexpectedly in old debug info format");
+  return wrap(cast<DbgRecord *>(DbgInst));
+}
+
 LLVMMetadataKind LLVMGetMetadataKind(LLVMMetadataRef Metadata) {
   switch(unwrap(Metadata)->getMetadataID()) {
 #define HANDLE_METADATA_LEAF(CLASS) \

>From 73dffdaa91a87fc0b9c0ed8385bbd17c6fb65366 Mon Sep 17 00:00:00 2001
From: Misomosi <misomosispi at gmail.com>
Date: Fri, 18 Oct 2024 19:06:14 -0400
Subject: [PATCH 2/2] Add LLVM-C DILabel DebugInfo Tests

---
 llvm/include/llvm-c/DebugInfo.h               |  2 +-
 .../Bindings/llvm-c/debug_info_new_format.ll  | 22 ++++++++++++-------
 llvm/tools/llvm-c-test/debuginfo.c            | 21 ++++++++++++++++--
 3 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h
index 0a3ccbb9613587..f7d81636f4dd4e 100644
--- a/llvm/include/llvm-c/DebugInfo.h
+++ b/llvm/include/llvm-c/DebugInfo.h
@@ -1424,7 +1424,7 @@ void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc);
  * \param NameLen         Length of variable name.
  * \param File            The file to create the label in.
  * \param LineNo          Line Number.
- * \param AlwaysPreserve  Preserve the label even if the optimizer wants to remove it.
+ * \param AlwaysPreserve  Preserve the label regardless of optimization.
  *
  * @see llvm::DIBuilder::createLabel()
  */
diff --git a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll
index e7f537aa4f1a9a..a3f4bb2421fa26 100644
--- a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll
+++ b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll
@@ -6,15 +6,18 @@
 
 ; CHECK:      define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !31 {
 ; CHECK-NEXT: entry:
-; CHECK-NEXT:     #dbg_declare(i64 0, !38, !DIExpression(), !44)
-; CHECK-NEXT:     #dbg_declare(i64 0, !39, !DIExpression(), !44)
-; CHECK-NEXT:     #dbg_declare(i64 0, !40, !DIExpression(), !44)
+; CHECK-NEXT:     #dbg_declare(i64 0, !38, !DIExpression(), !45)
+; CHECK-NEXT:     #dbg_declare(i64 0, !39, !DIExpression(), !45)
+; CHECK-NEXT:     #dbg_declare(i64 0, !40, !DIExpression(), !45)
+; CHECK-NEXT:     #dbg_label(!46, !45)
+; CHECK-NEXT:   br label %vars
+; CHECK-NEXT:     #dbg_label(!47, !45)
 ; CHECK-NEXT:   br label %vars
 ; CHECK:      vars:
 ; CHECK-NEXT:   %p1 = phi i64 [ 0, %entry ]
 ; CHECK-NEXT:   %p2 = phi i64 [ 0, %entry ]
-; CHECK-NEXT:     #dbg_value(i64 0, !41, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !45)
-; CHECK-NEXT:     #dbg_value(i64 1, !43, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !45)
+; CHECK-NEXT:     #dbg_value(i64 0, !41, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !48)
+; CHECK-NEXT:     #dbg_value(i64 1, !43, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !48)
 ; CHECK-NEXT:   %a = add i64 %p1, %p2
 ; CHECK-NEXT:   ret i64 0
 ; CHECK-NEXT: }
@@ -60,12 +63,15 @@
 ; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !35)
 ; CHECK-NEXT: !35 = !{!36}
 ; CHECK-NEXT: !36 = !DISubrange(count: 10, lowerBound: 0)
-; CHECK-NEXT: !37 = !{!38, !39, !40, !41, !43}
+; CHECK-NEXT: !37 = !{!38, !39, !40, !41, !43, !44}
 ; CHECK-NEXT: !38 = !DILocalVariable(name: "a", arg: 1, scope: !31, file: !1, line: 42, type: !6)
 ; CHECK-NEXT: !39 = !DILocalVariable(name: "b", arg: 2, scope: !31, file: !1, line: 42, type: !6)
 ; CHECK-NEXT: !40 = !DILocalVariable(name: "c", arg: 3, scope: !31, file: !1, line: 42, type: !34)
 ; CHECK-NEXT: !41 = !DILocalVariable(name: "d", scope: !42, file: !1, line: 43, type: !6)
 ; CHECK-NEXT: !42 = distinct !DILexicalBlock(scope: !31, file: !1, line: 42)
 ; CHECK-NEXT: !43 = !DILocalVariable(name: "e", scope: !42, file: !1, line: 44, type: !6)
-; CHECK-NEXT: !44 = !DILocation(line: 42, scope: !31)
-; CHECK-NEXT: !45 = !DILocation(line: 43, scope: !31)
+; CHECK-NEXT: !44 = !DILabel(scope: !31, name: "label3", file: !1, line: 42)
+; CHECK-NEXT: !45 = !DILocation(line: 42, scope: !31)
+; CHECK-NEXT: !46 = !DILabel(scope: !31, name: "label1", file: !1, line: 42)
+; CHECK-NEXT: !47 = !DILabel(scope: !31, name: "label2", file: !1, line: 42)
+; CHECK-NEXT: !48 = !DILocation(line: 43, scope: !31)
diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c
index 942cbe5e5900e4..baf4ddfcc9a37b 100644
--- a/llvm/tools/llvm-c-test/debuginfo.c
+++ b/llvm/tools/llvm-c-test/debuginfo.c
@@ -163,6 +163,11 @@ int llvm_test_dibuilder(void) {
 
   LLVMSetSubprogram(FooFunction, FunctionMetadata);
 
+  LLVMMetadataRef FooLabel1 = LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
+    "label1", 6, File, 42, false);
+  LLVMDIBuilderInsertLabelAtEnd(DIB, FooLabel1, FooParamLocation,
+    FooEntryBlock);
+
   LLVMMetadataRef FooLexicalBlock =
     LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);
 
@@ -210,8 +215,6 @@ int llvm_test_dibuilder(void) {
   LLVMAddNamedMetadataOperand(
       M, "EnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), EnumTest));
 
-  LLVMDIBuilderFinalize(DIB);
-
   // Using the new debug format, debug records get attached to instructions.
   // Insert a `br` and `ret` now to absorb the debug records which are
   // currently "trailing", meaning that they're associated with a block
@@ -221,6 +224,20 @@ int llvm_test_dibuilder(void) {
   LLVMPositionBuilderAtEnd(Builder, FooEntryBlock);
   // Build `br label %vars` in entry.
   LLVMBuildBr(Builder, FooVarBlock);
+
+  // Build another br for the sake of testing labels.
+  LLVMMetadataRef FooLabel2 = LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
+    "label2", 6, File, 42, false);
+  LLVMDIBuilderInsertLabelBefore(DIB, FooLabel2, FooParamLocation,
+    LLVMBuildBr(Builder, FooVarBlock));
+  // label3 will be emitted, but label4 won't be emitted
+  // because label3 is AlwaysPreserve and label4 is not.
+  LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
+    "label3", 6, File, 42, true);
+  LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
+    "label4", 6, File, 42, false);
+  LLVMDIBuilderFinalize(DIB);
+
   // Build `ret i64 0` in vars.
   LLVMPositionBuilderAtEnd(Builder, FooVarBlock);
   LLVMTypeRef I64 = LLVMInt64TypeInContext(Ctx);



More information about the llvm-commits mailing list