Skip to content

Commit 36c34ec

Browse files
abidhgysit
andauthored
[mlir][debug] Support DICommonBlock. (#111706)
A COMMON block is a named area of memory that holds a collection of variables. Fortran subprograms may map the COMMON block memory area to a list of variables. A common block is represented in LLVM debug by DICommonBlock. This PR adds support for this in MLIR. The changes are mostly mechanical apart from small change to access the DICompileUnit when the scope of the variable is DICommonBlock. --------- Co-authored-by: Tobias Gysi <[email protected]>
1 parent 39a9141 commit 36c34ec

File tree

11 files changed

+138
-30
lines changed

11 files changed

+138
-30
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

+16
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,22 @@ def LLVM_DISubrangeAttr : LLVM_Attr<"DISubrange", "di_subrange", /*traits=*/[],
701701
let assemblyFormat = "`<` struct(params) `>`";
702702
}
703703

704+
//===----------------------------------------------------------------------===//
705+
// DICommonBlockAttr
706+
//===----------------------------------------------------------------------===//
707+
708+
def LLVM_DICommonBlockAttr : LLVM_Attr<"DICommonBlock", "di_common_block",
709+
/*traits=*/[], "DIScopeAttr"> {
710+
let parameters = (ins
711+
"DIScopeAttr":$scope,
712+
OptionalParameter<"DIGlobalVariableAttr">:$decl,
713+
"StringAttr":$name,
714+
OptionalParameter<"DIFileAttr">:$file,
715+
OptionalParameter<"unsigned">:$line
716+
);
717+
let assemblyFormat = "`<` struct(params) `>`";
718+
}
719+
704720
//===----------------------------------------------------------------------===//
705721
// DISubroutineTypeAttr
706722
//===----------------------------------------------------------------------===//

mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp

+11-9
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,24 @@ void LLVMDialect::registerAttributes() {
5656
//===----------------------------------------------------------------------===//
5757

5858
bool DINodeAttr::classof(Attribute attr) {
59-
return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
60-
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
61-
DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
62-
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
63-
DINamespaceAttr, DINullTypeAttr, DIAnnotationAttr,
64-
DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr,
65-
DISubroutineTypeAttr>(attr);
59+
return llvm::isa<DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
60+
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
61+
DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr,
62+
DILexicalBlockAttr, DILexicalBlockFileAttr,
63+
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
64+
DINullTypeAttr, DIAnnotationAttr, DIStringTypeAttr,
65+
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
66+
attr);
6667
}
6768

6869
//===----------------------------------------------------------------------===//
6970
// DIScopeAttr
7071
//===----------------------------------------------------------------------===//
7172

7273
bool DIScopeAttr::classof(Attribute attr) {
73-
return llvm::isa<DICompileUnitAttr, DICompositeTypeAttr, DIFileAttr,
74-
DILocalScopeAttr, DIModuleAttr, DINamespaceAttr>(attr);
74+
return llvm::isa<DICommonBlockAttr, DICompileUnitAttr, DICompositeTypeAttr,
75+
DIFileAttr, DILocalScopeAttr, DIModuleAttr, DINamespaceAttr>(
76+
attr);
7577
}
7678

7779
//===----------------------------------------------------------------------===//

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -3369,11 +3369,12 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface {
33693369
AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
33703370
return TypeSwitch<Attribute, AliasResult>(attr)
33713371
.Case<AccessGroupAttr, AliasScopeAttr, AliasScopeDomainAttr,
3372-
DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
3373-
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
3374-
DIGlobalVariableExpressionAttr, DIImportedEntityAttr, DILabelAttr,
3375-
DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr,
3376-
DIModuleAttr, DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
3372+
DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
3373+
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
3374+
DIGlobalVariableAttr, DIGlobalVariableExpressionAttr,
3375+
DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
3376+
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
3377+
DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
33773378
DISubprogramAttr, DISubroutineTypeAttr, LoopAnnotationAttr,
33783379
LoopVectorizeAttr, LoopInterleaveAttr, LoopUnrollAttr,
33793380
LoopUnrollAndJamAttr, LoopLICMAttr, LoopDistributeAttr,

mlir/lib/Target/LLVMIR/DebugImporter.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,13 @@ DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) {
302302
getAttrOrNull(node->getStride()));
303303
}
304304

