Skip to content

Commit

Permalink
[MLIR] Add DIExpression to LLVM dialect (llvm#72462)
Browse files Browse the repository at this point in the history
Add initial support for DIExpression in LLVM dialect.

Similar to LLVM IR, DI Expression is encoded as a list of uint64. The
difference is that LLVM IR has helpers for understanding the expression
(e.g. for verification and pretty printing), whereas the current support
added by this PR treats the expression elements as opaque.
  • Loading branch information
zyx-billy authored Nov 16, 2023
1 parent 927f6f1 commit 0ab6b20
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 29 deletions.
11 changes: 11 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,17 @@ def LLVM_DITagParameter : LLVM_DIParameter<
"tag", /*default=*/"", "Tag"
>;

//===----------------------------------------------------------------------===//
// DIExpressionAttr
//===----------------------------------------------------------------------===//

// TODO: Implement custom printer/parser for elements so that operators are
// dumped in textual form.
def LLVM_DIExpressionAttr : ArrayOfAttr<LLVM_Dialect, "DIExpression",
"di_expr", "uint64_t"> {
let assemblyFormat = "`<` `[` (`]` `>`) : ($value^ `]` `>`)?";
}

//===----------------------------------------------------------------------===//
// DINullTypeAttr
//===----------------------------------------------------------------------===//
Expand Down
20 changes: 14 additions & 6 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
llvm::MetadataAsValue::get(ctx,
llvm::ValueAsMetadata::get(moduleTranslation.lookupValue(opInst.getOperand(0)))),
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($varInfo)),
llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, std::nullopt)),
llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, $locationExpr)),
});
}];
let mlirBuilder = [{
Expand All @@ -548,21 +548,29 @@ class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
return success();
}];
let assemblyFormat = [{
qualified($varInfo) `=` $}] # argName #
qualified($varInfo) (qualified($locationExpr)^)? `=` $}] # argName #
[{ `:` qualified(type($}] # argName # [{)) attr-dict
}];
}

def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr",
[DeclareOpInterfaceMethods<PromotableOpInterface>]> {
let summary = "Describes how the address relates to a source language variable.";
let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
let arguments = (ins
LLVM_AnyPointer:$addr,
LLVM_DILocalVariableAttr:$varInfo,
DefaultValuedAttr<LLVM_DIExpressionAttr, "std::nullopt">:$locationExpr
);
}

def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value",
[DeclareOpInterfaceMethods<PromotableOpInterface>]> {
let summary = "Describes how the value relates to a source language variable.";
let arguments = (ins LLVM_Type:$value, LLVM_DILocalVariableAttr:$varInfo);
let arguments = (ins
LLVM_Type:$value,
LLVM_DILocalVariableAttr:$varInfo,
DefaultValuedAttr<LLVM_DIExpressionAttr, "std::nullopt">:$locationExpr
);
}

def LLVM_DbgLabelOp : LLVM_IntrOp<"dbg.label", [], [], [], 0> {
Expand Down Expand Up @@ -660,8 +668,8 @@ class LLVM_VecReductionI<string mnem>
// LLVM vector reduction over a single vector, with an initial value,
// and with permission to reassociate the reduction operations.
class LLVM_VecReductionAccBase<string mnem, Type element>
: LLVM_OneResultIntrOp</*mnem=*/"vector.reduce." # mnem,
/*overloadedResults=*/[],
: LLVM_OneResultIntrOp</*mnem=*/"vector.reduce." # mnem,
/*overloadedResults=*/[],
/*overloadedOperands=*/[1],
/*traits=*/[Pure, SameOperandsAndResultElementType],
/*equiresFastmath=*/1>,
Expand Down
6 changes: 4 additions & 2 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ void LLVM::AllocaOp::handleBlockArgument(const MemorySlot &slot,
for (Operation *user : getOperation()->getUsers())
if (auto declareOp = llvm::dyn_cast<LLVM::DbgDeclareOp>(user))
rewriter.create<LLVM::DbgValueOp>(declareOp.getLoc(), argument,
declareOp.getVarInfo());
declareOp.getVarInfo(),
declareOp.getLocationExpr());
}

void LLVM::AllocaOp::handlePromotionComplete(const MemorySlot &slot,
Expand Down Expand Up @@ -174,7 +175,8 @@ DeletionKind LLVM::StoreOp::removeBlockingUses(
for (Operation *user : slot.ptr.getUsers())
if (auto declareOp = dyn_cast<LLVM::DbgDeclareOp>(user))
rewriter.create<LLVM::DbgValueOp>(declareOp->getLoc(), getValue(),
declareOp.getVarInfo());
declareOp.getVarInfo(),
declareOp.getLocationExpr());
return DeletionKind::Delete;
}

