mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[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:
parent
a09a19be58
commit
ac1b69b9db
@ -518,6 +518,31 @@ def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_typ
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -287,7 +287,7 @@ def LLVM_MemcpyInlineOp :
|
||||
# setAliasAnalysisMetadataCode;
|
||||
}
|
||||
|
||||
def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2],
|
||||
def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2],
|
||||
[DeclareOpInterfaceMethods<PromotableMemOpInterface>,
|
||||
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
|
||||
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
|
||||
@ -557,17 +557,35 @@ 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>]> {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
//
|
||||
|
@ -91,12 +91,12 @@ def LLVM_AnyTargetExt : Type<CPred<"::llvm::isa<::mlir::LLVM::LLVMTargetExtType>
|
||||
// Type constraint accepting LLVM target extension types with no support for
|
||||
// memory operations such as alloca, load and store.
|
||||
def LLVM_NonLoadableTargetExtType : Type<
|
||||
And<[LLVM_AnyTargetExt.predicate,
|
||||
And<[LLVM_AnyTargetExt.predicate,
|
||||
CPred<"!::llvm::cast<::mlir::LLVM::LLVMTargetExtType>($_self).supportsMemOps()">]
|
||||
>>;
|
||||
|
||||
// Type constraint accepting any LLVM type that can be loaded or stored, i.e. a
|
||||
// type that has size (not void, function, opaque struct type or target
|
||||
// type that has size (not void, function, opaque struct type or target
|
||||
// extension type which does not support memory operations).
|
||||
def LLVM_LoadableType : Type<
|
||||
Or<[And<[LLVM_PrimitiveType.predicate, Neg<LLVM_OpaqueStruct.predicate>,
|
||||
@ -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;
|
||||
// - $_float_attr - substituted by a call to a float 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;
|
||||
// - $_location - substituted with the MLIR location;
|
||||
// - $_builder - substituted with the MLIR builder;
|
||||
|
@ -148,6 +148,9 @@ public:
|
||||
/// fails.
|
||||
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
|
||||
/// operations, or returns failure if the conversion fails.
|
||||
FailureOr<SmallVector<SymbolRefAttr>>
|
||||
|
@ -43,10 +43,11 @@ void LLVMDialect::registerAttributes() {
|
||||
|
||||
bool DINodeAttr::classof(Attribute attr) {
|
||||
return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
|
||||
DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr,
|
||||
DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
|
||||
DISubroutineTypeAttr>(attr);
|
||||
DIDerivedTypeAttr, DIFileAttr, DILabelAttr,
|
||||
DILexicalBlockAttr, DILexicalBlockFileAttr,
|
||||
DILocalVariableAttr, DINamespaceAttr, DINullTypeAttr,
|
||||
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
|
||||
attr);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -3063,7 +3063,7 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface {
|
||||
AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
|
||||
return TypeSwitch<Attribute, AliasResult>(attr)
|
||||
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
|
||||
DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr,
|
||||
DINullTypeAttr, DISubprogramAttr, DISubroutineTypeAttr,
|
||||
LoopAnnotationAttr, LoopVectorizeAttr, LoopInterleaveAttr,
|
||||
|
@ -87,6 +87,12 @@ DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) {
|
||||
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) {
|
||||
return DILexicalBlockAttr::get(context, translate(node->getScope()),
|
||||
translate(node->getFile()), node->getLine(),
|
||||
@ -200,6 +206,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
|
||||
return translateImpl(casted);
|
||||
if (auto *casted = dyn_cast<llvm::DIFile>(node))
|
||||
return translateImpl(casted);
|
||||
if (auto *casted = dyn_cast<llvm::DILabel>(node))
|
||||
return translateImpl(casted);
|
||||
if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
|
||||
return translateImpl(casted);
|
||||
if (auto *casted = dyn_cast<llvm::DILexicalBlockFile>(node))
|
||||
|
@ -57,6 +57,7 @@ private:
|
||||
DICompositeTypeAttr translateImpl(llvm::DICompositeType *node);
|
||||
DIDerivedTypeAttr translateImpl(llvm::DIDerivedType *node);
|
||||
DIFileAttr translateImpl(llvm::DIFile *node);
|
||||
DILabelAttr translateImpl(llvm::DILabel *node);
|
||||
DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
|
||||
DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
|
||||
DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);
|
||||
|
@ -149,6 +149,12 @@ llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) {
|
||||
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) {
|
||||
return llvm::DILexicalBlock::getDistinct(llvmCtx, translate(attr.getScope()),
|
||||
translate(attr.getFile()),
|
||||
@ -247,7 +253,7 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
|
||||
llvm::DINode *node =
|
||||
TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
|
||||
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
|
||||
DILexicalBlockFileAttr, DILocalVariableAttr, DINamespaceAttr,
|
||||
DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
|
||||
DISubroutineTypeAttr>(
|
||||
|
@ -67,6 +67,7 @@ private:
|
||||
llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr);
|
||||
llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr);
|
||||
llvm::DIFile *translateImpl(DIFileAttr attr);
|
||||
llvm::DILabel *translateImpl(DILabelAttr attr);
|
||||
llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr);
|
||||
llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr);
|
||||
llvm::DILocalScope *translateImpl(DILocalScopeAttr attr);
|
||||
|
@ -1255,6 +1255,12 @@ DILocalVariableAttr ModuleImport::matchLocalVariableAttr(llvm::Value *value) {
|
||||
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>>
|
||||
ModuleImport::matchAliasScopeAttrs(llvm::Value *value) {
|
||||
auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
|
||||
|
@ -136,6 +136,12 @@
|
||||
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)
|
||||
llvm.func @addr(%arg: i64) {
|
||||
// CHECK: %[[ALLOC:.*]] = llvm.alloca
|
||||
@ -153,5 +159,9 @@ llvm.func @value(%arg1: i32, %arg2: i32) {
|
||||
llvm.intr.dbg.value #var1 = %arg1 : i32
|
||||
// CHECK: llvm.intr.dbg.value #[[VAR2]] = %[[ARG2]]
|
||||
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
|
||||
}
|
||||
|
@ -233,8 +233,10 @@ source_filename = "debug-info.ll"
|
||||
|
||||
; // -----
|
||||
|
||||
; CHECK: #[[FILE:.+]] = #llvm.di_file<
|
||||
; 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-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
|
||||
; 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
|
||||
; CHECK: llvm.intr.dbg.label #[[$LABEL]] loc(#[[LOC1:.+]])
|
||||
call void @llvm.dbg.label(metadata !10), !dbg !9
|
||||
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.declare(metadata, metadata, metadata)
|
||||
declare void @llvm.dbg.label(metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!1}
|
||||
!llvm.module.flags = !{!0}
|
||||
@ -266,6 +271,7 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
!7 = !DILocation(line: 1, column: 2, scope: !3)
|
||||
!8 = !DILocation(line: 2, column: 2, scope: !3)
|
||||
!9 = !DILocation(line: 3, column: 2, scope: !3)
|
||||
!10 = !DILabel(scope: !3, name: "label", file: !2, line: 42)
|
||||
|
||||
; // -----
|
||||
|
||||
|
@ -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_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_label = #llvm.di_label<scope = #di_lexical_block_file, name = "label", file = #di_file, line = 42>
|
||||
|
||||
#loc0 = loc("foo.mlir":0:0)
|
||||
#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])
|
||||
// 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])
|
||||
// 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
|
||||
} 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: ![[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 ![[LABEL]] = !DILabel(scope: ![[LEXICAL_BLOCK_FILE]], name: "label", file: ![[FILE]], line: 42)
|
||||
|
@ -270,6 +270,8 @@ static LogicalResult emitOneMLIRBuilder(const Record &record, raw_ostream &os,
|
||||
bs << "moduleImport.matchFloatAttr";
|
||||
} else if (name == "_var_attr") {
|
||||
bs << "moduleImport.matchLocalVariableAttr";
|
||||
} else if (name == "_label_attr") {
|
||||
bs << "moduleImport.matchLabelAttr";
|
||||
} else if (name == "_resultType") {
|
||||
bs << "moduleImport.convertType(inst->getType())";
|
||||
} else if (name == "_location") {
|
||||
|
Loading…
Reference in New Issue
Block a user