Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mlir][debuginfo] Add support for subroutine annotations #110946

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

walter-erquinigo
Copy link
Member

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Oct 3, 2024

@llvm/pr-subscribers-mlir-llvm

Author: Walter Erquinigo (walter-erquinigo)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/110946.diff

4 Files Affected:

  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+19-3)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp (+9-8)
  • (modified) mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp (+1-1)
  • (modified) mlir/lib/Target/LLVMIR/DebugTranslation.cpp (+22-3)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 2da45eba77655b..dc711232aa9be8 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -586,7 +586,8 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
     OptionalParameter<"unsigned">:$scopeLine,
     OptionalParameter<"DISubprogramFlags">:$subprogramFlags,
     OptionalParameter<"DISubroutineTypeAttr">:$type,
-    OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes
+    OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes,
+    OptionalArrayRefParameter<"DINodeAttr">:$annotations
   );
   let builders = [
     AttrBuilder<(ins
@@ -594,11 +595,11 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
       "DIScopeAttr":$scope, "StringAttr":$name, "StringAttr":$linkageName,
       "DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
       "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type,
-      "ArrayRef<DINodeAttr>":$retainedNodes
+      "ArrayRef<DINodeAttr>":$retainedNodes, "ArrayRef<DINodeAttr>":$annotations
     ), [{
       return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/false, id, compileUnit,
                    scope, name, linkageName, file, line, scopeLine,
-                   subprogramFlags, type, retainedNodes);
+                   subprogramFlags, type, retainedNodes, annotations);
     }]>
   ];
   let assemblyFormat = "`<` struct(params) `>`";
@@ -670,6 +671,21 @@ def LLVM_DIImportedEntityAttr : LLVM_Attr<"DIImportedEntity", "di_imported_entit
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// DIStringAnnotationAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIStringAnnotationAttr : LLVM_Attr<"DIStringAnnotation",
+                                            "di_string_annotation",
+                                           /*traits=*/[], "DINodeAttr"> {
+  let parameters = (ins
+    "StringAttr":$name,
+    "StringAttr":$value
+  );
+
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // DISubrangeAttr
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index bd2164e640e7b8..a4304ef6668e5e 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -60,9 +60,9 @@ bool DINodeAttr::classof(Attribute attr) {
                    DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
                    DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
                    DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
-                   DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
-                   DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
-      attr);
+                   DINamespaceAttr, DINullTypeAttr, DIStringAnnotationAttr,
+                   DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr,
+                   DISubroutineTypeAttr>(attr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -221,15 +221,16 @@ DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
 //===----------------------------------------------------------------------===//
 
 DIRecursiveTypeAttrInterface DISubprogramAttr::withRecId(DistinctAttr recId) {
-  return DISubprogramAttr::get(
-      getContext(), recId, getIsRecSelf(), getId(), getCompileUnit(),
-      getScope(), getName(), getLinkageName(), getFile(), getLine(),
-      getScopeLine(), getSubprogramFlags(), getType(), getRetainedNodes());
+  return DISubprogramAttr::get(getContext(), recId, getIsRecSelf(), getId(),
+                               getCompileUnit(), getScope(), getName(),
+                               getLinkageName(), getFile(), getLine(),
+                               getScopeLine(), getSubprogramFlags(), getType(),
+                               getRetainedNodes(), getAnnotations());
 }
 
 DIRecursiveTypeAttrInterface DISubprogramAttr::getRecSelf(DistinctAttr recId) {
   return DISubprogramAttr::get(recId.getContext(), recId, /*isRecSelf=*/true,
-                               {}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {});
+                               {}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {}, {});
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index 2cfaffa7c8efce..59a4f8e9023582 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -78,7 +78,7 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
   auto subprogramAttr = LLVM::DISubprogramAttr::get(
       context, id, compileUnitAttr, fileAttr, funcName, funcName, fileAttr,
       /*line=*/line, /*scopeline=*/col, subprogramFlags, subroutineTypeAttr,
-      /*retainedNodes=*/{});
+      /*retainedNodes=*/{}, /*annotations=*/{});
   llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
 }
 
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 8ca3beca6b66f7..5b7b28a761ec83 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -102,6 +102,13 @@ DebugTranslation::getMDTupleOrNull(ArrayRef<DINodeAttr> elements) {
     return nullptr;
   SmallVector<llvm::Metadata *> llvmElements = llvm::to_vector(
       llvm::map_range(elements, [&](DINodeAttr attr) -> llvm::Metadata * {
+        if (DIStringAnnotationAttr annAttr =
+                dyn_cast<DIStringAnnotationAttr>(attr)) {
+          llvm::Metadata *ops[2] = {
+              llvm::MDString::get(llvmCtx, annAttr.getName()),
+              llvm::MDString::get(llvmCtx, annAttr.getValue())};
+          return llvm::MDNode::get(llvmCtx, ops);
+        }
         return translate(attr);
       }));
   return llvm::MDNode::get(llvmCtx, llvmElements);
@@ -332,7 +339,8 @@ llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
       /*ThisAdjustment=*/0, llvm::DINode::FlagZero,
       static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
       compileUnit, /*TemplateParams=*/nullptr, /*Declaration=*/nullptr,
-      getMDTupleOrNull(attr.getRetainedNodes()));
+      getMDTupleOrNull(attr.getRetainedNodes()), nullptr,
+      getMDTupleOrNull(attr.getAnnotations()));
   if (attr.getId())
     distinctAttrToNode.try_emplace(attr.getId(), node);
   return node;
