Skip to content

Commit 259da6b

Browse files
author
walter erquinigo
committed
[mlir][debuginfo] Add support for subroutine annotations
LLVM already supports `DW_TAG_LLVM_annotation` entries for subroutines, but this hasn't been surfaced to the LLVM dialect. I'm doing the minimal amount of work to support string-based annotations, which is useful for attaching metadata to functions, which is useful for debuggers to offer features beyond basic DWARF. As LLVM already supports this, this patch is not controversial.
1 parent 144dc4c commit 259da6b

File tree

10 files changed

+81
-22
lines changed

10 files changed

+81
-22
lines changed

flang/lib/Optimizer/Transforms/AddDebugInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
330330
if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly) {
331331
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
332332
context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
333-
line, line, subprogramFlags, subTypeAttr, /*retainedNodes=*/{});
333+
line, line, subprogramFlags, subTypeAttr, /*retainedNodes=*/{},
334+
/*annotations=*/{});
334335
funcOp->setLoc(builder.getFusedLoc({l}, spAttr));
335336
return;
336337
}
@@ -354,7 +355,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
354355
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
355356
context, recId, /*isRecSelf=*/true, id, compilationUnit, Scope, funcName,
356357
fullName, funcFileAttr, line, line, subprogramFlags, subTypeAttr,
357-
/*retainedNodes=*/{});
358+
/*retainedNodes=*/{}, /*annotations=*/{});
358359

359360
// There is no direct information in the IR for any 'use' statement in the
360361
// function. We have to extract that information from the DeclareOp. We do
@@ -387,7 +388,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
387388
spAttr = mlir::LLVM::DISubprogramAttr::get(
388389
context, recId, /*isRecSelf=*/false, id2, compilationUnit, Scope,
389390
funcName, fullName, funcFileAttr, line, line, subprogramFlags,
390-
subTypeAttr, entities);
391+
subTypeAttr, entities, /*annotations=*/{});
391392
funcOp->setLoc(builder.getFusedLoc({l}, spAttr));
392393

393394
funcOp.walk([&](fir::cg::XDeclareOp declOp) {

mlir/include/mlir-c/Dialect/LLVM.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,12 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDISubprogramAttrGet(
325325
MlirAttribute compileUnit, MlirAttribute scope, MlirAttribute name,
326326
MlirAttribute linkageName, MlirAttribute file, unsigned int line,
327327
unsigned int scopeLine, uint64_t subprogramFlags, MlirAttribute type,
328-
intptr_t nRetainedNodes, MlirAttribute const *retainedNodes);
328+
intptr_t nRetainedNodes, MlirAttribute const *retainedNodes,
329+
intptr_t nAnnotations, MlirAttribute const *annotations);
330+
331+
/// Creates a LLVM DIStringAnnotation attribute.
332+
MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIStringAnnotationAttrGet(
333+
MlirContext ctx, MlirAttribute name, MlirAttribute value);
329334

330335
/// Gets the scope from this DISubprogramAttr.
331336
MLIR_CAPI_EXPORTED MlirAttribute

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -586,19 +586,20 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
586586
OptionalParameter<"unsigned">:$scopeLine,
587587
OptionalParameter<"DISubprogramFlags">:$subprogramFlags,
588588
OptionalParameter<"DISubroutineTypeAttr">:$type,
589-
OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes
589+
OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes,
590+
OptionalArrayRefParameter<"DINodeAttr">:$annotations
590591
);
591592
let builders = [
592593
AttrBuilder<(ins
593594
"DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
594595
"DIScopeAttr":$scope, "StringAttr":$name, "StringAttr":$linkageName,
595596
"DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
596597
"DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type,
597-
"ArrayRef<DINodeAttr>":$retainedNodes
598+
"ArrayRef<DINodeAttr>":$retainedNodes, "ArrayRef<DINodeAttr>":$annotations
598599
), [{
599600
return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/false, id, compileUnit,
600601
scope, name, linkageName, file, line, scopeLine,
601-
subprogramFlags, type, retainedNodes);
602+
subprogramFlags, type, retainedNodes, annotations);
602603
}]>
603604
];
604605
let assemblyFormat = "`<` struct(params) `>`";
@@ -670,6 +671,21 @@ def LLVM_DIImportedEntityAttr : LLVM_Attr<"DIImportedEntity", "di_imported_entit
670671
let assemblyFormat = "`<` struct(params) `>`";
671672
}
672673

