[mlir][llvm] Add debug label intrinsic

This revision adds support for the llvm.dbg.label.intrinsic
and the corresponding DILabel metadata.

Reviewed By: Dinistro

Differential Revision: https://reviews.llvm.org/D153975
This commit is contained in:
Tobias Gysi 2023-06-29 06:31:03 +00:00
parent a09a19be58
commit ac1b69b9db
15 changed files with 105 additions and 13 deletions

View File

@ -518,6 +518,31 @@ def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_typ
let assemblyFormat = "`<` struct(params) `>`"; let assemblyFormat = "`<` struct(params) `>`";
} }
//===----------------------------------------------------------------------===//
// DILabelAttr
//===----------------------------------------------------------------------===//
def LLVM_DILabelAttr : LLVM_Attr<"DILabel", "di_label",
/*traits=*/[], "DINodeAttr"> {
let parameters = (ins
"DIScopeAttr":$scope,
OptionalParameter<"StringAttr">:$name,
OptionalParameter<"DIFileAttr">:$file,
OptionalParameter<"unsigned">:$line
);
let builders = [
AttrBuilderWithInferredContext<(ins
"DIScopeAttr":$scope, "StringRef":$name, "DIFileAttr":$file,
"unsigned":$line
), [{
MLIRContext *ctx = scope.getContext();
return $_get(ctx, scope, StringAttr::get(ctx, name), file, line);
}]>
];
let assemblyFormat = "`<` struct(params) `>`";
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// MemoryEffectsAttr // MemoryEffectsAttr
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -559,15 +559,33 @@ class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr", def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr",
[DeclareOpInterfaceMethods<PromotableOpInterface>]> { [DeclareOpInterfaceMethods<PromotableOpInterface>]> {
let summary = "Declare the address of a local debug info variable."; 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);
} }
def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value"> { def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value"> {
let summary = "Describe the current value of a local debug info variable."; 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);
} }
def LLVM_DbgLabelOp : LLVM_IntrOp<"dbg.label", [], [], [], 0> {
let summary = "Relates the program to a debug information label.";
let arguments = (ins LLVM_DILabelAttr:$label);
let llvmBuilder = [{
llvm::Module *module = builder.GetInsertBlock()->getModule();
llvm::LLVMContext &ctx = module->getContext();
llvm::Function *fn =
llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::dbg_label);
builder.CreateCall(fn, {
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($label))
});
}];
let mlirBuilder = [{
$_op = $_builder.create<$_qualCppClassName>($_location, $_label_attr($label));
}];
let assemblyFormat = "$label attr-dict";
}
// //
// Variadic function intrinsics. // Variadic function intrinsics.
// //

View File

@ -174,6 +174,7 @@ class LLVM_OpBase<Dialect dialect, string mnemonic, list<Trait> traits = []> :
// - $_int_attr - substituted by a call to an integer attribute matcher; // - $_int_attr - substituted by a call to an integer attribute matcher;
// - $_float_attr - substituted by a call to a float attribute matcher; // - $_float_attr - substituted by a call to a float attribute matcher;
// - $_var_attr - substituted by a call to a variable attribute matcher; // - $_var_attr - substituted by a call to a variable attribute matcher;
// - $_label_attr - substituted by a call to a label attribute matcher;
// - $_resultType - substituted with the MLIR result type; // - $_resultType - substituted with the MLIR result type;
// - $_location - substituted with the MLIR location; // - $_location - substituted with the MLIR location;
// - $_builder - substituted with the MLIR builder; // - $_builder - substituted with the MLIR builder;

View File

@ -148,6 +148,9 @@ public:
/// fails. /// fails.
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value); DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value);
/// Converts `value` to a label attribute. Asserts if the matching fails.
DILabelAttr matchLabelAttr(llvm::Value *value);
/// Converts `value` to an array of symbol references pointing to alias scope /// Converts `value` to an array of symbol references pointing to alias scope
/// operations, or returns failure if the conversion fails. /// operations, or returns failure if the conversion fails.
FailureOr<SmallVector<SymbolRefAttr>> FailureOr<SmallVector<SymbolRefAttr>>

View File