Expand Down
16 changes: 9 additions & 7 deletions mlir/lib/Target/LLVMIR/ModuleImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1819,9 +1819,9 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
emitWarning(loc) << "dropped intrinsic: " << diag(*dbgIntr);
return success();
};
// Drop debug intrinsics with a non-empty debug expression.
// TODO: Support debug intrinsics that evaluate a debug expression.
if (dbgIntr->hasArgList() || dbgIntr->getExpression()->getNumElements() != 0)
// Drop debug intrinsics with arg lists.
// TODO: Support debug intrinsics that have arg lists.
if (dbgIntr->hasArgList())
return emitUnsupportedWarning();
// Kill locations can have metadata nodes as location operand. This
// cannot be converted to poison as the type cannot be reconstructed.
Expand Down Expand Up @@ -1855,15 +1855,17 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
}
DILocalVariableAttr localVariableAttr =
matchLocalVariableAttr(dbgIntr->getArgOperand(1));
auto locationExprAttr =
DIExpressionAttr::get(context, dbgIntr->getExpression()->getElements());
Operation *op =
llvm::TypeSwitch<llvm::DbgVariableIntrinsic *, Operation *>(dbgIntr)
.Case([&](llvm::DbgDeclareInst *) {
return builder.create<LLVM::DbgDeclareOp>(loc, *argOperand,
localVariableAttr);
return builder.create<LLVM::DbgDeclareOp>(
loc, *argOperand, localVariableAttr, locationExprAttr);
})
.Case([&](llvm::DbgValueInst *) {
return builder.create<LLVM::DbgValueOp>(loc, *argOperand,
localVariableAttr);
return builder.create<LLVM::DbgValueOp>(
loc, *argOperand, localVariableAttr, locationExprAttr);
});
mapNoResultOp(dbgIntr, op);
setNonDebugMetadataAttrs(dbgIntr, op);
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Dialect/LLVMIR/debuginfo.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ llvm.func @addr(%arg: i64) {

// CHECK: llvm.func @value(%[[ARG1:.*]]: i32, %[[ARG2:.*]]: i32)
llvm.func @value(%arg1: i32, %arg2: i32) {
// CHECK: llvm.intr.dbg.value #[[VAR1]] = %[[ARG1]]
llvm.intr.dbg.value #var1 = %arg1 : i32
// CHECK: llvm.intr.dbg.value #[[VAR1]] #llvm.di_expr<[2, 4096, 0, 4]> = %[[ARG1]]
llvm.intr.dbg.value #var1 #llvm.di_expr<[2, 4096, 0, 4]> = %arg1 : i32
// CHECK: llvm.intr.dbg.value #[[VAR2]] = %[[ARG2]]
llvm.intr.dbg.value #var2 = %arg2 : i32
// CHECK: llvm.intr.dbg.label #[[LABEL1]]
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Target/LLVMIR/Import/debug-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ source_filename = "debug-info.ll"
; CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]
define void @intrinsic(i64 %0, ptr %1) {
; CHECK: llvm.intr.dbg.declare #[[$VAR1]] = %[[ARG1]] : !llvm.ptr loc(#[[LOC1:.+]])
; 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.value #[[$VAR0]] #llvm.di_expr<[4096, 0, 8]> = %[[ARG0]] : i64 loc(#[[LOC0:.+]])
call void @llvm.dbg.value(metadata i64 %0, metadata !5, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 8)), !dbg !7
call void @llvm.dbg.declare(metadata ptr %1, metadata !6, metadata !DIExpression()), !dbg !9
; CHECK: llvm.intr.dbg.label #[[$LABEL]] loc(#[[LOC1:.+]])
call void @llvm.dbg.label(metadata !10), !dbg !9
Expand Down
3 changes: 0 additions & 3 deletions mlir/test/Target/LLVMIR/Import/import-failure.ll
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,11 @@ define void @unhandled_intrinsic() gc "example" {

declare void @llvm.dbg.value(metadata, metadata, metadata)

; CHECK: import-failure.ll
; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata i64 %arg1, metadata !3, metadata !DIExpression(DW_OP_plus_uconst, 42, DW_OP_stack_value)), !dbg !5
; CHECK: import-failure.ll
; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !DIArgList(i64 %arg1, i64 undef), metadata !3, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value)), !dbg !5
; CHECK: import-failure.ll
; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression()), !dbg !5
define void @dropped_instruction(i64 %arg1) {
call void @llvm.dbg.value(metadata i64 %arg1, metadata !3, metadata !DIExpression(DW_OP_plus_uconst, 42, DW_OP_stack_value)), !dbg !5
call void @llvm.dbg.value(metadata !DIArgList(i64 %arg1, i64 undef), metadata !3, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value)), !dbg !5
call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression()), !dbg !5
ret void
Expand Down
12 changes: 6 additions & 6 deletions mlir/test/Target/LLVMIR/llvmir-debug.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ llvm.func @func_no_debug() {
#variableAddr = #llvm.di_local_variable<scope = #blockScope, name = "alloc">
#noNameVariable = #llvm.di_local_variable<scope = #blockScope>
#module = #llvm.di_module<
file = #file, scope = #file, name = "module",
file = #file, scope = #file, name = "module",
configMacros = "bar", includePath = "/",
apinotes = "/", line = 42, isDecl = true
>
Expand All @@ -91,12 +91,12 @@ 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())
// CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC:[0-9]+]], metadata !DIExpression())
// CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 8, 8))
// CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 8))
// CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[NO_NAME_VAR:[0-9]+]], metadata !DIExpression())
llvm.intr.dbg.value #variable = %arg : i64
llvm.intr.dbg.declare #variableAddr = %alloc : !llvm.ptr
llvm.intr.dbg.value #noNameVariable= %arg : i64
llvm.intr.dbg.value #variable #llvm.di_expr<[4096, 8, 8]> = %arg : i64
llvm.intr.dbg.declare #variableAddr #llvm.di_expr<[4096, 0, 8]> = %alloc : !llvm.ptr
llvm.intr.dbg.value #noNameVariable = %arg : 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))
Expand Down
2 changes: 1 addition & 1 deletion mlir/test/mlir-translate/import-diagnostics.ll
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
; DEFAULT-NOT: warning:
; EXPENSIVE: warning:
define void @dropped_instruction(i64 %arg1) {
call void @llvm.dbg.value(metadata i64 %arg1, metadata !3, metadata !DIExpression(DW_OP_plus_uconst, 42, DW_OP_stack_value)), !dbg !5
call void @llvm.dbg.value(metadata !DIArgList(i64 %arg1, i64 undef), metadata !3, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)), !dbg !5
ret void
}

Expand Down

0 comments on commit 0ab6b20

Please sign in to comment.