Skip to content

Commit

Permalink
[mlir][debug] Support DIGenericSubrange. (#113441)
Browse files Browse the repository at this point in the history
`DIGenericSubrange` is used when the dimensions of the arrays are
unknown at build time (e.g. assumed-rank arrays in Fortran). It has same
`lowerBound`, `upperBound`, `count` and `stride` fields as in
`DISubrange` and its translation looks quite similar as a result.

---------

Co-authored-by: Tobias Gysi <tobias.gysi@nextsilicon.com>
  • Loading branch information
abidh and gysit authored Oct 31, 2024
1 parent e67e03a commit 89f2d50
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 23 deletions.
16 changes: 16 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down
14 changes: 7 additions & 7 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ void LLVMDialect::registerAttributes() {
//===----------------------------------------------------------------------===//

bool DINodeAttr::classof(Attribute attr) {
return llvm::isa<DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr,
DILexicalBlockAttr, DILexicalBlockFileAttr,
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
DINullTypeAttr, DIAnnotationAttr, DIStringTypeAttr,
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
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);
}

Expand Down
31 changes: 31 additions & 0 deletions mlir/lib/Target/LLVMIR/DebugImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<llvm::DIExpression *>(data))
return translateExpression(expr);
if (auto *var = dyn_cast<llvm::DIVariable *>(data)) {
if (auto *local = dyn_cast<llvm::DILocalVariable>(var))
return translate(local);
if (auto *global = dyn_cast<llvm::DIGlobalVariable>(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<DITypeAttr> types;
Expand Down Expand Up @@ -378,6 +407,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DISubrange>(node))
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DIGenericSubrange>(node))
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DISubroutineType>(node))
return translateImpl(casted);
return nullptr;
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Target/LLVMIR/DebugImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
37 changes: 32 additions & 5 deletions mlir/lib/Target/LLVMIR/DebugTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Attribute, llvm::Metadata *>(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.
Expand Down Expand Up @@ -437,11 +464,11 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
node = TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
.Case<DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr,
DILexicalBlockAttr, DILexicalBlockFileAttr,
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
DINullTypeAttr, DIStringTypeAttr, DISubprogramAttr,
DISubrangeAttr, DISubroutineTypeAttr>(
DIGenericSubrangeAttr, DIGlobalVariableAttr,
DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
[&](auto attr) { return translateImpl(attr); });

if (node && !node->isTemporary())
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Target/LLVMIR/DebugTranslation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 10 additions & 2 deletions mlir/test/Dialect/LLVMIR/debuginfo.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,17 @@
flags = "TypePassByReference|NonTrivial"
>

// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[NULL]], #[[INT0]], #[[PTR0]], #[[PTR1]], #[[PTR2]], #[[COMP0:.*]], #[[COMP1:.*]], #[[COMP2:.*]]>
// CHECK-DAG: #[[COMP3:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements2"{{.*}}elements = #llvm.di_generic_subrange<count = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16), DW_OP_deref]>, 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<tag = DW_TAG_array_type,
name = "expr_elements2", baseType = #int0, elements =
#llvm.di_generic_subrange<count = #exp1, lowerBound = #exp2, stride = #exp3>>

// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[NULL]], #[[INT0]], #[[PTR0]], #[[PTR1]], #[[PTR2]], #[[COMP0:.*]], #[[COMP1:.*]], #[[COMP2:.*]], #[[COMP3:.*]]>
#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<types = #[[INT1]], #[[INT1]]>
Expand Down
11 changes: 9 additions & 2 deletions mlir/test/Target/LLVMIR/Import/debug-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ define void @derived_type() !dbg !3 {
; CHECK-DAG: #[[COMP4:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange<lowerBound = 0 : i64, upperBound = 4 : i64, stride = 1 : i64>>
; CHECK-DAG: #[[COMP5:.+]] = #llvm.di_composite_type<{{.*}}, name = "var_elements"{{.*}}elements = #llvm.di_subrange<count = #[[VAR]], stride = #[[GV]]>>
; CHECK-DAG: #[[COMP6:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements"{{.*}}elements = #llvm.di_subrange<count = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16), DW_OP_deref]>>>
; CHECK-DAG: #llvm.di_subroutine_type<types = #[[COMP1]], #[[COMP2]], #[[COMP3]], #[[COMP4]], #[[COMP5]], #[[COMP6]]>
; CHECK-DAG: #[[COMP7:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements2"{{.*}}elements = #llvm.di_generic_subrange<count = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16), DW_OP_deref]>, 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<types = #[[COMP1]], #[[COMP2]], #[[COMP3]], #[[COMP4]], #[[COMP5]], #[[COMP6]], #[[COMP7]]>

@gv = external global i64

Expand All @@ -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)
Expand All @@ -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}


; // -----
Expand Down
35 changes: 28 additions & 7 deletions mlir/test/Target/LLVMIR/llvmir-debug.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -591,35 +591,48 @@ 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<tag = DW_TAG_base_type, name = "int">
#file = #llvm.di_file<"debug-info.ll" in "/">
#cu = #llvm.di_compile_unit<id = distinct[1]<>,
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<tag = DW_TAG_array_type,
name = "expr_elements", baseType = #bt, flags = Vector,
elements = #llvm.di_subrange<count = #llvm.di_expression<
[DW_OP_push_object_address, DW_OP_plus_uconst(16), DW_OP_deref]>>>
#srty = #llvm.di_subroutine_type<types = #bt, #comp_ty1>
elements = #llvm.di_subrange<count = #exp1>>
#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<tag = DW_TAG_array_type,
name = "expr_elements2", baseType = #bt, elements =
#llvm.di_generic_subrange<count = #exp1, lowerBound = #exp2, stride = #exp3>>
#srty = #llvm.di_subroutine_type<types = #bt, #comp_ty1, #comp_ty2>
#sp = #llvm.di_subprogram<compileUnit = #cu, scope = #file, name = "subranges",
file = #file, subprogramFlags = Definition, type = #srty>
#lvar = #llvm.di_local_variable<scope = #sp, name = "size">
#gv = #llvm.di_global_variable<scope = #cu, name = "gv", file = #file,
line = 3, type = #bt>
#gve = #llvm.di_global_variable_expression<var = #gv, expr = <>>
#comp_ty2 = #llvm.di_composite_type<tag = DW_TAG_array_type,
#comp_ty3 = #llvm.di_composite_type<tag = DW_TAG_array_type,
name = "var_elements", baseType = #bt, flags = Vector,
elements = #llvm.di_subrange<count = #lvar, stride = #gv>>
#lvar2 = #llvm.di_local_variable<scope = #sp, name = "var", type = #comp_ty2>
#comp_ty4 = #llvm.di_composite_type<tag = DW_TAG_array_type,
name = "var_elements2", baseType = #bt, elements =
#llvm.di_generic_subrange<count = #lvar, lowerBound = #gv, stride = #gv>>
#lvar2 = #llvm.di_local_variable<scope = #sp, name = "var", type = #comp_ty3>
#lvar3 = #llvm.di_local_variable<scope = #sp, name = "var1", type = #comp_ty4>
#loc1 = loc("test.f90": 1:1)
#loc2 = loc(fused<#sp>[#loc1])

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)

Expand All @@ -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]])

// -----

Expand Down

0 comments on commit 89f2d50

Please sign in to comment.