305+
DICommonBlockAttr DebugImporter::translateImpl(llvm::DICommonBlock *node) {
306+
return DICommonBlockAttr::get(context, translate(node->getScope()),
307+
translate(node->getDecl()),
308+
getStringAttrOrNull(node->getRawName()),
309+
translate(node->getFile()), node->getLineNo());
310+
}
311+
305312
DISubroutineTypeAttr
306313
DebugImporter::translateImpl(llvm::DISubroutineType *node) {
307314
SmallVector<DITypeAttr> types;
@@ -339,6 +346,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
339346
auto translateNode = [this](llvm::DINode *node) -> DINodeAttr {
340347
if (auto *casted = dyn_cast<llvm::DIBasicType>(node))
341348
return translateImpl(casted);
349+
if (auto *casted = dyn_cast<llvm::DICommonBlock>(node))
350+
return translateImpl(casted);
342351
if (auto *casted = dyn_cast<llvm::DICompileUnit>(node))
343352
return translateImpl(casted);
344353
if (auto *casted = dyn_cast<llvm::DICompositeType>(node))

mlir/lib/Target/LLVMIR/DebugImporter.h

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class DebugImporter {
7979
DIScopeAttr translateImpl(llvm::DIScope *node);
8080
DISubprogramAttr translateImpl(llvm::DISubprogram *node);
8181
DISubrangeAttr translateImpl(llvm::DISubrange *node);
82+
DICommonBlockAttr translateImpl(llvm::DICommonBlock *node);
8283
DISubroutineTypeAttr translateImpl(llvm::DISubroutineType *node);
8384
DITypeAttr translateImpl(llvm::DIType *node);
8485

mlir/lib/Target/LLVMIR/DebugTranslation.cpp

+14-6
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,13 @@ llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
397397
getMetadataOrNull(attr.getStride()));
398398
}
399399

400+
llvm::DICommonBlock *DebugTranslation::translateImpl(DICommonBlockAttr attr) {
401+
return llvm::DICommonBlock::get(llvmCtx, translate(attr.getScope()),
402+
translate(attr.getDecl()),
403+
getMDStringOrNull(attr.getName()),
404+
translate(attr.getFile()), attr.getLine());
405+
}
406+
400407
llvm::DISubroutineType *
401408
DebugTranslation::translateImpl(DISubroutineTypeAttr attr) {
402409
// Concatenate the result and argument types into a single array.
@@ -428,12 +435,13 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
428435

429436
if (!node)
430437
node = TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
431-
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
432-
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
433-
DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
434-
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
435-
DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
436-
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
438+
.Case<DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
439+
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
440+
DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr,
441+
DILexicalBlockAttr, DILexicalBlockFileAttr,
442+
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
443+
DINullTypeAttr, DIStringTypeAttr, DISubprogramAttr,
444+
DISubrangeAttr, DISubroutineTypeAttr>(
437445
[&](auto attr) { return translateImpl(attr); });
438446

439447
if (node && !node->isTemporary())

mlir/lib/Target/LLVMIR/DebugTranslation.h

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class DebugTranslation {
8888
llvm::DIScope *translateImpl(DIScopeAttr attr);
8989
llvm::DISubprogram *translateImpl(DISubprogramAttr attr);
9090
llvm::DISubrange *translateImpl(DISubrangeAttr attr);
91+
llvm::DICommonBlock *translateImpl(DICommonBlockAttr attr);
9192
llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr);
9293
llvm::DIType *translateImpl(DITypeAttr attr);
9394

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

+18-10
Original file line numberDiff line numberDiff line change
@@ -1064,19 +1064,27 @@ LogicalResult ModuleTranslation::convertGlobals() {
10641064
// There is no `globals` field in DICompileUnitAttr which can be directly
10651065
// assigned to DICompileUnit. We have to build the list by looking at the
10661066
// dbgExpr of all the GlobalOps. The scope of the variable is used to get
1067-
// the DICompileUnit in which to add it. But for the languages that
1068-
// support modules, the scope hierarchy can be
1069-
// variable -> module -> compile unit
1070-
// If a variable scope points to the module then we use the scope of the
1071-
// module to get the compile unit.
1072-
// Global variables are also used for things like static local variables
1073-
// in C and local variables with the save attribute in Fortran. The scope
1074-
// of the variable is the parent function. We use the compile unit of the
1075-
// parent function in this case.
1067+
// the DICompileUnit in which to add it.
1068+
// But there are cases where the scope of a global does not
1069+
// directly point to the DICompileUnit and we have to do a bit more work
1070+
// to get to it. Some of those cases are:
1071+
//
1072+
// 1. For the languages that support modules, the scope hierarchy can be
1073+
// variable -> DIModule -> DICompileUnit
1074+
//
1075+
// 2. For the Fortran common block variable, the scope hierarchy can be
1076+
// variable -> DICommonBlock -> DISubprogram -> DICompileUnit
1077+
//
1078+
// 3. For entities like static local variables in C or variable with
1079+
// SAVE attribute in Fortran, the scope hierarchy can be
1080+
// variable -> DISubprogram -> DICompileUnit
10761081
llvm::DIScope *scope = diGlobalVar->getScope();
10771082
if (auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
10781083
scope = mod->getScope();
1079-
else if (auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
1084+
else if (auto *cb = dyn_cast_if_present<llvm::DICommonBlock>(scope)) {
1085+
if (auto *sp = dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
1086+
scope = sp->getUnit();
1087+
} else if (auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
10801088
scope = sp->getUnit();
10811089

10821090
// Get the compile unit (scope) of the the global variable.

mlir/test/Dialect/LLVMIR/debuginfo.mlir

+8
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@
156156
// CHECK-DAG: #[[LABEL2:.*]] = #llvm.di_label<scope = #[[BLOCK2]]>
157157
#label2 = #llvm.di_label<scope = #block2>
158158

159+
// CHECK-DAG: #llvm.di_common_block<scope = #[[SP1]], name = "block", file = #[[FILE]], line = 3>
160+
#di_common_block = #llvm.di_common_block<scope = #sp1, name = "block", file = #file, line = 3>
161+
#global_var = #llvm.di_global_variable<scope = #di_common_block, name = "a",
162+
file = #file, line = 2, type = #int0>
163+
#var_expression = #llvm.di_global_variable_expression<var = #global_var,
164+
expr = <>>
165+
llvm.mlir.global common @block_() {dbg_expr = #var_expression} : i64
166+
159167
// CHECK: llvm.func @addr(%[[ARG:.*]]: i64)
160168
llvm.func @addr(%arg: i64) {
161169
// CHECK: %[[ALLOC:.*]] = llvm.alloca

mlir/test/Target/LLVMIR/Import/debug-info.ll

+24
Original file line numberDiff line numberDiff line change
@@ -843,3 +843,27 @@ define void @fn_with_annotations() !dbg !12 {
843843

844844

845845
; CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "fn_with_annotations"{{.*}}annotations = #llvm.di_annotation<name = "foo", value = "bar">>
846+
847+
; // -----
848+
849+
@block = common global [4 x i8] zeroinitializer, !dbg !0
850+
851+
define void @test() !dbg !3 {
852+
ret void
853+
}
854+
855+
!llvm.module.flags = !{!10}
856+
!llvm.dbg.cu = !{!7}
857+
858+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
859+
!1 = distinct !DIGlobalVariable(name: "alpha", scope: !2, file: !4, type: !9)
860+
!2 = !DICommonBlock(scope: !3, declaration: null, name: "block", file: !4, line: 3)
861+
!3 = distinct !DISubprogram(name: "test", scope: !4, file: !4, spFlags: DISPFlagDefinition, unit: !7)
862+
!4 = !DIFile(filename: "test.f90", directory: "")
863+
!7 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !4)
864+
!9 = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
865+
!10 = !{i32 2, !"Debug Info Version", i32 3}
866+
867+
; CHECK: #[[FILE:.+]] = #llvm.di_file<"test.f90" in "">
868+
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<{{.*}}name = "test"{{.*}}>
869+
; CHECK: #llvm.di_common_block<scope = #[[SP]], name = "block", file = #[[FILE]], line = 3>

mlir/test/Target/LLVMIR/llvmir-debug.mlir

+30
Original file line numberDiff line numberDiff line change
@@ -660,3 +660,33 @@ llvm.func @string_ty(%arg0: !llvm.ptr) {
660660

661661
// CHECK-DAG: !DIStringType(name: "character(*)", stringLength: ![[VAR:[0-9]+]], stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), size: 32, align: 8)
662662
// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "string_size"{{.*}} flags: DIFlagArtificial)
663+
664+
// -----
665+
666+
// Test translation of DICommonBlockAttr.
667+
#bt = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32>
668+
#file = #llvm.di_file<"test.f90" in "">
669+
#cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C,
670+
file = #file, isOptimized = false, emissionKind = Full>
671+
#sp = #llvm.di_subprogram<compileUnit = #cu, scope = #file, name = "test",
672+
file = #file, subprogramFlags = Definition>
673+
#di_common_block = #llvm.di_common_block<scope = #sp, name = "block",
674+
file = #file, line = 3>
675+
#global_var = #llvm.di_global_variable<scope = #di_common_block, name = "a",
676+
file = #file, line = 2, type = #bt>
677+
#var_expression = #llvm.di_global_variable_expression<var = #global_var,
678+
expr = <>>
679+
680+
llvm.mlir.global common @block_(dense<0> : tensor<8xi8>)
681+
{dbg_expr = #var_expression} : !llvm.array<8 x i8>
682+
683+
llvm.func @test() {
684+
llvm.return
685+
} loc(#loc2)
686+
687+
#loc1 = loc("test.f90":1:0)
688+
#loc2 = loc(fused<#sp>[#loc1])
689+
690+
// CHECK: !DICommonBlock(scope: ![[SCOPE:[0-9]+]], declaration: null, name: "block", file: ![[FILE:[0-9]+]], line: 3)
691+
// CHECK: ![[SCOPE]] = {{.*}}!DISubprogram(name: "test"{{.*}})
692+
// CHECK: ![[FILE]] = !DIFile(filename: "test.f90"{{.*}})

0 commit comments

Comments
 (0)