674+
//===----------------------------------------------------------------------===//
675+
// DIStringAnnotationAttr
676+
//===----------------------------------------------------------------------===//
677+
678+
def LLVM_DIStringAnnotationAttr : LLVM_Attr<"DIStringAnnotation",
679+
"di_string_annotation",
680+
/*traits=*/[], "DINodeAttr"> {
681+
let parameters = (ins
682+
"StringAttr":$name,
683+
"StringAttr":$value
684+
);
685+
686+
let assemblyFormat = "`<` struct(params) `>`";
687+
}
688+
673689
//===----------------------------------------------------------------------===//
674690
// DISubrangeAttr
675691
//===----------------------------------------------------------------------===//

mlir/lib/CAPI/Dialect/LLVM.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,14 @@ MlirAttribute mlirLLVMDISubprogramAttrGet(
303303
MlirAttribute compileUnit, MlirAttribute scope, MlirAttribute name,
304304
MlirAttribute linkageName, MlirAttribute file, unsigned int line,
305305
unsigned int scopeLine, uint64_t subprogramFlags, MlirAttribute type,
306-
intptr_t nRetainedNodes, MlirAttribute const *retainedNodes) {
306+
intptr_t nRetainedNodes, MlirAttribute const *retainedNodes,
307+
intptr_t nAnnotations, MlirAttribute const *annotations) {
307308
SmallVector<Attribute> nodesStorage;
308309
nodesStorage.reserve(nRetainedNodes);
310+
311+
SmallVector<Attribute> annotationsStorage;
312+
annotationsStorage.reserve(nAnnotations);
313+
309314
return wrap(DISubprogramAttr::get(
310315
unwrap(ctx), cast<DistinctAttr>(unwrap(recId)), isRecSelf,
311316
cast<DistinctAttr>(unwrap(id)),
@@ -316,6 +321,9 @@ MlirAttribute mlirLLVMDISubprogramAttrGet(
316321
cast<DISubroutineTypeAttr>(unwrap(type)),
317322
llvm::map_to_vector(
318323
unwrapList(nRetainedNodes, retainedNodes, nodesStorage),
324+
[](Attribute a) { return cast<DINodeAttr>(a); }),
325+
llvm::map_to_vector(
326+
unwrapList(nAnnotations, annotations, annotationsStorage),
319327
[](Attribute a) { return cast<DINodeAttr>(a); })));
320328
}
321329

@@ -375,3 +383,11 @@ MlirAttribute mlirLLVMDIImportedEntityAttrGet(
375383
llvm::map_to_vector(unwrapList(nElements, elements, elementsStorage),
376384
[](Attribute a) { return cast<DINodeAttr>(a); })));
377385
}
386+
387+
MlirAttribute mlirLLVMDIStringAnnotationAttrGet(MlirContext ctx,
388+
MlirAttribute name,
389+
MlirAttribute value) {
390+
return wrap(DIStringAnnotationAttr::get(unwrap(ctx),
391+
cast<StringAttr>(unwrap(name)),
392+
cast<StringAttr>(unwrap(value))));
393+
}

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ bool DINodeAttr::classof(Attribute attr) {
6060
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
6161
DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
6262
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
63-
DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
64-
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
65-
attr);
63+
DINamespaceAttr, DINullTypeAttr, DIStringAnnotationAttr,
64+
DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr,
65+
DISubroutineTypeAttr>(attr);
6666
}
6767

6868
//===----------------------------------------------------------------------===//
@@ -221,15 +221,16 @@ DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
221221
//===----------------------------------------------------------------------===//
222222

223223
DIRecursiveTypeAttrInterface DISubprogramAttr::withRecId(DistinctAttr recId) {
224-
return DISubprogramAttr::get(
225-
getContext(), recId, getIsRecSelf(), getId(), getCompileUnit(),
226-
getScope(), getName(), getLinkageName(), getFile(), getLine(),
227-
getScopeLine(), getSubprogramFlags(), getType(), getRetainedNodes());
224+
return DISubprogramAttr::get(getContext(), recId, getIsRecSelf(), getId(),
225+
getCompileUnit(), getScope(), getName(),
226+
getLinkageName(), getFile(), getLine(),
227+
getScopeLine(), getSubprogramFlags(), getType(),
228+
getRetainedNodes(), getAnnotations());
228229
}
229230

230231
DIRecursiveTypeAttrInterface DISubprogramAttr::getRecSelf(DistinctAttr recId) {
231232
return DISubprogramAttr::get(recId.getContext(), recId, /*isRecSelf=*/true,
232-
{}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {});
233+
{}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {}, {});
233234
}
234235

235236
//===----------------------------------------------------------------------===//

mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
7878
auto subprogramAttr = LLVM::DISubprogramAttr::get(
7979
context, id, compileUnitAttr, fileAttr, funcName, funcName, fileAttr,
8080
/*line=*/line, /*scopeline=*/col, subprogramFlags, subroutineTypeAttr,
81-
/*retainedNodes=*/{});
81+
/*retainedNodes=*/{}, /*annotations=*/{});
8282
llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
8383
}
8484

