diff --git a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp index 45588937795348..92e786b130abb8 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 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 5ee94dbec87365..6e8b2dec75b716 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 UseNewDbgInfoFormat; + #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc" namespace { @@ -1801,6 +1803,9 @@ prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext, StringRef name) { m->getContext()->getOrLoadDialect(); auto llvmModule = std::make_unique(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(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 c6e7ca6f3f21d0..019e3565c3577d 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 57e7d658fb501f..157c6265be8346 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 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(); },