[Mlir-commits] [mlir] [MLIR][DebugInfo] Set debug info format in MLIR->IR translation (PR #95329)
Stephen Tozer
llvmlistbot at llvm.org
Wed Jun 12 16:17:08 PDT 2024
https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/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 https://github.com/llvm/llvm-project/pull/95098 which can be landed once the flang frontend has been updated by https://github.com/llvm/llvm-project/pull/95306. This is the counterpart to the earlier patch https://github.com/llvm/llvm-project/pull/89735 which handled the IR->MLIR conversion.
>From 66adcc0d3404f59e81b34865346582da0f7a32e1 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Wed, 12 Jun 2024 10:52:32 +0100
Subject: [PATCH] [MLIR][DebugInfo] Set debug info format in MLIR->IR
translation
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.
---
mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp | 10 ++++++
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 10 ++++++
mlir/test/Target/LLVMIR/llvmir-debug.mlir | 33 ++++++++++++-------
.../Dialect/Test/TestToLLVMIRTranslation.cpp | 10 ++++++
4 files changed, 52 insertions(+), 11 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
index 4558893779534..be3b36c762055 100644
--- a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
@@ -16,9 +16,12 @@
#include "mlir/Target/LLVMIR/Dialect/All.h"
#include "mlir/Target/LLVMIR/Export.h"
#include "mlir/Tools/mlir-translate/Translation.h"
+#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+extern llvm::cl::opt<bool> WriteNewDbgInfoFormat;
+
using namespace mlir;
namespace mlir {
@@ -31,6 +34,13 @@ void registerToLLVMIRTranslation() {
if (!llvmModule)
return failure();
+ // When printing LLVM IR, we should convert the module to the debug info
+ // format that LLVM expects us to print.
+ // See https://llvm.org/docs/RemoveDIsDebugInfo.html
+ llvm::ScopedDbgInfoFormatSetter FormatSetter(*llvmModule,
+ WriteNewDbgInfoFormat);
+ if (WriteNewDbgInfoFormat)
+ llvmModule->removeDebugIntrinsicDeclarations();
llvmModule->print(output, nullptr);
return success();
},
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 5ee94dbec8736..6e8b2dec75b71 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -64,6 +64,8 @@ using namespace mlir;
using namespace mlir::LLVM;
using namespace mlir::LLVM::detail;
+extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
+
#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
namespace {
@@ -1801,6 +1803,9 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
StringRef name) {
m->getContext()->getOrLoadDialect<LLVM::LLVMDialect>();
auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
+ // ModuleTranslation can currently only construct modules in the old debug
+ // info format, so set the flag accordingly.
+ llvmModule->setNewDbgInfoFormatFlag(false);
if (auto dataLayoutAttr =
m->getDiscardableAttr(LLVM::LLVMDialect::getDataLayoutAttrName())) {
llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
@@ -1879,6 +1884,11 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
if (failed(translator.convertFunctions()))
return nullptr;
+ // Once we've finished constructing elements in the module, we should convert
+ // it to use the debug info format desired by LLVM.
+ // See https://llvm.org/docs/RemoveDIsDebugInfo.html
+ translator.llvmModule->setIsNewDbgInfoFormat(UseNewDbgInfoFormat);
+
if (!disableVerification &&
llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
return nullptr;
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index c6e7ca6f3f21d..019e3565c3577 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -1,4 +1,5 @@
-// RUN: mlir-translate -mlir-to-llvmir --split-input-file %s | FileCheck %s
+// RUN: mlir-translate -mlir-to-llvmir --write-experimental-debuginfo=false --split-input-file %s | FileCheck %s --check-prefixes=CHECK,INTRINSICS
+// RUN: mlir-translate -mlir-to-llvmir --write-experimental-debuginfo=true --split-input-file %s | FileCheck %s --check-prefixes=CHECK,RECORDS
// CHECK-LABEL: define void @func_with_empty_named_info()
// Check that translation doens't crash in the presence of an inlineble call
@@ -98,13 +99,16 @@ llvm.func @func_with_debug(%arg: i64) {
%allocCount = llvm.mlir.constant(1 : i32) : i32
%alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr
- // CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 1))
+ // INTRINSICS: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 1))
+ // RECORDS: #dbg_value(i64 %[[ARG]], ![[VAR_LOC:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 1), !{{.*}})
llvm.intr.dbg.value #variable #llvm.di_expression<[DW_OP_LLVM_fragment(0, 1)]> = %arg : i64
- // 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))
+ // 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))
+ // RECORDS: #dbg_declare(ptr %[[ALLOC]], ![[ADDR_LOC:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 4, DW_ATE_signed), !{{.*}})
llvm.intr.dbg.declare #variableAddr #llvm.di_expression<[DW_OP_deref, DW_OP_LLVM_convert(4, DW_ATE_signed)]> = %alloc : !llvm.ptr
- // CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[NO_NAME_VAR:[0-9]+]], metadata !DIExpression())
+ // INTRINSICS: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[NO_NAME_VAR:[0-9]+]], metadata !DIExpression())
+ // RECORDS: #dbg_value(i64 %[[ARG]], ![[NO_NAME_VAR:[0-9]+]], !DIExpression(), !{{.*}})
llvm.intr.dbg.value #noNameVariable = %arg : i64
// 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
// CHECK-LABEL: define i32 @func_with_inlined_dbg_value(
// CHECK-SAME: i32 %[[ARG:.*]]) !dbg ![[OUTER_FUNC:[0-9]+]]
llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
- // CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC0:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
+ // INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC0:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
+ // RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC0:[0-9]+]], !DIExpression(), ![[DBG_LOC0:.*]])
llvm.intr.dbg.value #di_local_variable0 = %arg0 : i32 loc(fused<#di_subprogram>[#loc0])
- // CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC1:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC1:.*]]
+ // INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC1:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC1:.*]]
+ // RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC1:[0-9]+]], !DIExpression(), ![[DBG_LOC1:.*]])
llvm.intr.dbg.value #di_local_variable1 = %arg0 : i32 loc(#loc1)
- // CHECK: call void @llvm.dbg.label(metadata ![[LABEL:[0-9]+]]), !dbg ![[DBG_LOC1:.*]]
+ // INTRINSICS: call void @llvm.dbg.label(metadata ![[LABEL:[0-9]+]]), !dbg ![[DBG_LOC1:.*]]
+ // RECORDS: #dbg_label(![[LABEL:[0-9]+]], ![[DBG_LOC1:.*]])
llvm.intr.dbg.label #di_label loc(#loc1)
llvm.return %arg0 : i32
} loc(fused<#di_subprogram>["caller"])
@@ -254,7 +261,8 @@ llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
// CHECK-LABEL: define void @func_without_subprogram(
// CHECK-SAME: i32 %[[ARG:.*]])
llvm.func @func_without_subprogram(%0 : i32) {
- // CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
+ // INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
+ // RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC:[0-9]+]], !DIExpression(), ![[DBG_LOC0:.*]])
llvm.intr.dbg.value #di_local_variable = %0 : i32 loc(fused<#di_subprogram>[#loc])
llvm.return
}
@@ -285,11 +293,14 @@ llvm.func @func_without_subprogram(%0 : i32) {
llvm.func @dbg_intrinsics_with_no_location(%arg0: i32) -> (i32) {
%allocCount = llvm.mlir.constant(1 : i32) : i32
%alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr
- // CHECK-NOT: @llvm.dbg.value
+ // INTRINSICS-NOT: @llvm.dbg.value
+ // RECORDS-NOT: #dbg_value
llvm.intr.dbg.value #di_local_variable = %arg0 : i32
- // CHECK-NOT: @llvm.dbg.declare
+ // INTRINSICS-NOT: @llvm.dbg.declare
+ // RECORDS-NOT: #dbg_declare
llvm.intr.dbg.declare #declared_var = %alloc : !llvm.ptr
- // CHECK-NOT: @llvm.dbg.label
+ // INTRINSICS-NOT: @llvm.dbg.label
+ // RECORDS-NOT: #dbg_label
llvm.intr.dbg.label #di_label
llvm.return %arg0 : i32
}
diff --git a/mlir/test/lib/Dialect/Test/TestToLLVMIRTranslation.cpp b/mlir/test/lib/Dialect/Test/TestToLLVMIRTranslation.cpp
index 57e7d658fb501..813b4960faa94 100644
--- a/mlir/test/lib/Dialect/Test/TestToLLVMIRTranslation.cpp
+++ b/mlir/test/lib/Dialect/Test/TestToLLVMIRTranslation.cpp
@@ -22,6 +22,9 @@
#include "mlir/Tools/mlir-translate/Translation.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/IR/DebugProgramInstruction.h"
+
+extern llvm::cl::opt<bool> WriteNewDbgInfoFormat;
using namespace mlir;
@@ -122,6 +125,13 @@ void registerTestToLLVMIR() {
if (!llvmModule)
return failure();
+ // When printing LLVM IR, we should convert the module to the debug info
+ // format that LLVM expects us to print.
+ // See https://llvm.org/docs/RemoveDIsDebugInfo.html
+ llvm::ScopedDbgInfoFormatSetter FormatSetter(*llvmModule,
+ WriteNewDbgInfoFormat);
+ if (WriteNewDbgInfoFormat)
+ llvmModule->removeDebugIntrinsicDeclarations();
llvmModule->print(output, nullptr);
return success();
},
More information about the Mlir-commits
mailing list