diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -12,10 +12,13 @@ include "mlir/IR/AttrTypeBase.td" include "mlir/Dialect/LLVMIR/LLVMEnums.td" include "mlir/Dialect/LLVMIR/LLVMOpBase.td" +include "mlir/IR/SubElementInterfaces.td" // All of the attributes will extend this class. -class LLVM_Attr - : AttrDef { +class LLVM_Attr traits = [], + string baseCppClass = "::mlir::Attribute"> + : AttrDef { let mnemonic = attrMnemonic; } @@ -81,4 +84,280 @@ let skipDefaultBuilders = 1; } +//===----------------------------------------------------------------------===// +// DebugInfo Attributes +//===----------------------------------------------------------------------===// + +class LLVM_DIParameter + : AttrOrTypeParameter { + let parser = [{ [&]() -> FailureOr { + SMLoc tagLoc = $_parser.getCurrentLocation(); + StringRef name; + if ($_parser.parseKeyword(&name)) + return failure(); + + if (unsigned tag = llvm::dwarf::get}] # parseName # [{(name)) + return tag; + return $_parser.emitError(tagLoc) + << "invalid debug info }] # summary # [{ name: " << name; + }() }]; + let printer = "$_printer << llvm::dwarf::" # printName # "String($_self)"; +} + +def LLVM_DICallingConventionParameter : LLVM_DIParameter< + "calling convention", "unsigned", "CallingConvention", "Convention" +>; + +def LLVM_DIEncodingParameter : LLVM_DIParameter< + "encoding", "unsigned", "AttributeEncoding" +>; + +def LLVM_DILanguageParameter : LLVM_DIParameter< + "language", "unsigned", "Language" +>; + +def LLVM_DITagParameter : LLVM_DIParameter< + "tag", "unsigned", "Tag" +>; + +//===----------------------------------------------------------------------===// +// DIBasicTypeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DIBasicTypeAttr : LLVM_Attr<"DIBasicType", "di_basic_type", + /*traits=*/[], "DITypeAttr"> { + let parameters = (ins + LLVM_DITagParameter:$tag, + "StringAttr":$name, + "uint64_t":$sizeInBits, + LLVM_DIEncodingParameter:$encoding + ); + + let builders = [ + TypeBuilder<(ins + "unsigned":$tag, "const Twine &":$name, "uint64_t":$sizeInBits, + "unsigned":$encoding + ), [{ + return $_get($_ctxt, tag, StringAttr::get($_ctxt, name), sizeInBits, + encoding); + }]> + ]; + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DICompileUnitAttr +//===----------------------------------------------------------------------===// + +def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit", [ + DeclareAttrInterfaceMethods + ], "DIScopeAttr"> { + let parameters = (ins + LLVM_DILanguageParameter:$sourceLanguage, + "DIFileAttr":$file, + "StringAttr":$producer, + "bool":$isOptimized, + "DIEmissionKind":$emissionKind + ); + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DICompositeTypeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type", [ + DeclareAttrInterfaceMethods + ], "DITypeAttr"> { + let parameters = (ins + LLVM_DITagParameter:$tag, + "StringAttr":$name, + OptionalParameter<"DIFileAttr">:$file, + "uint32_t":$line, + OptionalParameter<"DIScopeAttr">:$scope, + "uint64_t":$sizeInBits, + "uint64_t":$alignInBits, + OptionalArrayRefParameter<"DINodeAttr">:$elements + ); + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DIDerivedTypeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DIDerivedTypeAttr : LLVM_Attr<"DIDerivedType", "di_derived_type", [ + DeclareAttrInterfaceMethods + ], "DITypeAttr"> { + let parameters = (ins + LLVM_DITagParameter:$tag, + "StringAttr":$name, + "DITypeAttr":$baseType, + "uint64_t":$sizeInBits, + "uint32_t":$alignInBits, + "uint64_t":$offsetInBits + ); + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DIFileAttr +//===----------------------------------------------------------------------===// + +def LLVM_DIFileAttr : LLVM_Attr<"DIFile", "di_file", /*traits=*/[], "DIScopeAttr"> { + let parameters = (ins "StringAttr":$name, "StringAttr":$directory); + let builders = [AttrBuilder<(ins "StringRef":$name, "StringRef":$directory), [{ + return $_get($_ctxt, StringAttr::get($_ctxt, name), + StringAttr::get($_ctxt, directory)); + }]> + ]; + let assemblyFormat = "`<` $name `in` $directory `>`"; +} + +//===----------------------------------------------------------------------===// +// DILexicalBlockAttr +//===----------------------------------------------------------------------===// + +def LLVM_DILexicalBlockAttr : LLVM_Attr<"DILexicalBlock", "di_lexical_block", [ + DeclareAttrInterfaceMethods + ], "DIScopeAttr"> { + let parameters = (ins + "DIScopeAttr":$scope, + "DIFileAttr":$file, + "unsigned":$line, + "unsigned":$column + ); + let builders = [ + AttrBuilderWithInferredContext<(ins + "DIScopeAttr":$scope, "DIFileAttr":$file, "unsigned":$line, + "unsigned":$column + ), [{ + return $_get(file.getContext(), scope, file, line, column); + }]> + ]; + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DILexicalBlockFileAttr +//===----------------------------------------------------------------------===// + +def LLVM_DILexicalBlockFile : LLVM_Attr<"DILexicalBlockFile", "di_lexical_block_file", [ + DeclareAttrInterfaceMethods + ], "DIScopeAttr"> { + let parameters = (ins + "DIScopeAttr":$scope, + "DIFileAttr":$file, + "unsigned":$descriminator + ); + let builders = [ + AttrBuilderWithInferredContext<(ins + "DIScopeAttr":$scope, "DIFileAttr":$file, "unsigned":$descriminator + ), [{ + return $_get(file.getContext(), scope, file, descriminator); + }]> + ]; + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DILocalVariableAttr +//===----------------------------------------------------------------------===// + +def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable", [ + DeclareAttrInterfaceMethods + ], "DINodeAttr"> { + let parameters = (ins + "DIScopeAttr":$scope, + "StringAttr":$name, + "DIFileAttr":$file, + "unsigned":$line, + "unsigned":$arg, + "unsigned":$alignInBits, + "DITypeAttr":$type + ); + let builders = [ + AttrBuilderWithInferredContext<(ins + "DIScopeAttr":$scope, "StringRef":$name, "DIFileAttr":$file, + "unsigned":$line, "unsigned":$arg, "unsigned":$alignInBits, + "DITypeAttr":$type + ), [{ + MLIRContext *ctx = file.getContext(); + return $_get(ctx, scope, StringAttr::get(ctx, name), file, line, + arg, alignInBits, type); + }]> + ]; + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DISubprogramAttr +//===----------------------------------------------------------------------===// + +def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram", [ + DeclareAttrInterfaceMethods + ], "DIScopeAttr"> { + let parameters = (ins + "DICompileUnitAttr":$compileUnit, + "DIScopeAttr":$scope, + "StringAttr":$name, + "StringAttr":$linkageName, + "DIFileAttr":$file, + "unsigned":$line, + "unsigned":$scopeLine, + "DISubprogramFlags":$subprogramFlags, + "DISubroutineTypeAttr":$type + ); + let builders = [ + AttrBuilderWithInferredContext<(ins + "DICompileUnitAttr":$compileUnit, "DIScopeAttr":$scope, "StringRef":$name, + "StringRef":$linkageName, "DIFileAttr":$file, "unsigned":$line, + "unsigned":$scopeLine, "DISubprogramFlags":$subprogramFlags, + "DISubroutineTypeAttr":$type + ), [{ + MLIRContext *ctx = file.getContext(); + return $_get(ctx, compileUnit, scope, StringAttr::get(ctx, name), + StringAttr::get(ctx, linkageName), file, line, + scopeLine, subprogramFlags, type); + }]> + ]; + + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DISubrangeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DISubrangeAttr : LLVM_Attr<"DISubrange", "di_subrange", /*traits=*/[], + "DINodeAttr"> { + let parameters = (ins + "IntegerAttr":$count, + "IntegerAttr":$lowerBound, + "IntegerAttr":$upperBound, + "IntegerAttr":$stride + ); + let assemblyFormat = "`<` struct(params) `>`"; +} + +//===----------------------------------------------------------------------===// +// DISubroutineTypeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_type", [ + DeclareAttrInterfaceMethods + ], "DITypeAttr"> { + let parameters = (ins + LLVM_DICallingConventionParameter:$callingConvention, + OptionalArrayRefParameter<"DITypeAttr">:$types + ); + let builders = [ + TypeBuilder<(ins "ArrayRef":$types), [{ + return $_get($_ctxt, /*callingConvention=*/0, types); + }]> + ]; + let assemblyFormat = "`<` struct(params) `>`"; +} + #endif // LLVMIR_ATTRDEFS diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h @@ -23,6 +23,33 @@ namespace LLVM { class LoopOptionsAttrBuilder; +/// This class represents the base attribute for all debug info attributes. +class DINodeAttr : public Attribute { +public: + using Attribute::Attribute; + + // Support LLVM type casting. + static bool classof(Attribute attr); +}; + +/// This class represents a LLVM attribute that describes a debug info scope. +class DIScopeAttr : public DINodeAttr { +public: + using DINodeAttr::DINodeAttr; + + /// Support LLVM type casting. + static bool classof(Attribute attr); +}; + +/// This class represents a LLVM attribute that describes a debug info type. +class DITypeAttr : public DINodeAttr { +public: + using DINodeAttr::DINodeAttr; + + /// Support LLVM type casting. + static bool classof(Attribute attr); +}; + // Inline the LLVM generated Linkage enum and utility. // This is only necessary to isolate the "enum generated code" from the // attribute definition itself. diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td @@ -204,6 +204,61 @@ "::mlir::LLVM::CConvAttr::get($_builder.getContext(), $0)"; } +//===----------------------------------------------------------------------===// +// DIEmissionKind +//===----------------------------------------------------------------------===// + +def LLVM_DIEmissionNone : I64EnumAttrCase<"None", 0>; +def LLVM_DIEmissionFull : I64EnumAttrCase<"Full", 1>; +def LLVM_DIEmissionLineTablesOnly : I64EnumAttrCase<"LineTablesOnly", 2>; +def LLVM_DIEmissionDebugDirectivesOnly : I64EnumAttrCase<"DebugDirectivesOnly", 3>; + +def LLVM_DIEmissionKind : I64EnumAttr< + "DIEmissionKind", + "LLVM debug emission kind", [ + LLVM_DIEmissionNone, + LLVM_DIEmissionFull, + LLVM_DIEmissionLineTablesOnly, + LLVM_DIEmissionDebugDirectivesOnly, + ]> { + let cppNamespace = "::mlir::LLVM"; +} + +//===----------------------------------------------------------------------===// +// DISubprogramFlags +//===----------------------------------------------------------------------===// + +def LLVM_DISPVirtual : I32BitEnumAttrCaseBit<"Virtual", 0>; +def LLVM_DISPPureVirtual : I32BitEnumAttrCaseBit<"PureVirtual", 1>; +def LLVM_DISPLocalToUnit : I32BitEnumAttrCaseBit<"LocalToUnit", 2>; +def LLVM_DISPDefinition : I32BitEnumAttrCaseBit<"Definition", 3>; +def LLVM_DISPOptimized : I32BitEnumAttrCaseBit<"Optimized", 4>; +def LLVM_DISPPure : I32BitEnumAttrCaseBit<"Pure", 5>; +def LLVM_DISPElemental : I32BitEnumAttrCaseBit<"Elemental", 6>; +def LLVM_DISPRecursive : I32BitEnumAttrCaseBit<"Recursive", 7>; +def LLVM_DISPMainSubprogram : I32BitEnumAttrCaseBit<"MainSubprogram", 8>; +def LLVM_DISPDeleted : I32BitEnumAttrCaseBit<"Deleted", 9>; +def LLVM_DISPObjCDirect : I32BitEnumAttrCaseBit<"ObjCDirect", 11>; + +def DISubprogramFlags : I32BitEnumAttr< + "DISubprogramFlags", + "LLVM DISubprogram flags", [ + LLVM_DISPVirtual, + LLVM_DISPPureVirtual, + LLVM_DISPLocalToUnit, + LLVM_DISPDefinition, + LLVM_DISPOptimized, + LLVM_DISPPure, + LLVM_DISPElemental, + LLVM_DISPRecursive, + LLVM_DISPMainSubprogram, + LLVM_DISPDeleted, + LLVM_DISPObjCDirect + ]> { + let cppNamespace = "::mlir::LLVM"; + let printBitEnumPrimaryGroups = 1; +} + //===----------------------------------------------------------------------===// // FastmathFlags //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -3,6 +3,7 @@ include "mlir/IR/OpBase.td" include "mlir/Dialect/LLVMIR/LLVMOpBase.td" +include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td" include "mlir/Interfaces/InferTypeOpInterface.td" // Operations that correspond to LLVM intrinsics. With MLIR operation set being @@ -228,6 +229,31 @@ let assemblyFormat = "$handle attr-dict"; } +// +// Debug function intrinsics. +// + +def LLVM_DbgAddrOp : LLVM_Op<"dbg.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_Op<"dbg.declare"> { + 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_Op<"dbg.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"; +} + // // Variadic function intrinsics. // diff --git a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt --- a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt +++ b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt @@ -21,6 +21,7 @@ LINK_COMPONENTS AsmParser + BinaryFormat BitReader BitWriter Core diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -16,6 +16,7 @@ #include "mlir/IR/DialectImplementation.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/TypeSwitch.h" +#include "llvm/BinaryFormat/Dwarf.h" using namespace mlir; using namespace mlir::LLVM; @@ -35,6 +36,197 @@ >(); } +//===----------------------------------------------------------------------===// +// DINodeAttr +//===----------------------------------------------------------------------===// + +bool DINodeAttr::classof(Attribute attr) { + return llvm::isa(attr); +} + +//===----------------------------------------------------------------------===// +// DIScopeAttr +//===----------------------------------------------------------------------===// + +bool DIScopeAttr::classof(Attribute attr) { + return llvm::isa(attr); +} + +//===----------------------------------------------------------------------===// +// DITypeAttr +//===----------------------------------------------------------------------===// + +bool DITypeAttr::classof(Attribute attr) { + return llvm::isa(attr); +} + +//===----------------------------------------------------------------------===// +// DICompileUnitAttr +//===----------------------------------------------------------------------===// + +void DICompileUnitAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getFile()); + walkAttrsFn(getProducer()); +} + +Attribute +DICompileUnitAttr::replaceImmediateSubElements(ArrayRef replAttrs, + ArrayRef replTypes) const { + return get(getContext(), getSourceLanguage(), replAttrs[0].cast(), + replAttrs[1].cast(), getIsOptimized(), + getEmissionKind()); +} + +//===----------------------------------------------------------------------===// +// DICompositeTypeAttr +//===----------------------------------------------------------------------===// + +void DICompositeTypeAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getName()); + walkAttrsFn(getFile()); + walkAttrsFn(getScope()); + for (DINodeAttr element : getElements()) + walkAttrsFn(element); +} + +Attribute DICompositeTypeAttr::replaceImmediateSubElements( + ArrayRef replAttrs, ArrayRef replTypes) const { + ArrayRef elements = replAttrs.drop_front(3); + return get( + getContext(), getTag(), replAttrs[0].cast(), + cast_or_null(replAttrs[1]), getLine(), + cast_or_null(replAttrs[2]), getSizeInBits(), + getAlignInBits(), + ArrayRef(static_cast(elements.data()), + elements.size())); +} + +//===----------------------------------------------------------------------===// +// DIDerivedTypeAttr +//===----------------------------------------------------------------------===// + +void DIDerivedTypeAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getName()); + walkAttrsFn(getBaseType()); +} + +Attribute +DIDerivedTypeAttr::replaceImmediateSubElements(ArrayRef replAttrs, + ArrayRef replTypes) const { + return get(getContext(), getTag(), replAttrs[0].cast(), + replAttrs[1].cast(), getSizeInBits(), getAlignInBits(), + getOffsetInBits()); +} + +//===----------------------------------------------------------------------===// +// DILexicalBlockAttr +//===----------------------------------------------------------------------===// + +void DILexicalBlockAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getScope()); + walkAttrsFn(getFile()); +} + +Attribute DILexicalBlockAttr::replaceImmediateSubElements( + ArrayRef replAttrs, ArrayRef replTypes) const { + return get(replAttrs[0].cast(), replAttrs[1].cast(), + getLine(), getColumn()); +} + +//===----------------------------------------------------------------------===// +// DILexicalBlockFileAttr +//===----------------------------------------------------------------------===// + +void DILexicalBlockFileAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getScope()); + walkAttrsFn(getFile()); +} + +Attribute DILexicalBlockFileAttr::replaceImmediateSubElements( + ArrayRef replAttrs, ArrayRef replTypes) const { + return get(replAttrs[0].cast(), replAttrs[1].cast(), + getDescriminator()); +} + +//===----------------------------------------------------------------------===// +// DILocalVariableAttr +//===----------------------------------------------------------------------===// + +void DILocalVariableAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getScope()); + walkAttrsFn(getName()); + walkAttrsFn(getFile()); + walkAttrsFn(getType()); +} + +Attribute DILocalVariableAttr::replaceImmediateSubElements( + ArrayRef replAttrs, ArrayRef replTypes) const { + return get(getContext(), replAttrs[0].cast(), + replAttrs[1].cast(), replAttrs[2].cast(), + getLine(), getArg(), getAlignInBits(), + replAttrs[3].cast()); +} + +//===----------------------------------------------------------------------===// +// DISubprogramAttr +//===----------------------------------------------------------------------===// + +void DISubprogramAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + walkAttrsFn(getCompileUnit()); + walkAttrsFn(getScope()); + walkAttrsFn(getName()); + walkAttrsFn(getLinkageName()); + walkAttrsFn(getFile()); + walkAttrsFn(getType()); +} + +Attribute +DISubprogramAttr::replaceImmediateSubElements(ArrayRef replAttrs, + ArrayRef replTypes) const { + return get(getContext(), replAttrs[0].cast(), + replAttrs[1].cast(), replAttrs[2].cast(), + replAttrs[3].cast(), replAttrs[4].cast(), + getLine(), getScopeLine(), getSubprogramFlags(), + replAttrs[5].cast()); +} + +//===----------------------------------------------------------------------===// +// DISubroutineTypeAttr +//===----------------------------------------------------------------------===// + +void DISubroutineTypeAttr::walkImmediateSubElements( + function_ref walkAttrsFn, + function_ref walkTypesFn) const { + for (DITypeAttr type : getTypes()) + walkAttrsFn(type); +} + +Attribute DISubroutineTypeAttr::replaceImmediateSubElements( + ArrayRef replAttrs, ArrayRef replTypes) const { + return get( + getContext(), getCallingConvention(), + ArrayRef(static_cast(replAttrs.data()), + replAttrs.size())); +} + //===----------------------------------------------------------------------===// // LoopOptionsAttrBuilder //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -2556,6 +2556,28 @@ return {}; } +//===----------------------------------------------------------------------===// +// OpAsmDialectInterface +//===----------------------------------------------------------------------===// + +namespace { +struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface { + using OpAsmDialectInterface::OpAsmDialectInterface; + + AliasResult getAlias(Attribute attr, raw_ostream &os) const override { + return TypeSwitch(attr) + .Case([&](auto attr) { + os << decltype(attr)::getMnemonic(); + return AliasResult::OverridableAlias; + }) + .Default([](Attribute) { return AliasResult::NoAlias; }); + } +}; +} // namespace + //===----------------------------------------------------------------------===// // LLVMDialect initialization, type parsing, and registration. //===----------------------------------------------------------------------===// @@ -2584,6 +2606,7 @@ // Support unknown operations because not all LLVM operations are registered. allowUnknownOperations(); + addInterfaces(); } #define GET_OP_CLASSES diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -0,0 +1,43 @@ +// RUN: mlir-opt %s | mlir-opt | FileCheck %s + +// CHECK: #[[TYPE:.*]] = #llvm.di_basic_type +#si64 = #llvm.di_basic_type< + tag = DW_TAG_base_type, name = "si64", sizeInBits = 0, + encoding = DW_ATE_signed +> + +// CHECK: #[[FILE:.*]] = #llvm.di_file<"debuginfo.mlir" in "/test/"> +#file = #llvm.di_file<"debuginfo.mlir" in "/test/"> + +// CHECK: #[[CU:.*]] = #llvm.di_compile_unit +#cu = #llvm.di_compile_unit< + sourceLanguage = DW_LANG_C, file = #file, producer = "MLIR", + isOptimized = true, emissionKind = Full +> + +// CHECK: #[[SPTYPE:.*]] = #llvm.di_subroutine_type +#spType = #llvm.di_subroutine_type + +// CHECK: #[[SP:.*]] = #llvm.di_subprogram +#sp = #llvm.di_subprogram< + compileUnit = #cu, scope = #file, name = "intrinsics", linkageName = "intrinsics", + file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType +> + +// CHECK: #[[VAR:.*]] = #llvm.di_local_variable +#variable = #llvm.di_local_variable + +// CHECK: llvm.func @intrinsics(%[[ARG:.*]]: i64) +llvm.func @intrinsics(%arg: i64) { + // CHECK: %[[ALLOC:.*]] = llvm.alloca + %allocCount = llvm.mlir.constant(1 : i32) : i32 + %alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr + + // CHECK: llvm.dbg.value #[[VAR]] = %[[ARG]] + // CHECK: llvm.dbg.addr #[[VAR]] = %[[ALLOC]] + // CHECK: llvm.dbg.declare #[[VAR]] = %[[ALLOC]] + llvm.dbg.value #variable = %arg : i64 + llvm.dbg.addr #variable = %alloc : !llvm.ptr + llvm.dbg.declare #variable = %alloc : !llvm.ptr + llvm.return +}