@@ -361,6 +369,16 @@ DebugTranslation::translateImpl(DIImportedEntityAttr attr) {
       getMDStringOrNull(attr.getName()), getMDTupleOrNull(attr.getElements()));
 }
 
+/*
+llvm::DINodeArray *
+DebugTranslation::translateImpl(DIStringAnnotationAttr attr) {
+  llvm::DINodeArray arr;
+  arr->push_back(llvm::MDString::get(llvmCtx, attr.getName()));
+  arr->push_back(llvm::MDString::get(llvmCtx, attr.getValue()));
+  return arr;
+}
+*/
+
 llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
   auto getMetadataOrNull = [&](Attribute attr) -> llvm::Metadata * {
     if (!attr)
@@ -426,8 +444,9 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
                      DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
                      DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
                      DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
-                     DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
-                   [&](auto attr) { return translateImpl(attr); });
+                     DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr
+                     // DIStringAnnotationAttr
+                     >([&](auto attr) { return translateImpl(attr); });
 
   if (node && !node->isTemporary())
     attrToNode.insert({attr, node});

@llvmbot
Copy link
Collaborator

llvmbot commented Oct 3, 2024

@llvm/pr-subscribers-mlir

Author: Walter Erquinigo (walter-erquinigo)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/110946.diff

4 Files Affected:

  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+19-3)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp (+9-8)
  • (modified) mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp (+1-1)
  • (modified) mlir/lib/Target/LLVMIR/DebugTranslation.cpp (+22-3)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 2da45eba77655b..dc711232aa9be8 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -586,7 +586,8 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
     OptionalParameter<"unsigned">:$scopeLine,
     OptionalParameter<"DISubprogramFlags">:$subprogramFlags,
     OptionalParameter<"DISubroutineTypeAttr">:$type,
-    OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes
+    OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes,
+    OptionalArrayRefParameter<"DINodeAttr">:$annotations
   );
   let builders = [
     AttrBuilder<(ins
@@ -594,11 +595,11 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
       "DIScopeAttr":$scope, "StringAttr":$name, "StringAttr":$linkageName,
       "DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
       "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type,
-      "ArrayRef<DINodeAttr>":$retainedNodes
+      "ArrayRef<DINodeAttr>":$retainedNodes, "ArrayRef<DINodeAttr>":$annotations
     ), [{
       return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/false, id, compileUnit,
                    scope, name, linkageName, file, line, scopeLine,
-                   subprogramFlags, type, retainedNodes);
+                   subprogramFlags, type, retainedNodes, annotations);
     }]>
   ];
   let assemblyFormat = "`<` struct(params) `>`";