@ -43,10 +43,11 @@ void LLVMDialect::registerAttributes() {
bool DINodeAttr::classof(Attribute attr) { bool DINodeAttr::classof(Attribute attr) {
return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr, return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr, DIDerivedTypeAttr, DIFileAttr, DILabelAttr,
DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
DINullTypeAttr, DISubprogramAttr, DISubrangeAttr, DILocalVariableAttr, DINamespaceAttr, DINullTypeAttr,
DISubroutineTypeAttr>(attr); DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
attr);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -3063,7 +3063,7 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface {
AliasResult getAlias(Attribute attr, raw_ostream &os) const override { AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
return TypeSwitch<Attribute, AliasResult>(attr) return TypeSwitch<Attribute, AliasResult>(attr)
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr, .Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr, DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr, DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr,
DINullTypeAttr, DISubprogramAttr, DISubroutineTypeAttr, DINullTypeAttr, DISubprogramAttr, DISubroutineTypeAttr,
LoopAnnotationAttr, LoopVectorizeAttr, LoopInterleaveAttr, LoopAnnotationAttr, LoopVectorizeAttr, LoopInterleaveAttr,

View File

@ -87,6 +87,12 @@ DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) {
return DIFileAttr::get(context, node->getFilename(), node->getDirectory()); return DIFileAttr::get(context, node->getFilename(), node->getDirectory());
} }
DILabelAttr DebugImporter::translateImpl(llvm::DILabel *node) {
return DILabelAttr::get(context, translate(node->getScope()),
getStringAttrOrNull(node->getRawName()),
translate(node->getFile()), node->getLine());
}
DILexicalBlockAttr DebugImporter::translateImpl(llvm::DILexicalBlock *node) { DILexicalBlockAttr DebugImporter::translateImpl(llvm::DILexicalBlock *node) {
return DILexicalBlockAttr::get(context, translate(node->getScope()), return DILexicalBlockAttr::get(context, translate(node->getScope()),
translate(node->getFile()), node->getLine(), translate(node->getFile()), node->getLine(),
@ -200,6 +206,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
return translateImpl(casted); return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DIFile>(node)) if (auto *casted = dyn_cast<llvm::DIFile>(node))
return translateImpl(casted); return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DILabel>(node))
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node)) if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
return translateImpl(casted); return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DILexicalBlockFile>(node)) if (auto *casted = dyn_cast<llvm::DILexicalBlockFile>(node))

View File

@ -57,6 +57,7 @@ private:
DICompositeTypeAttr translateImpl(llvm::DICompositeType *node); DICompositeTypeAttr translateImpl(llvm::DICompositeType *node);
DIDerivedTypeAttr translateImpl(llvm::DIDerivedType *node); DIDerivedTypeAttr translateImpl(llvm::DIDerivedType *node);
DIFileAttr translateImpl(llvm::DIFile *node); DIFileAttr translateImpl(llvm::DIFile *node);
DILabelAttr translateImpl(llvm::DILabel *node);
DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node); DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node); DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
DILocalVariableAttr translateImpl(llvm::DILocalVariable *node); DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);

View File

@ -149,6 +149,12 @@ llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) {
getMDStringOrNull(attr.getDirectory())); getMDStringOrNull(attr.getDirectory()));
} }
llvm::DILabel *DebugTranslation::translateImpl(DILabelAttr attr) {
return llvm::DILabel::get(llvmCtx, translate(attr.getScope()),
getMDStringOrNull(attr.getName()),
translate(attr.getFile()), attr.getLine());
}
llvm::DILexicalBlock *DebugTranslation::translateImpl(DILexicalBlockAttr attr) { llvm::DILexicalBlock *DebugTranslation::translateImpl(DILexicalBlockAttr attr) {
return llvm::DILexicalBlock::getDistinct(llvmCtx, translate(attr.getScope()), return llvm::DILexicalBlock::getDistinct(llvmCtx, translate(attr.getScope()),
translate(attr.getFile()), translate(attr.getFile()),
@ -247,7 +253,7 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
llvm::DINode *node = llvm::DINode *node =
TypeSwitch<DINodeAttr, llvm::DINode *>(attr) TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr, .Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr, DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr, DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr,
DINullTypeAttr, DISubprogramAttr, DISubrangeAttr, DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
DISubroutineTypeAttr>( DISubroutineTypeAttr>(

View File

@ -67,6 +67,7 @@ private:
llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr); llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr);
llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr); llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr);
llvm::DIFile *translateImpl(DIFileAttr attr); llvm::DIFile *translateImpl(DIFileAttr attr);
llvm::DILabel *translateImpl(DILabelAttr attr);
llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr); llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr);
llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr); llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr);
llvm::DILocalScope *translateImpl(DILocalScopeAttr attr); llvm::DILocalScope *translateImpl(DILocalScopeAttr attr);

View File

