[Mlir-commits] [mlir] be4b494 - [mlir][llvm] Import debug intrinsics from LLVMIR.
Tobias Gysi
llvmlistbot at llvm.org
Tue Nov 29 02:32:40 PST 2022
Author: Tobias Gysi
Date: 2022-11-29T12:31:54+02:00
New Revision: be4b49407e6968411a8013cdd439cff66acdf61a
URL: https://github.com/llvm/llvm-project/commit/be4b49407e6968411a8013cdd439cff66acdf61a
DIFF: https://github.com/llvm/llvm-project/commit/be4b49407e6968411a8013cdd439cff66acdf61a.diff
LOG: [mlir][llvm] Import debug intrinsics from LLVMIR.
Currently, the import of LLVMIR fails if the program contains debug
intrinsics. The revision adds support to import debug intrinsics that
have no debug expression attached and drops all debug intrinsics with a
non-empty debug expression. It also moves the existing debug intrinsics
into the "intr" namespace by deriving from LLVM_IntrOp.
Reviewed By: rriddle
Differential Revision: https://reviews.llvm.org/D138405
Added:
Modified:
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
mlir/test/Dialect/LLVMIR/debuginfo.mlir
mlir/test/Target/LLVMIR/Import/debug-info.ll
mlir/test/Target/LLVMIR/llvmir-debug.mlir
mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 6335cbcd8eadd..9557779992710 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -274,11 +274,11 @@ def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable",
let parameters = (ins
"DIScopeAttr":$scope,
"StringAttr":$name,
- "DIFileAttr":$file,
- "unsigned":$line,
- "unsigned":$arg,
- "unsigned":$alignInBits,
- "DITypeAttr":$type
+ OptionalParameter<"DIFileAttr">:$file,
+ OptionalParameter<"unsigned">:$line,
+ OptionalParameter<"unsigned">:$arg,
+ OptionalParameter<"unsigned">:$alignInBits,
+ OptionalParameter<"DITypeAttr">:$type
);
let builders = [
AttrBuilderWithInferredContext<(ins
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index bb2668790dbfb..d40c6d2685c52 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -262,7 +262,7 @@ def LLVM_CoroResumeOp : LLVM_IntrOp<"coro.resume", [], [], [], 0> {
// Debug function intrinsics.
//
-class LLVM_DbgIntrOp<string name> : LLVM_Op<name> {
+class LLVM_DbgIntrOp<string name, string argName> : LLVM_IntrOp<name, [], [], [], 0> {
let llvmBuilder = [{
llvm::Module *module = builder.GetInsertBlock()->getModule();
llvm::LLVMContext &ctx = module->getContext();
@@ -276,27 +276,34 @@ class LLVM_DbgIntrOp<string name> : LLVM_Op<name> {
llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, llvm::None)),
});
}];
+ let mlirBuilder = [{
+ // Drop all debug intrinsics with a non-empty debug expression.
+ // TODO: Stop dropping debug intrinsics once debug expressions are
+ // convertible to MLIR.
+ auto *dbgIntr = cast<llvm::DbgVariableIntrinsic>(inst);
+ if (dbgIntr->getExpression()->getNumElements() == 0)
+ $_builder.create<$_qualCppClassName>($_location,
+ $}] # argName # [{, $_var_attr($varInfo));
+ }];
+ let assemblyFormat = [{
+ qualified($varInfo) `=` $}] # argName #
+ [{ `:` qualified(type($}] # argName # [{)) attr-dict
+ }];
}
-def LLVM_DbgAddrOp : LLVM_DbgIntrOp<"dbg.addr"> {
+def LLVM_DbgAddrOp : LLVM_DbgIntrOp<"dbg.addr", "addr"> {
let summary = "Describe the current address of a local debug info variable.";
let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
-
- let assemblyFormat = "qualified($varInfo) `=` $addr `:` type($addr) attr-dict";
}
-def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare"> {
+def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr"> {
let summary = "Declare the address of a local debug info variable.";
let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
-
- let assemblyFormat = "qualified($varInfo) `=` $addr `:` type($addr) attr-dict";
}
-def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value"> {
+def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value"> {
let summary = "Describe the current value of a local debug info variable.";
let arguments = (ins LLVM_Type:$value, LLVM_DILocalVariableAttr:$varInfo);
-
- let assemblyFormat = "qualified($varInfo) `=` $value `:` type($value) attr-dict";
}
//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
index e821584c84457..1177ee751473a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
@@ -234,6 +234,7 @@ class LLVM_OpBase<Dialect dialect, string mnemonic, list<Trait> traits = []> :
// name matches the result name, by a reference to store the
// result of the newly created MLIR operation to;
// - $_int_attr - substituted by a call to an integer attribute matcher;
+ // - $_var_attr - substituted by a call to a variable attribute matcher;
// - $_resultType - substituted with the MLIR result type;
// - $_location - substituted with the MLIR location;
// - $_builder - substituted with the MLIR builder;
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index d193b9f530517..f151965baae01 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -372,7 +372,10 @@ class Importer {
SmallVector<Value> convertValues(ArrayRef<llvm::Value *> values);
/// Converts `value` to an integer attribute. Asserts if the conversion fails.
- IntegerAttr matchIntegerAttr(Value value);
+ IntegerAttr matchIntegerAttr(llvm::Value *value);
+
+ /// Converts `value` to a local variable attribute.
+ DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value);
/// Translates the debug location.
Location translateLoc(llvm::DILocation *loc) {
@@ -852,6 +855,12 @@ Value Importer::convertConstantExpr(llvm::Constant *constant) {
}
Value Importer::convertValue(llvm::Value *value) {
+ // A value may be wrapped as metadata, for example, when passed to a debug
+ // intrinsic. Unwrap these values before the conversion.
+ if (auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value))
+ if (auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata()))
+ value = node->getValue();
+
// Return the mapped value if it has been converted before.
if (valueMapping.count(value))
return lookupValue(value);
@@ -872,14 +881,20 @@ SmallVector<Value> Importer::convertValues(ArrayRef<llvm::Value *> values) {
return remapped;
}
-IntegerAttr Importer::matchIntegerAttr(Value value) {
+IntegerAttr Importer::matchIntegerAttr(llvm::Value *value) {
IntegerAttr integerAttr;
- bool success = matchPattern(value, m_Constant(&integerAttr));
+ bool success = matchPattern(convertValue(value), m_Constant(&integerAttr));
assert(success && "expected a constant value");
(void)success;
return integerAttr;
}
+DILocalVariableAttr Importer::matchLocalVariableAttr(llvm::Value *value) {
+ auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
+ auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
+ return debugImporter.translate(node);
+}
+
LogicalResult
Importer::convertBranchArgs(llvm::Instruction *branch, llvm::BasicBlock *target,
SmallVectorImpl<Value> &blockArguments) {
diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
index 07f8fb3801ae7..275e322b89819 100644
--- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir
+++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
@@ -81,16 +81,16 @@
file = #file, line = 4, scopeLine = 4, subprogramFlags = "Definition", type = #spType1
>
-// CHECK-DAG: #[[VAR0:.*]] = #llvm.di_local_variable<scope = #[[SP0]], name = "arg", file = #[[FILE]], line = 6, arg = 1, alignInBits = 0, type = #[[INT0]]>
+// CHECK-DAG: #[[VAR0:.*]] = #llvm.di_local_variable<scope = #[[SP0]], name = "alloc", file = #[[FILE]], line = 6, arg = 1, alignInBits = 32, type = #[[INT0]]>
#var0 = #llvm.di_local_variable<
- scope = #sp0, name = "arg", file = #file,
- line = 6, arg = 1, alignInBits = 0, type = #int0
+ scope = #sp0, name = "alloc", file = #file,
+ line = 6, arg = 1, alignInBits = 32, type = #int0
>
-// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable<scope = #[[SP1]], name = "arg", file = #[[FILE]], line = 7, arg = 2, alignInBits = 0, type = #[[INT1]]>
+// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable<scope = #[[SP1]], name = "arg">
#var1 = #llvm.di_local_variable<
- scope = #sp1, name = "arg", file = #file,
- line = 7, arg = 2, alignInBits = 0, type = #int1
+ // Omit the optional parameters.
+ scope = #sp1, name = "arg"
>
// CHECK: llvm.func @addr(%[[ARG:.*]]: i64)
@@ -99,16 +99,16 @@ llvm.func @addr(%arg: i64) {
%allocCount = llvm.mlir.constant(1 : i32) : i32
%alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr<i64>
- // CHECK: llvm.dbg.addr #[[VAR0]] = %[[ALLOC]]
- // CHECK: llvm.dbg.declare #[[VAR0]] = %[[ALLOC]]
- llvm.dbg.addr #var0 = %alloc : !llvm.ptr<i64>
- llvm.dbg.declare #var0 = %alloc : !llvm.ptr<i64>
+ // CHECK: llvm.intr.dbg.addr #[[VAR0]] = %[[ALLOC]]
+ // CHECK: llvm.intr.dbg.declare #[[VAR0]] = %[[ALLOC]]
+ llvm.intr.dbg.addr #var0 = %alloc : !llvm.ptr<i64>
+ llvm.intr.dbg.declare #var0 = %alloc : !llvm.ptr<i64>
llvm.return
}
// CHECK: llvm.func @value(%[[ARG:.*]]: i32)
llvm.func @value(%arg: i32) -> i32 {
- // CHECK: llvm.dbg.value #[[VAR1]] = %[[ARG]]
- llvm.dbg.value #var1 = %arg : i32
+ // CHECK: llvm.intr.dbg.value #[[VAR1]] = %[[ARG]]
+ llvm.intr.dbg.value #var1 = %arg : i32
llvm.return %arg : i32
}
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index aa0a07d1bd0d1..9cbc11bb49321 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -226,3 +226,43 @@ define void @func_loc() !dbg !3 {
; Verify the module location is set to the source filename.
; CHECK: loc("debug-info.ll":0:0)
source_filename = "debug-info.ll"
+
+; // -----
+
+; CHECK: #[[$SP:.+]] = #llvm.di_subprogram<
+; CHECK: #[[$VAR0:.+]] = #llvm.di_local_variable<scope = #[[$SP]], name = "arg", file = #{{.*}}, line = 1, arg = 1, alignInBits = 32, type = #{{.*}}>
+; CHECK: #[[$VAR1:.+]] = #llvm.di_local_variable<scope = #[[$SP]], name = "arg">
+
+; CHECK-LABEL: @intrinsic
+; CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]
+; CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]
+define void @intrinsic(i64 %0, ptr %1) {
+ ; CHECK: llvm.intr.dbg.value #[[$VAR0]] = %[[ARG0]] : i64 loc(#[[LOC0:.+]])
+ call void @llvm.dbg.value(metadata i64 %0, metadata !5, metadata !DIExpression()), !dbg !7
+ ; CHECK: llvm.intr.dbg.addr #[[$VAR1]] = %[[ARG1]] : !llvm.ptr loc(#[[LOC1:.+]])
+ call void @llvm.dbg.addr(metadata ptr %1, metadata !6, metadata !DIExpression()), !dbg !8
+ ; CHECK: llvm.intr.dbg.declare #[[$VAR1]] = %[[ARG1]] : !llvm.ptr loc(#[[LOC2:.+]])
+ call void @llvm.dbg.declare(metadata ptr %1, metadata !6, metadata !DIExpression()), !dbg !9
+ ret void
+}
+
+; CHECK: #[[LOC0]] = loc(fused<#[[$SP]]>["debug-info.ll":1:2])
+; CHECK: #[[LOC1]] = loc(fused<#[[$SP]]>["debug-info.ll":2:2])
+; CHECK: #[[LOC2]] = loc(fused<#[[$SP]]>["debug-info.ll":3:2])
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+declare void @llvm.dbg.addr(metadata, metadata, metadata)
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "intrinsic", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1)
+!4 = !DIBasicType(name: "int")
+!5 = !DILocalVariable(scope: !3, name: "arg", file: !2, line: 1, arg: 1, align: 32, type: !4);
+!6 = !DILocalVariable(scope: !3, name: "arg")
+!7 = !DILocation(line: 1, column: 2, scope: !3)
+!8 = !DILocation(line: 2, column: 2, scope: !3)
+!9 = !DILocation(line: 3, column: 2, scope: !3)
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 5026af97d9497..80a89d1f92a50 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -64,6 +64,7 @@ llvm.func @func_no_debug() {
>
#fileScope = #llvm.di_lexical_block_file<scope = #sp, file = #file, discriminator = 0>
#variable = #llvm.di_local_variable<scope = #fileScope, name = "arg", file = #file, line = 6, arg = 1, alignInBits = 0, type = #si64>
+#variableAddr = #llvm.di_local_variable<scope = #fileScope, name = "alloc">
// CHECK-LABEL: define void @func_with_debug(
// CHECK-SAME: i64 %[[ARG:.*]]) !dbg ![[FUNC_LOC:[0-9]+]]
@@ -73,11 +74,11 @@ llvm.func @func_with_debug(%arg: i64) {
%alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr<i64>
// CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression())
- // CHECK: call void @llvm.dbg.addr(metadata ptr %[[ALLOC]], metadata ![[VAR_LOC]], metadata !DIExpression())
- // CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[VAR_LOC]], metadata !DIExpression())
- llvm.dbg.value #variable = %arg : i64
- llvm.dbg.addr #variable = %alloc : !llvm.ptr<i64>
- llvm.dbg.declare #variable = %alloc : !llvm.ptr<i64>
+ // CHECK: call void @llvm.dbg.addr(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC:[0-9]+]], metadata !DIExpression())
+ // CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC]], metadata !DIExpression())
+ llvm.intr.dbg.value #variable = %arg : i64
+ llvm.intr.dbg.addr #variableAddr = %alloc : !llvm.ptr<i64>
+ llvm.intr.dbg.declare #variableAddr = %alloc : !llvm.ptr<i64>
// CHECK: call void @func_no_debug(), !dbg ![[CALLSITE_LOC:[0-9]+]]
llvm.call @func_no_debug() : () -> () loc(callsite("mysource.cc":3:4 at "mysource.cc":5:6))
@@ -116,6 +117,7 @@ llvm.func @func_with_debug(%arg: i64) {
// CHECK: ![[VAR_LOC]] = !DILocalVariable(name: "arg", arg: 1, scope: ![[VAR_SCOPE:.*]], file: ![[CU_FILE_LOC]], line: 6, type: ![[ARG_TYPE]])
// CHECK: ![[VAR_SCOPE]] = distinct !DILexicalBlockFile(scope: ![[FUNC_LOC]], file: ![[CU_FILE_LOC]], discriminator: 0)
+// CHECK: ![[ADDR_LOC]] = !DILocalVariable(name: "alloc", scope: ![[VAR_SCOPE:.*]])
// CHECK-DAG: ![[CALLSITE_LOC]] = !DILocation(line: 3, column: 4,
// CHECK-DAG: ![[FILE_LOC]] = !DILocation(line: 1, column: 2,
diff --git a/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp b/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
index b070e581a13cc..a7d9019b91325 100644
--- a/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
+++ b/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
@@ -237,18 +237,24 @@ static LogicalResult emitOneMLIRBuilder(const Record &record, raw_ostream &os,
return emitError(
record, "expected non-negative operand index for argument " + name);
}
- bool isVariadicOperand = isVariadicOperandName(op, name);
- auto result =
- isVariadicOperand
- ? formatv("convertValues(llvmOperands.drop_front({0}))", idx)
- : formatv("convertValue(llvmOperands[{0}])", idx);
- bs << result;
+ if (isAttributeName(op, name)) {
+ bs << formatv("llvmOperands[{0}]", idx);
+ } else {
+ bool isVariadicOperand = isVariadicOperandName(op, name);
+ auto result =
+ isVariadicOperand
+ ? formatv("convertValues(llvmOperands.drop_front({0}))", idx)
+ : formatv("convertValue(llvmOperands[{0}])", idx);
+ bs << result;
+ }
} else if (isResultName(op, name)) {
if (op.getNumResults() != 1)
return emitError(record, "expected op to have one result");
bs << formatv("mapValue(inst)");
} else if (name == "_int_attr") {
bs << "matchIntegerAttr";
+ } else if (name == "_var_attr") {
+ bs << "matchLocalVariableAttr";
} else if (name == "_resultType") {
bs << "convertType(inst->getType())";
} else if (name == "_location") {
More information about the Mlir-commits
mailing list