Skip to content

Commit 48f8d95

Browse files
authored
[MLIR][DebugInfo] Set debug info format in MLIR->IR translation (#95329)
MLIR's LLVM dialect does not internally support debug records, only converting to/from debug intrinsics. To smooth the transition from intrinsics to records, there is a step prior to IR->MLIR translation that switches the IR module to intrinsic-form; this patch adds the equivalent conversion to record-form at MLIR->IR translation. This is a partial reapply of #95098 which can be landed once the flang frontend has been updated by #95306. This is the counterpart to the earlier patch #89735 which handled the IR->MLIR conversion.
1 parent 91a55cf commit 48f8d95

File tree

4 files changed

+52
-11
lines changed

4 files changed

+52
-11
lines changed

mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
#include "mlir/Target/LLVMIR/Dialect/All.h"
1717
#include "mlir/Target/LLVMIR/Export.h"
1818
#include "mlir/Tools/mlir-translate/Translation.h"
19+
#include "llvm/IR/DebugProgramInstruction.h"
1920
#include "llvm/IR/LLVMContext.h"
2021
#include "llvm/IR/Module.h"
2122

23+
extern llvm::cl::opt<bool> WriteNewDbgInfoFormat;
24+
2225
using namespace mlir;
2326

2427
namespace mlir {
@@ -31,6 +34,13 @@ void registerToLLVMIRTranslation() {
3134
if (!llvmModule)
3235
return failure();
3336

37+
// When printing LLVM IR, we should convert the module to the debug info
38+
// format that LLVM expects us to print.
39+
// See https://llvm.org/docs/RemoveDIsDebugInfo.html
40+
llvm::ScopedDbgInfoFormatSetter formatSetter(*llvmModule,
41+
WriteNewDbgInfoFormat);
42+
if (WriteNewDbgInfoFormat)
43+
llvmModule->removeDebugIntrinsicDeclarations();
3444
llvmModule->print(output, nullptr);
3545
return success();
3646
},

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ using namespace mlir;
6464
using namespace mlir::LLVM;
6565
using namespace mlir::LLVM::detail;
6666

67+
extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
68+
6769
#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
6870

6971
namespace {
@@ -1801,6 +1803,9 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
18011803
StringRef name) {
18021804
m->getContext()->getOrLoadDialect<LLVM::LLVMDialect>();
18031805
auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
1806+
// ModuleTranslation can currently only construct modules in the old debug
1807+
// info format, so set the flag accordingly.
1808+
llvmModule->setNewDbgInfoFormatFlag(false);
18041809
if (auto dataLayoutAttr =
18051810
m->getDiscardableAttr(LLVM::LLVMDialect::getDataLayoutAttrName())) {
18061811
llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
@@ -1879,6 +1884,11 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
18791884
if (failed(translator.convertFunctions()))
18801885
return nullptr;
18811886

1887+
// Once we've finished constructing elements in the module, we should convert
1888+
// it to use the debug info format desired by LLVM.
1889+
// See https://llvm.org/docs/RemoveDIsDebugInfo.html
1890+
translator.llvmModule->setIsNewDbgInfoFormat(UseNewDbgInfoFormat);
1891+
18821892
if (!disableVerification &&
18831893
llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
18841894
return nullptr;

mlir/test/Target/LLVMIR/llvmir-debug.mlir

+22-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: mlir-translate -mlir-to-llvmir --split-input-file %s | FileCheck %s
1+
// RUN: mlir-translate -mlir-to-llvmir --write-experimental-debuginfo=false --split-input-file %s | FileCheck %s --check-prefixes=CHECK,INTRINSICS
2+
// RUN: mlir-translate -mlir-to-llvmir --write-experimental-debuginfo=true --split-input-file %s | FileCheck %s --check-prefixes=CHECK,RECORDS
23

34
// CHECK-LABEL: define void @func_with_empty_named_info()
45
// Check that translation doens't crash in the presence of an inlineble call
@@ -98,13 +99,16 @@ llvm.func @func_with_debug(%arg: i64) {
9899
%allocCount = llvm.mlir.constant(1 : i32) : i32
99100
%alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr
100101

101-
// CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 1))
102+
// INTRINSICS: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 1))
103+
// RECORDS: #dbg_value(i64 %[[ARG]], ![[VAR_LOC:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 1), !{{.*}})
102104
llvm.intr.dbg.value #variable #llvm.di_expression<[DW_OP_LLVM_fragment(0, 1)]> = %arg : i64
103105

104-
// CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 4, DW_ATE_signed))
106+
// INTRINSICS: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 4, DW_ATE_signed))
107+
// RECORDS: #dbg_declare(ptr %[[ALLOC]], ![[ADDR_LOC:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 4, DW_ATE_signed), !{{.*}})
105108
llvm.intr.dbg.declare #variableAddr #llvm.di_expression<[DW_OP_deref, DW_OP_LLVM_convert(4, DW_ATE_signed)]> = %alloc : !llvm.ptr
106109

107-
// CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[NO_NAME_VAR:[0-9]+]], metadata !DIExpression())
110+
// INTRINSICS: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[NO_NAME_VAR:[0-9]+]], metadata !DIExpression())
111+
// RECORDS: #dbg_value(i64 %[[ARG]], ![[NO_NAME_VAR:[0-9]+]], !DIExpression(), !{{.*}})
108112
llvm.intr.dbg.value #noNameVariable = %arg : i64
109113

110114
// CHECK: call void @func_no_debug(), !dbg ![[FILE_LOC:[0-9]+]]
@@ -219,11 +223,14 @@ llvm.func @func_decl_with_subprogram() -> (i32) loc(fused<#di_subprogram>["foo.m
219223
// CHECK-LABEL: define i32 @func_with_inlined_dbg_value(
220224
// CHECK-SAME: i32 %[[ARG:.*]]) !dbg ![[OUTER_FUNC:[0-9]+]]
221225
llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
222-
// CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC0:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
226+
// INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC0:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
227+
// RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC0:[0-9]+]], !DIExpression(), ![[DBG_LOC0:.*]])
223228
llvm.intr.dbg.value #di_local_variable0 = %arg0 : i32 loc(fused<#di_subprogram>[#loc0])
224-
// CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC1:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC1:.*]]
229+
// INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC1:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC1:.*]]
230+
// RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC1:[0-9]+]], !DIExpression(), ![[DBG_LOC1:.*]])
225231
llvm.intr.dbg.value #di_local_variable1 = %arg0 : i32 loc(#loc1)
226-
// CHECK: call void @llvm.dbg.label(metadata ![[LABEL:[0-9]+]]), !dbg ![[DBG_LOC1:.*]]
232+
// INTRINSICS: call void @llvm.dbg.label(metadata ![[LABEL:[0-9]+]]), !dbg ![[DBG_LOC1:.*]]
233+
// RECORDS: #dbg_label(![[LABEL:[0-9]+]], ![[DBG_LOC1:.*]])
227234
llvm.intr.dbg.label #di_label loc(#loc1)
228235
llvm.return %arg0 : i32
229236
} loc(fused<#di_subprogram>["caller"])
@@ -254,7 +261,8 @@ llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
254261
// CHECK-LABEL: define void @func_without_subprogram(
255262
// CHECK-SAME: i32 %[[ARG:.*]])
256263
llvm.func @func_without_subprogram(%0 : i32) {
257-
// CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
264+
// INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
265+
// RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC:[0-9]+]], !DIExpression(), ![[DBG_LOC0:.*]])
258266
llvm.intr.dbg.value #di_local_variable = %0 : i32 loc(fused<#di_subprogram>[#loc])
259267
llvm.return
260268
}
@@ -285,11 +293,14 @@ llvm.func @func_without_subprogram(%0 : i32) {
285293
llvm.func @dbg_intrinsics_with_no_location(%arg0: i32) -> (i32) {
286294
%allocCount = llvm.mlir.constant(1 : i32) : i32
287295
%alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr
288-
// CHECK-NOT: @llvm.dbg.value
296+
// INTRINSICS-NOT: @llvm.dbg.value
297+
// RECORDS-NOT: #dbg_value
289298
llvm.intr.dbg.value #di_local_variable = %arg0 : i32
290-
// CHECK-NOT: @llvm.dbg.declare
299+
// INTRINSICS-NOT: @llvm.dbg.declare
300+
// RECORDS-NOT: #dbg_declare
291301
llvm.intr.dbg.declare #declared_var = %alloc : !llvm.ptr
292-
// CHECK-NOT: @llvm.dbg.label
302+
// INTRINSICS-NOT: @llvm.dbg.label
303+
// RECORDS-NOT: #dbg_label
293304
llvm.intr.dbg.label #di_label
294305
llvm.return %arg0 : i32
295306
}

mlir/test/lib/Dialect/Test/TestToLLVMIRTranslation.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include "mlir/Tools/mlir-translate/Translation.h"
2323
#include "llvm/ADT/StringSwitch.h"
2424
#include "llvm/ADT/TypeSwitch.h"
25+
#include "llvm/IR/DebugProgramInstruction.h"
26+
27+
extern llvm::cl::opt<bool> WriteNewDbgInfoFormat;
2528

2629
using namespace mlir;
2730

@@ -122,6 +125,13 @@ void registerTestToLLVMIR() {
122125
if (!llvmModule)
123126
return failure();
124127

128+
// When printing LLVM IR, we should convert the module to the debug info
129+
// format that LLVM expects us to print.
130+
// See https://llvm.org/docs/RemoveDIsDebugInfo.html
131+
llvm::ScopedDbgInfoFormatSetter formatSetter(*llvmModule,
132+
WriteNewDbgInfoFormat);
133+
if (WriteNewDbgInfoFormat)
134+
llvmModule->removeDebugIntrinsicDeclarations();
125135
llvmModule->print(output, nullptr);
126136
return success();
127137
},

0 commit comments

Comments
 (0)