@ -1255,6 +1255,12 @@ DILocalVariableAttr ModuleImport::matchLocalVariableAttr(llvm::Value *value) {
return debugImporter->translate(node); return debugImporter->translate(node);
} }
DILabelAttr ModuleImport::matchLabelAttr(llvm::Value *value) {
auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
return debugImporter->translate(node);
}
FailureOr<SmallVector<SymbolRefAttr>> FailureOr<SmallVector<SymbolRefAttr>>
ModuleImport::matchAliasScopeAttrs(llvm::Value *value) { ModuleImport::matchAliasScopeAttrs(llvm::Value *value) {
auto *nodeAsVal = cast<llvm::MetadataAsValue>(value); auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);

View File

@ -136,6 +136,12 @@
scope = #block2, name = "arg2" scope = #block2, name = "arg2"
> >
// CHECK-DAG: #[[LABEL1:.*]] = #llvm.di_label<scope = #[[BLOCK1]], name = "label", file = #[[FILE]], line = 42>
#label1 = #llvm.di_label<scope = #block1, name = "label", file = #file, line = 42>
// CHECK-DAG: #[[LABEL2:.*]] = #llvm.di_label<scope = #[[BLOCK2]]>
#label2 = #llvm.di_label<scope = #block2>
// CHECK: llvm.func @addr(%[[ARG:.*]]: i64) // CHECK: llvm.func @addr(%[[ARG:.*]]: i64)
llvm.func @addr(%arg: i64) { llvm.func @addr(%arg: i64) {
// CHECK: %[[ALLOC:.*]] = llvm.alloca // CHECK: %[[ALLOC:.*]] = llvm.alloca
@ -153,5 +159,9 @@ llvm.func @value(%arg1: i32, %arg2: i32) {
llvm.intr.dbg.value #var1 = %arg1 : i32 llvm.intr.dbg.value #var1 = %arg1 : i32
// CHECK: llvm.intr.dbg.value #[[VAR2]] = %[[ARG2]] // CHECK: llvm.intr.dbg.value #[[VAR2]] = %[[ARG2]]
llvm.intr.dbg.value #var2 = %arg2 : i32 llvm.intr.dbg.value #var2 = %arg2 : i32
// CHECK: llvm.intr.dbg.label #[[LABEL1]]
llvm.intr.dbg.label #label1
// CHECK: llvm.intr.dbg.label #[[LABEL2]]
llvm.intr.dbg.label #label2
llvm.return llvm.return
} }

View File

@ -233,8 +233,10 @@ source_filename = "debug-info.ll"
; // ----- ; // -----
; CHECK: #[[FILE:.+]] = #llvm.di_file<
; CHECK: #[[$SP:.+]] = #llvm.di_subprogram< ; CHECK: #[[$SP:.+]] = #llvm.di_subprogram<
; CHECK: #[[$VAR0:.+]] = #llvm.di_local_variable<scope = #[[$SP]], name = "arg", file = #{{.*}}, line = 1, arg = 1, alignInBits = 32, type = #{{.*}}> ; CHECK: #[[$LABEL:.+]] = #llvm.di_label<scope = #[[$SP]], name = "label", file = #[[FILE]], line = 42>
; CHECK: #[[$VAR0:.+]] = #llvm.di_local_variable<scope = #[[$SP]], name = "arg", file = #[[FILE]], line = 1, arg = 1, alignInBits = 32, type = #{{.*}}>
; CHECK: #[[$VAR1:.+]] = #llvm.di_local_variable<scope = #[[$SP]], name = "arg"> ; CHECK: #[[$VAR1:.+]] = #llvm.di_local_variable<scope = #[[$SP]], name = "arg">
; CHECK-LABEL: @intrinsic ; CHECK-LABEL: @intrinsic
@ -245,6 +247,8 @@ define void @intrinsic(i64 %0, ptr %1) {
call void @llvm.dbg.value(metadata i64 %0, metadata !5, metadata !DIExpression()), !dbg !7 call void @llvm.dbg.value(metadata i64 %0, metadata !5, metadata !DIExpression()), !dbg !7
; CHECK: llvm.intr.dbg.declare #[[$VAR1]] = %[[ARG1]] : !llvm.ptr loc(#[[LOC1:.+]]) ; CHECK: llvm.intr.dbg.declare #[[$VAR1]] = %[[ARG1]] : !llvm.ptr loc(#[[LOC1:.+]])
call void @llvm.dbg.declare(metadata ptr %1, metadata !6, metadata !DIExpression()), !dbg !9 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
ret void ret void
} }
@ -253,6 +257,7 @@ define void @intrinsic(i64 %0, ptr %1) {
declare void @llvm.dbg.value(metadata, metadata, metadata) declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @llvm.dbg.declare(metadata, metadata, metadata) declare void @llvm.dbg.declare(metadata, metadata, metadata)
declare void @llvm.dbg.label(metadata)
!llvm.dbg.cu = !{!1} !llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0} !llvm.module.flags = !{!0}
@ -266,6 +271,7 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata)
!7 = !DILocation(line: 1, column: 2, scope: !3) !7 = !DILocation(line: 1, column: 2, scope: !3)
!8 = !DILocation(line: 2, column: 2, scope: !3) !8 = !DILocation(line: 2, column: 2, scope: !3)
!9 = !DILocation(line: 3, column: 2, scope: !3) !9 = !DILocation(line: 3, column: 2, scope: !3)
!10 = !DILabel(scope: !3, name: "label", file: !2, line: 42)
; // ----- ; // -----