@@ -670,6 +671,21 @@ def LLVM_DIImportedEntityAttr : LLVM_Attr<"DIImportedEntity", "di_imported_entit
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// DIStringAnnotationAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIStringAnnotationAttr : LLVM_Attr<"DIStringAnnotation",
+                                            "di_string_annotation",
+                                           /*traits=*/[], "DINodeAttr"> {
+  let parameters = (ins
+    "StringAttr":$name,
+    "StringAttr":$value
+  );
+
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // DISubrangeAttr
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index bd2164e640e7b8..a4304ef6668e5e 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -60,9 +60,9 @@ bool DINodeAttr::classof(Attribute attr) {
                    DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
                    DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
                    DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
-                   DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
-                   DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
-      attr);
+                   DINamespaceAttr, DINullTypeAttr, DIStringAnnotationAttr,
+                   DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr,
+                   DISubroutineTypeAttr>(attr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -221,15 +221,16 @@ DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
 //===----------------------------------------------------------------------===//
 
 DIRecursiveTypeAttrInterface DISubprogramAttr::withRecId(DistinctAttr recId) {
-  return DISubprogramAttr::get(
-      getContext(), recId, getIsRecSelf(), getId(), getCompileUnit(),
-      getScope(), getName(), getLinkageName(), getFile(), getLine(),
-      getScopeLine(), getSubprogramFlags(), getType(), getRetainedNodes());
+  return DISubprogramAttr::get(getContext(), recId, getIsRecSelf(), getId(),
+                               getCompileUnit(), getScope(), getName(),
+                               getLinkageName(), getFile(), getLine(),
+                               getScopeLine(), getSubprogramFlags(), getType(),
+                               getRetainedNodes(), getAnnotations());
 }
 
 DIRecursiveTypeAttrInterface DISubprogramAttr::getRecSelf(DistinctAttr recId) {
   return DISubprogramAttr::get(recId.getContext(), recId, /*isRecSelf=*/true,
-                               {}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {});
+                               {}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {}, {});
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index 2cfaffa7c8efce..59a4f8e9023582 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -78,7 +78,7 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
   auto subprogramAttr = LLVM::DISubprogramAttr::get(
       context, id, compileUnitAttr, fileAttr, funcName, funcName, fileAttr,
       /*line=*/line, /*scopeline=*/col, subprogramFlags, subroutineTypeAttr,
-      /*retainedNodes=*/{});
+      /*retainedNodes=*/{}, /*annotations=*/{});
   llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
 }
 
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 8ca3beca6b66f7..5b7b28a761ec83 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -102,6 +102,13 @@ DebugTranslation::getMDTupleOrNull(ArrayRef<DINodeAttr> elements) {
     return nullptr;
   SmallVector<llvm::Metadata *> llvmElements = llvm::to_vector(
       llvm::map_range(elements, [&](DINodeAttr attr) -> llvm::Metadata * {
+        if (DIStringAnnotationAttr annAttr =
+                dyn_cast<DIStringAnnotationAttr>(attr)) {
+          llvm::Metadata *ops[2] = {
+              llvm::MDString::get(llvmCtx, annAttr.getName()),
+              llvm::MDString::get(llvmCtx, annAttr.getValue())};
+          return llvm::MDNode::get(llvmCtx, ops);
+        }
         return translate(attr);
       }));
   return llvm::MDNode::get(llvmCtx, llvmElements);
@@ -332,7 +339,8 @@ llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
       /*ThisAdjustment=*/0, llvm::DINode::FlagZero,
       static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
       compileUnit, /*TemplateParams=*/nullptr, /*Declaration=*/nullptr,
-      getMDTupleOrNull(attr.getRetainedNodes()));
+      getMDTupleOrNull(attr.getRetainedNodes()), nullptr,
+      getMDTupleOrNull(attr.getAnnotations()));
   if (attr.getId())
     distinctAttrToNode.try_emplace(attr.getId(), node);
   return node;
@@ -361,6 +369,16 @@ DebugTranslation::translateImpl(DIImportedEntityAttr attr) {
       getMDStringOrNull(attr.getName()), getMDTupleOrNull(attr.getElements()));
 }
 
+/*
+llvm::DINodeArray *
+DebugTranslation::translateImpl(DIStringAnnotationAttr attr) {
+  llvm::DINodeArray arr;
+  arr->push_back(llvm::MDString::get(llvmCtx, attr.getName()));
+  arr->push_back(llvm::MDString::get(llvmCtx, attr.getValue()));
+  return arr;
+}
+*/
+
 llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
   auto getMetadataOrNull = [&](Attribute attr) -> llvm::Metadata * {
     if (!attr)
@@ -426,8 +444,9 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
                      DIImportedEntityAttr, DILabelAttr, DILexicalBlockAttr,
                      DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
                      DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr,
-                     DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
-                   [&](auto attr) { return translateImpl(attr); });
+                     DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr
+                     // DIStringAnnotationAttr
+                     >([&](auto attr) { return translateImpl(attr); });
 
   if (node && !node->isTemporary())
     attrToNode.insert({attr, node});

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.
@walter-erquinigo walter-erquinigo force-pushed the users/walter-erquinigo/annotations branch from 9c3c671 to 54f5b32 Compare October 3, 2024 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants