Skip to content

Add DILabel functions for LLVM-C #112840

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions llvm/include/llvm-c/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 regardless of optimization.
*
* @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.
*
Expand Down
41 changes: 41 additions & 0 deletions llvm/lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
22 changes: 14 additions & 8 deletions llvm/test/Bindings/llvm-c/debug_info_new_format.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: }
Expand Down Expand Up @@ -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)
21 changes: 19 additions & 2 deletions llvm/tools/llvm-c-test/debuginfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down
Loading