mlir/lib/Target/LLVMIR/DebugImporter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,16 @@ DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) {
245245
if (llvm::is_contained(retainedNodes, nullptr))
246246
retainedNodes.clear();
247247

248+
SmallVector<DINodeAttr> annotations;
249+
for (llvm::DINode *annotation : node->getAnnotations())
250+
retainedNodes.push_back(translate(annotation));
251+
248252
return DISubprogramAttr::get(context, id, translate(node->getUnit()), scope,
249253
getStringAttrOrNull(node->getRawName()),
250254
getStringAttrOrNull(node->getRawLinkageName()),
251255
translate(node->getFile()), node->getLine(),
252256
node->getScopeLine(), *subprogramFlags, type,
253-
retainedNodes);
257+
retainedNodes, annotations);
254258
}
255259

256260
DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) {

mlir/lib/Target/LLVMIR/DebugTranslation.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ DebugTranslation::getMDTupleOrNull(ArrayRef<DINodeAttr> elements) {
102102
return nullptr;
103103
SmallVector<llvm::Metadata *> llvmElements = llvm::to_vector(
104104
llvm::map_range(elements, [&](DINodeAttr attr) -> llvm::Metadata * {
105+
if (DIStringAnnotationAttr annAttr =
106+
dyn_cast<DIStringAnnotationAttr>(attr)) {
107+
llvm::Metadata *ops[2] = {
108+
llvm::MDString::get(llvmCtx, annAttr.getName()),
109+
llvm::MDString::get(llvmCtx, annAttr.getValue())};
110+
return llvm::MDNode::get(llvmCtx, ops);
111+
}
105112
return translate(attr);
106113
}));
107114
return llvm::MDNode::get(llvmCtx, llvmElements);
@@ -332,7 +339,8 @@ llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
332339
/*ThisAdjustment=*/0, llvm::DINode::FlagZero,
333340
static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
334341
compileUnit, /*TemplateParams=*/nullptr, /*Declaration=*/nullptr,
335-
getMDTupleOrNull(attr.getRetainedNodes()));
342+
getMDTupleOrNull(attr.getRetainedNodes()), nullptr,
343+
getMDTupleOrNull(attr.getAnnotations()));
336344
if (attr.getId())
337345
distinctAttrToNode.try_emplace(attr.getId(), node);
338346
return node;

mlir/test/CAPI/llvm.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,16 @@ static void testDebugInfoAttributes(MlirContext ctx) {
324324
mlirAttributeDump(di_imported_entity);
325325
// CHECK: #llvm.di_imported_entity<{{.*}}>
326326

327+
MlirAttribute di_annotation = mlirLLVMDIStringAnnotationAttrGet(
328+
ctx, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo")),
329+
mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar")));
330+
331+
mlirAttributeDump(di_annotation);
332+
// CHECK: #llvm.di_string_annotation<{{.*}}>
333+
327334
MlirAttribute di_subprogram = mlirLLVMDISubprogramAttrGet(
328335
ctx, recId0, false, id, compile_unit, compile_unit, foo, bar, file, 1, 2,
329-
0, subroutine_type, 1, &di_imported_entity);
336+
0, subroutine_type, 1, &di_imported_entity, 1, &di_annotation);
330337
// CHECK: #llvm.di_subprogram<{{.*}}>
331338
mlirAttributeDump(di_subprogram);
332339

mlir/test/Dialect/LLVMIR/debuginfo.mlir

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,11 @@
116116
apinotes = "/", line = 42, isDecl = true
117117
>
118118

119-
// CHECK-DAG: #[[SP2:.*]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[MODULE]], name = "value", file = #[[FILE]], subprogramFlags = Definition, type = #[[SPTYPE2]]>
119+
// CHECK-DAG: #[[SP2:.*]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[MODULE]], name = "value", file = #[[FILE]], subprogramFlags = Definition, type = #[[SPTYPE2]], annotations = #llvm.di_string_annotation<name = "foo", value = "bar">
120120
#sp2 = #llvm.di_subprogram<
121121
compileUnit = #cu, scope = #module, name = "value",
122-
file = #file, subprogramFlags = "Definition", type = #spType2
122+
file = #file, subprogramFlags = "Definition", type = #spType2,
123+
annotations = #llvm.di_string_annotation<name = "foo", value = "bar">
123124
>
124125

125126
// CHECK-DAG: #[[BLOCK0:.*]] = #llvm.di_lexical_block<scope = #[[SP0]], line = 1, column = 2>

0 commit comments

Comments
 (0)