View File

@ -176,6 +176,7 @@ llvm.func @empty_types() {
#di_local_variable0 = #llvm.di_local_variable<scope = #di_subprogram, name = "a", file = #di_file, type = #di_basic_type> #di_local_variable0 = #llvm.di_local_variable<scope = #di_subprogram, name = "a", file = #di_file, type = #di_basic_type>
#di_lexical_block_file = #llvm.di_lexical_block_file<scope = #di_subprogram1, file = #di_file, discriminator = 0> #di_lexical_block_file = #llvm.di_lexical_block_file<scope = #di_subprogram1, file = #di_file, discriminator = 0>
#di_local_variable1 = #llvm.di_local_variable<scope = #di_lexical_block_file, name = "b", file = #di_file, type = #di_basic_type> #di_local_variable1 = #llvm.di_local_variable<scope = #di_lexical_block_file, name = "b", file = #di_file, type = #di_basic_type>
#di_label = #llvm.di_label<scope = #di_lexical_block_file, name = "label", file = #di_file, line = 42>
#loc0 = loc("foo.mlir":0:0) #loc0 = loc("foo.mlir":0:0)
#loc1 = loc(callsite(#loc0 at fused<#di_subprogram>["foo.mlir":4:2])) #loc1 = loc(callsite(#loc0 at fused<#di_subprogram>["foo.mlir":4:2]))
@ -187,6 +188,8 @@ llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
llvm.intr.dbg.value #di_local_variable0 = %arg0 : i32 loc(fused<#di_subprogram>[#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:.*]] // CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC1:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC1:.*]]
llvm.intr.dbg.value #di_local_variable1 = %arg0 : i32 loc(fused<#di_lexical_block_file>[#loc1]) llvm.intr.dbg.value #di_local_variable1 = %arg0 : i32 loc(fused<#di_lexical_block_file>[#loc1])
// CHECK: call void @llvm.dbg.label(metadata ![[LABEL:[0-9]+]]), !dbg ![[DBG_LOC1:.*]]
llvm.intr.dbg.label #di_label loc(fused<#di_lexical_block_file>[#loc1])
llvm.return %arg0 : i32 llvm.return %arg0 : i32
} loc(fused<#di_subprogram>["caller"]) } loc(fused<#di_subprogram>["caller"])
@ -196,3 +199,4 @@ llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
// CHECK-DAG: ![[LEXICAL_BLOCK_FILE:.*]] = distinct !DILexicalBlockFile(scope: ![[INNER_FUNC]], file: ![[FILE]], discriminator: 0) // CHECK-DAG: ![[LEXICAL_BLOCK_FILE:.*]] = distinct !DILexicalBlockFile(scope: ![[INNER_FUNC]], file: ![[FILE]], discriminator: 0)
// CHECK-DAG: ![[VAR_LOC0]] = !DILocalVariable(name: "a", scope: ![[OUTER_FUNC]], file: ![[FILE]] // CHECK-DAG: ![[VAR_LOC0]] = !DILocalVariable(name: "a", scope: ![[OUTER_FUNC]], file: ![[FILE]]
// CHECK-DAG: ![[VAR_LOC1]] = !DILocalVariable(name: "b", scope: ![[LEXICAL_BLOCK_FILE]], file: ![[FILE]] // CHECK-DAG: ![[VAR_LOC1]] = !DILocalVariable(name: "b", scope: ![[LEXICAL_BLOCK_FILE]], file: ![[FILE]]
// CHECK-DAG ![[LABEL]] = !DILabel(scope: ![[LEXICAL_BLOCK_FILE]], name: "label", file: ![[FILE]], line: 42)

View File

@ -270,6 +270,8 @@ static LogicalResult emitOneMLIRBuilder(const Record &record, raw_ostream &os,
bs << "moduleImport.matchFloatAttr"; bs << "moduleImport.matchFloatAttr";
} else if (name == "_var_attr") { } else if (name == "_var_attr") {
bs << "moduleImport.matchLocalVariableAttr"; bs << "moduleImport.matchLocalVariableAttr";
} else if (name == "_label_attr") {
bs << "moduleImport.matchLabelAttr";
} else if (name == "_resultType") { } else if (name == "_resultType") {
bs << "moduleImport.convertType(inst->getType())"; bs << "moduleImport.convertType(inst->getType())";
} else if (name == "_location") { } else if (name == "_location") {