diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 855fa5702f5b9c..e8eeafd09a9cba 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -721,6 +721,22 @@ def LLVM_DICommonBlockAttr : LLVM_Attr<"DICommonBlock", "di_common_block", let assemblyFormat = "`<` struct(params) `>`"; } +//===----------------------------------------------------------------------===// +// DIGenericSubrangeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DIGenericSubrangeAttr : LLVM_Attr<"DIGenericSubrange", + "di_generic_subrange", /*traits=*/[], + "DINodeAttr"> { + let parameters = (ins + OptionalParameter<"::mlir::Attribute">:$count, + "::mlir::Attribute":$lowerBound, + OptionalParameter<"::mlir::Attribute">:$upperBound, + "::mlir::Attribute":$stride + ); + let assemblyFormat = "`<` struct(params) `>`"; +} + //===----------------------------------------------------------------------===// // DISubroutineTypeAttr //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index 9640bbdf28df45..ee4e344674a67e 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -56,13 +56,13 @@ void LLVMDialect::registerAttributes() { //===----------------------------------------------------------------------===// bool DINodeAttr::classof(Attribute attr) { - return llvm::isa( + return llvm::isa< + DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr, + DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr, DIGenericSubrangeAttr, + DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr, + DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr, + DIModuleAttr, DINamespaceAttr, DINullTypeAttr, DIAnnotationAttr, + DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>( attr); } diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index 412125b6ea65f6..779c1d12720c1f 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -309,6 +309,35 @@ DICommonBlockAttr DebugImporter::translateImpl(llvm::DICommonBlock *node) { translate(node->getFile()), node->getLineNo()); } +DIGenericSubrangeAttr +DebugImporter::translateImpl(llvm::DIGenericSubrange *node) { + auto getAttrOrNull = + [&](llvm::DIGenericSubrange::BoundType data) -> Attribute { + if (data.isNull()) + return nullptr; + if (auto *expr = dyn_cast(data)) + return translateExpression(expr); + if (auto *var = dyn_cast(data)) { + if (auto *local = dyn_cast(var)) + return translate(local); + if (auto *global = dyn_cast(var)) + return translate(global); + return nullptr; + } + return nullptr; + }; + Attribute count = getAttrOrNull(node->getCount()); + Attribute upperBound = getAttrOrNull(node->getUpperBound()); + Attribute lowerBound = getAttrOrNull(node->getLowerBound()); + Attribute stride = getAttrOrNull(node->getStride()); + // Either count or the upper bound needs to be present. Otherwise, the + // metadata is invalid. + if (!count && !upperBound) + return {}; + return DIGenericSubrangeAttr::get(context, count, lowerBound, upperBound, + stride); +} + DISubroutineTypeAttr DebugImporter::translateImpl(llvm::DISubroutineType *node) { SmallVector types; @@ -378,6 +407,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) { return translateImpl(casted); if (auto *casted = dyn_cast(node)) return translateImpl(casted); + if (auto *casted = dyn_cast(node)) + return translateImpl(casted); if (auto *casted = dyn_cast(node)) return translateImpl(casted); return nullptr; diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.h b/mlir/lib/Target/LLVMIR/DebugImporter.h index a452e01a9f6041..b224ad3376be71 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.h +++ b/mlir/lib/Target/LLVMIR/DebugImporter.h @@ -79,6 +79,7 @@ class DebugImporter { DIScopeAttr translateImpl(llvm::DIScope *node); DISubprogramAttr translateImpl(llvm::DISubprogram *node); DISubrangeAttr translateImpl(llvm::DISubrange *node); + DIGenericSubrangeAttr translateImpl(llvm::DIGenericSubrange *node); DICommonBlockAttr translateImpl(llvm::DICommonBlock *node); DISubroutineTypeAttr translateImpl(llvm::DISubroutineType *node); DITypeAttr translateImpl(llvm::DIType *node); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index 2491db299af312..cf734de49acd62 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -404,6 +404,33 @@ llvm::DICommonBlock *DebugTranslation::translateImpl(DICommonBlockAttr attr) { translate(attr.getFile()), attr.getLine()); } +llvm::DIGenericSubrange * +DebugTranslation::translateImpl(DIGenericSubrangeAttr attr) { + auto getMetadataOrNull = [&](Attribute attr) -> llvm::Metadata * { + if (!attr) + return nullptr; + + llvm::Metadata *metadata = + llvm::TypeSwitch(attr) + .Case([&](LLVM::DIExpressionAttr expr) { + return translateExpression(expr); + }) + .Case([&](LLVM::DILocalVariableAttr local) { + return translate(local); + }) + .Case<>([&](LLVM::DIGlobalVariableAttr global) { + return translate(global); + }) + .Default([&](Attribute attr) { return nullptr; }); + return metadata; + }; + return llvm::DIGenericSubrange::get(llvmCtx, + getMetadataOrNull(attr.getCount()), + getMetadataOrNull(attr.getLowerBound()), + getMetadataOrNull(attr.getUpperBound()), + getMetadataOrNull(attr.getStride())); +} + llvm::DISubroutineType * DebugTranslation::translateImpl(DISubroutineTypeAttr attr) { // Concatenate the result and argument types into a single array. @@ -437,11 +464,11 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) { node = TypeSwitch(attr) .Case( + DIGenericSubrangeAttr, DIGlobalVariableAttr, + DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr, + DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr, + DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr, + DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>( [&](auto attr) { return translateImpl(attr); }); if (node && !node->isTemporary()) diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h index ff4eaa46c564e2..930e6a2672136d 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -87,6 +87,7 @@ class DebugTranslation { llvm::DINamespace *translateImpl(DINamespaceAttr attr); llvm::DIScope *translateImpl(DIScopeAttr attr); llvm::DISubprogram *translateImpl(DISubprogramAttr attr); + llvm::DIGenericSubrange *translateImpl(DIGenericSubrangeAttr attr); llvm::DISubrange *translateImpl(DISubrangeAttr attr); llvm::DICommonBlock *translateImpl(DICommonBlockAttr attr); llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr); diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir index dafb3bcef740f0..1147cb110199d0 100644 --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -80,9 +80,17 @@ flags = "TypePassByReference|NonTrivial" > -// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type +// CHECK-DAG: #[[COMP3:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements2"{{.*}}elements = #llvm.di_generic_subrange, lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24), DW_OP_deref]>, stride = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32), DW_OP_deref]>>> +#exp1 = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16), DW_OP_deref]> +#exp2 = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24), DW_OP_deref]> +#exp3 = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32), DW_OP_deref]> +#comp3 = #llvm.di_composite_type> + +// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type #spType0 = #llvm.di_subroutine_type< - callingConvention = DW_CC_normal, types = #null, #int0, #ptr0, #ptr1, #ptr2, #comp0, #comp1, #comp2 + callingConvention = DW_CC_normal, types = #null, #int0, #ptr0, #ptr1, #ptr2, #comp0, #comp1, #comp2, #comp3 > // CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 9ef1942e0787c6..9e2a17fb436af7 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -169,7 +169,8 @@ define void @derived_type() !dbg !3 { ; CHECK-DAG: #[[COMP4:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange> ; CHECK-DAG: #[[COMP5:.+]] = #llvm.di_composite_type<{{.*}}, name = "var_elements"{{.*}}elements = #llvm.di_subrange> ; CHECK-DAG: #[[COMP6:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements"{{.*}}elements = #llvm.di_subrange>> -; CHECK-DAG: #llvm.di_subroutine_type +; CHECK-DAG: #[[COMP7:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements2"{{.*}}elements = #llvm.di_generic_subrange, lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24), DW_OP_deref]>, stride = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32), DW_OP_deref]>>> +; CHECK-DAG: #llvm.di_subroutine_type @gv = external global i64 @@ -184,7 +185,7 @@ define void @composite_type() !dbg !3 { !2 = !DIFile(filename: "debug-info.ll", directory: "/") !3 = distinct !DISubprogram(name: "composite_type", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4) !4 = !DISubroutineType(types: !5) -!5 = !{!7, !8, !9, !10, !18, !22} +!5 = !{!7, !8, !9, !10, !18, !22, !24} !6 = !DIBasicType(name: "int") !7 = !DICompositeType(tag: DW_TAG_array_type, name: "array1", line: 10, size: 128, align: 32, baseType: !6) !8 = !DICompositeType(tag: DW_TAG_array_type, name: "array2", file: !2, scope: !2, baseType: !6) @@ -203,6 +204,12 @@ define void @composite_type() !dbg !3 { !21 = !{!19} !22 = !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements", flags: DIFlagVector, elements: !21, baseType: !6) !23 = !DIGlobalVariable(name: "gv", scope: !1, file: !2, line: 3, type: !6, isLocal: false, isDefinition: false) +!24 = !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements2", elements: !29, baseType: !6) +!25 = !DIGenericSubrange(count: !26, lowerBound: !27, stride: !28) +!26 = !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref) +!27 = !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref) +!28 = !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref) +!29 = !{!25} ; // ----- diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index b97bdcbc772d80..eac2c5090a5b5c 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -591,28 +591,40 @@ llvm.func @fn_with_composite() { // ----- -// Test that Subrange works with expression and variables. +// Test that Subrange/generic_subrange works with expression and variables. #bt = #llvm.di_basic_type #file = #llvm.di_file<"debug-info.ll" in "/"> #cu = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #file, isOptimized = false, emissionKind = Full> +#exp1 = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16), + DW_OP_deref]> #comp_ty1 = #llvm.di_composite_type>> -#srty = #llvm.di_subroutine_type + elements = #llvm.di_subrange> +#exp2 = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24), + DW_OP_deref]> +#exp3 = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32), + DW_OP_deref]> +#comp_ty2 = #llvm.di_composite_type> +#srty = #llvm.di_subroutine_type #sp = #llvm.di_subprogram #lvar = #llvm.di_local_variable #gv = #llvm.di_global_variable #gve = #llvm.di_global_variable_expression> -#comp_ty2 = #llvm.di_composite_type> -#lvar2 = #llvm.di_local_variable +#comp_ty4 = #llvm.di_composite_type> +#lvar2 = #llvm.di_local_variable +#lvar3 = #llvm.di_local_variable #loc1 = loc("test.f90": 1:1) #loc2 = loc(fused<#sp>[#loc1]) @@ -620,6 +632,7 @@ llvm.mlir.global external @gv() {dbg_exprs = [#gve]} : i64 llvm.func @subranges(%arg: !llvm.ptr) { llvm.intr.dbg.declare #lvar2 = %arg : !llvm.ptr + llvm.intr.dbg.declare #lvar3 = %arg : !llvm.ptr llvm.return } loc(#loc2) @@ -628,11 +641,19 @@ llvm.func @subranges(%arg: !llvm.ptr) { // CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements"{{.*}}elements: ![[ELEMENTS1:[0-9]+]]) // CHECK: ![[ELEMENTS1]] = !{![[ELEMENT1:[0-9]+]]} // CHECK: ![[ELEMENT1]] = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref)) +// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements2"{{.*}}elements: ![[GSR_ELEMS:[0-9]+]]) +// CHECK: ![[GSR_ELEMS]] = !{![[GSR_ELEM:[0-9]+]]} +// CHECK: ![[GSR_ELEM]] = !DIGenericSubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref) +// CHECK-SAME: lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref) +// CHECK-SAME: stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref) // CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "var_elements"{{.*}}elements: ![[ELEMENTS2:[0-9]+]]) // CHECK: ![[ELEMENTS2]] = !{![[ELEMENT2:[0-9]+]]} -// CHECK: ![[ELEMENT2]] = !DISubrange(count: ![[LV:[0-9]+]], stride: ![[GV:[0-9]+]]) +// CHECK: ![[ELEMENT2]] = !DISubrange(count: ![[LV:[0-9]+]], stride: ![[GV]]) // CHECK: ![[LV]] = !DILocalVariable(name: "size"{{.*}}) +// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "var_elements2", baseType: !{{.*}}, elements: ![[GSR_ELEMS2:[0-9]+]]) +// CHECK: ![[GSR_ELEMS2]] = !{![[GSR_ELEM2:[0-9]+]]} +// CHECK: ![[GSR_ELEM2]] = !DIGenericSubrange(count: ![[LV]], lowerBound: ![[GV]], stride: ![[GV]]) // -----