Skip to content

[mlir] Add support for DIGlobalVariable and DIGlobalVariableExpression #73367

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

Merged
merged 1 commit into from
Dec 4, 2023

Conversation

waj334
Copy link
Contributor

@waj334 waj334 commented Nov 24, 2023

This PR introduces DIGlobalVariableAttr and DIGlobalVariableExpressionAttr so that ModuleTranslation can emit the required metadata needed for debug information about global variable. The translator implementation for debug metadata needed to be refactored in order to allow translation of nodes based on MDNode (DIGlobalVariableExpressionAttr and DIExpression) in addition to DINode-based nodes.

A DIGlobalVariableExpressionAttr can now be passed to the GlobalOp operation directly and ModuleTranslation will create the respective DIGlobalVariable and DIGlobalVariableExpression nodes. The compile unit that DIGlobalVariable is expected to be configured with will be updated with the created DIGlobalVariableExpression.

@llvmbot
Copy link
Member

llvmbot commented Nov 24, 2023

@llvm/pr-subscribers-mlir-llvm

Author: Justin Wilson (waj334)

Changes

This PR introduces DIGlobalVariableAttr, DIGlobalVariableExpressionAttr and DIExpressionAttr so that ModuleTranslation can emit the required metadata needed for debug information about global variable. The translator implementation for debug metadata needed to be refactored in order to allow translation of nodes based on MDNode (DIGlobalVariableExpressionAttr and DIExpression) in addition to DINode-based nodes.

A DIGlobalVariableExpressionAttr can now be passed to the GlobalOp operation directly and ModuleTranslation will create the respective DIGlobalVariable and DIGlobalVariableExpression nodes. The compile unit that DIGlobalVariable is expected to be configured with will be updated with the created DIGlobalVariableExpression.


Patch is 21.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73367.diff

12 Files Affected:

  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+45)
  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h (+11-2)
  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+3-1)
  • (modified) mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h (+1)
  • (modified) mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp (+9-1)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp (+16-2)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+5-1)
  • (modified) mlir/lib/Target/LLVMIR/DebugImporter.cpp (+32-5)
  • (modified) mlir/lib/Target/LLVMIR/DebugImporter.h (+12-6)
  • (modified) mlir/lib/Target/LLVMIR/DebugTranslation.cpp (+29-8)
  • (modified) mlir/lib/Target/LLVMIR/DebugTranslation.h (+10-3)
  • (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+15)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 9e35bf1ba977725..09f2f7c8048349f 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -11,6 +11,7 @@
 
 include "mlir/Dialect/LLVMIR/LLVMDialect.td"
 include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/CommonAttrConstraints.td"
 
 // All of the attributes will extend this class.
 class LLVM_Attr<string name, string attrMnemonic,
@@ -447,6 +448,50 @@ def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable",
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// DIExpressionAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression",
+                                          /*traits=*/[], "MDNodeAttr"> {
+  let parameters = (ins
+    ArrayRefParameter<"uint64_t">:$operations
+  );
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
+//===----------------------------------------------------------------------===//
+// DIGlobalVariableExpressionAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIGlobalVariableExpressionAttr : LLVM_Attr<"DIGlobalVariableExpression", "di_global_variable_expression",
+                                          /*traits=*/[], "MDNodeAttr"> {
+  let parameters = (ins
+    "DIGlobalVariableAttr":$var,
+    OptionalParameter<"DIExpressionAttr">:$expr
+  );
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
+//===----------------------------------------------------------------------===//
+// DIGlobalVariableAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIGlobalVariable : LLVM_Attr<"DIGlobalVariable", "di_global_variable",
+                                      /*traits=*/[], "DINodeAttr"> {
+  let parameters = (ins
+    "DIScopeAttr":$scope,
+    OptionalParameter<"StringAttr">:$name,
+    OptionalParameter<"StringAttr">:$linkageName,
+    OptionalParameter<"DIFileAttr">:$file,
+    OptionalParameter<"unsigned">:$line,
+    OptionalParameter<"DITypeAttr">:$type,
+    OptionalParameter<"bool">:$isLocalToUnit,
+    OptionalParameter<"bool">:$isDefined,
+    OptionalParameter<"unsigned">:$alignInBits);
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // DISubprogramAttr
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
index c370bfa2b733d65..e49b40e2d487dc8 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
@@ -23,8 +23,8 @@
 namespace mlir {
 namespace LLVM {
 
-/// This class represents the base attribute for all debug info attributes.
-class DINodeAttr : public Attribute {
+/// This class represents the base attribute for all metadata attributes.
+class MDNodeAttr : public Attribute {
 public:
   using Attribute::Attribute;
 
@@ -32,6 +32,15 @@ class DINodeAttr : public Attribute {
   static bool classof(Attribute attr);
 };
 
+/// This class represents the base attribute for all debug info attributes.
+class DINodeAttr : public MDNodeAttr {
+public:
+  using MDNodeAttr::MDNodeAttr;
+
+  // Support LLVM type casting.
+  static bool classof(Attribute attr);
+};
+
 /// This class represents a LLVM attribute that describes a debug info scope.
 class DIScopeAttr : public DINodeAttr {
 public:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 88f4f81735372b9..ecfdced641299fe 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1087,6 +1087,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
     OptionalAttr<UnnamedAddr>:$unnamed_addr,
     OptionalAttr<StrAttr>:$section,
     OptionalAttr<SymbolRefAttr>:$comdat,
+    OptionalAttr<LLVM_DIGlobalVariableExpressionAttr>:$dbg_expr,
     DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
   );
   let summary = "LLVM dialect global.";
@@ -1196,7 +1197,8 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
       CArg<"bool", "false">:$dsoLocal,
       CArg<"bool", "false">:$thread_local_,
       CArg<"SymbolRefAttr", "{}">:$comdat,
-      CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
+      CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
+      CArg<"DIGlobalVariableExpressionAttr", "{}">:$dbgExpr)>
   ];
 
   let extraClassDeclaration = [{
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 4820e826d0ca357..a94596cc9583b1f 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -46,6 +46,7 @@ class LoopAnnotationTranslation;
 
 class AliasScopeAttr;
 class AliasScopeDomainAttr;
+class MDNodeAttr;
 class DINodeAttr;
 class LLVMFuncOp;
 class ComdatSelectorOp;
diff --git a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
index 3a01795ce3f53e5..a306007953d5b7b 100644
--- a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
+++ b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
@@ -86,7 +86,15 @@ LLVMTypeConverter::LLVMTypeConverter(MLIRContext *ctx,
 
     if (type.isIdentified()) {
       auto convertedType = LLVM::LLVMStructType::getIdentified(
-          type.getContext(), ("_Converted." + type.getName()).str());
+          type.getContext(), ("_Converted_" + type.getName()).str());
+      unsigned counter = 1;
+      while (convertedType.isInitialized()) {
+        assert(counter != UINT_MAX &&
+               "about to overflow struct renaming counter in conversion");
+        convertedType = LLVM::LLVMStructType::getIdentified(
+            type.getContext(),
+            ("_Converted_" + std::to_string(counter) + type.getName()).str());
+      }
 
       SmallVectorImpl<Type> &recursiveStack = getCurrentThreadRecursiveStack();
       if (llvm::count(recursiveStack, type)) {
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 3d45ab8fac4d705..1f5ed86f8d875e9 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -37,14 +37,28 @@ void LLVMDialect::registerAttributes() {
       >();
 }
 
+//===----------------------------------------------------------------------===//
+// MDNodeAttr
+//===----------------------------------------------------------------------===//
+
+bool MDNodeAttr::classof(Attribute attr) {
+  return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
+                   DIDerivedTypeAttr, DIExpressionAttr, DIFileAttr,
+                   DIGlobalVariableAttr, DIGlobalVariableExpressionAttr,
+                   DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
+                   DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
+                   DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
+                   DISubroutineTypeAttr>(attr);
+}
+
 //===----------------------------------------------------------------------===//
 // DINodeAttr
 //===----------------------------------------------------------------------===//
 
 bool DINodeAttr::classof(Attribute attr) {
   return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
-                   DIDerivedTypeAttr, DIFileAttr, DILabelAttr,
-                   DILexicalBlockAttr, DILexicalBlockFileAttr,
+                   DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
+                   DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
                    DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
                    DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
                    DISubroutineTypeAttr>(attr);
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f6c8f388732c3da..53c0c9b70a8824a 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1781,7 +1781,7 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
                      bool isConstant, Linkage linkage, StringRef name,
                      Attribute value, uint64_t alignment, unsigned addrSpace,
                      bool dsoLocal, bool threadLocal, SymbolRefAttr comdat,
-                     ArrayRef<NamedAttribute> attrs) {
+                     ArrayRef<NamedAttribute> attrs, DIGlobalVariableExpressionAttr dbgExpr) {
   result.addAttribute(getSymNameAttrName(result.name),
                       builder.getStringAttr(name));
   result.addAttribute(getGlobalTypeAttrName(result.name), TypeAttr::get(type));
@@ -1812,6 +1812,10 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
     result.addAttribute(getAddrSpaceAttrName(result.name),
                         builder.getI32IntegerAttr(addrSpace));
   result.attributes.append(attrs.begin(), attrs.end());
+
+  if (dbgExpr)
+    result.addAttribute(getDbgExprAttrName(result.name), dbgExpr);
+
   result.addRegion();
 }
 
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 36a03ec71c0c6c6..ae221bd1779eeeb 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -61,7 +61,7 @@ DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) {
   SmallVector<DINodeAttr> elements;
   for (llvm::DINode *element : node->getElements()) {
     assert(element && "expected a non-null element type");
-    elements.push_back(translate(element));
+    elements.push_back(cast<DINodeAttr>(translate(element)));
   }
   // Drop the elements parameter if a cyclic dependency is detected. We
   // currently cannot model these cycles and thus drop the parameter if
@@ -116,6 +116,27 @@ DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
                                      node->getDiscriminator());
 }
 
+DIExpressionAttr DebugImporter::translateImpl(llvm::DIExpression *node) {
+  return DIExpressionAttr::get(context, node->getElements());
+}
+
+DIGlobalVariableExpressionAttr
+DebugImporter::translateImpl(llvm::DIGlobalVariableExpression *node) {
+  return DIGlobalVariableExpressionAttr::get(context,
+                                             translate(node->getVariable()),
+                                             translate(node->getExpression()));
+}
+
+DIGlobalVariableAttr
+DebugImporter::translateImpl(llvm::DIGlobalVariable *node) {
+  return DIGlobalVariableAttr::get(
+      context, translate(node->getScope()),
+      StringAttr::get(context, node->getName()),
+      StringAttr::get(context, node->getLinkageName()),
+      translate(node->getFile()), node->getLine(), translate(node->getType()),
+      node->isLocalToUnit(), node->isDefinition(), node->getAlignInBits());
+}
+
 DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
   return DILocalVariableAttr::get(context, translate(node->getScope()),
                                   getStringAttrOrNull(node->getRawName()),
@@ -204,12 +225,12 @@ DITypeAttr DebugImporter::translateImpl(llvm::DIType *node) {
   return cast<DITypeAttr>(translate(static_cast<llvm::DINode *>(node)));
 }
 
-DINodeAttr DebugImporter::translate(llvm::DINode *node) {
+MDNodeAttr DebugImporter::translate(llvm::MDNode *node) {
   if (!node)
     return nullptr;
 
   // Check for a cached instance.
-  if (DINodeAttr attr = nodeToAttr.lookup(node))
+  if (MDNodeAttr attr = nodeToAttr.lookup(node))
     return attr;
 
   // Return nullptr if a cyclic dependency is detected since the same node is
@@ -220,7 +241,7 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
   auto guard = llvm::make_scope_exit([&]() { translationStack.pop_back(); });
 
   // Convert the debug metadata if possible.
-  auto translateNode = [this](llvm::DINode *node) -> DINodeAttr {
+  auto translateNode = [this](llvm::MDNode *node) -> MDNodeAttr {
     if (auto *casted = dyn_cast<llvm::DIBasicType>(node))
       return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DICompileUnit>(node))
@@ -231,6 +252,12 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
       return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DIFile>(node))
       return translateImpl(casted);
+    if (auto *casted = dyn_cast<llvm::DIExpression>(node))
+      return translateImpl(casted);
+    if (auto *casted = dyn_cast<llvm::DIGlobalVariableExpression>(node))
+      return translateImpl(casted);
+    if (auto *casted = dyn_cast<llvm::DIGlobalVariable>(node))
+      return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DILabel>(node))
       return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
@@ -251,7 +278,7 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
       return translateImpl(casted);
     return nullptr;
   };
-  if (DINodeAttr attr = translateNode(node)) {
+  if (MDNodeAttr attr = translateNode(node)) {
     nodeToAttr.insert({node, attr});
     return attr;
   }
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.h b/mlir/lib/Target/LLVMIR/DebugImporter.h
index 5c07ec82d0191bc..6e92a8823889387 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.h
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.h
@@ -40,15 +40,18 @@ class DebugImporter {
   Location translateFuncLocation(llvm::Function *func);
 
   /// Translates the given LLVM debug metadata to MLIR.
-  DINodeAttr translate(llvm::DINode *node);
+  MDNodeAttr translate(llvm::MDNode *node);
+  MDNodeAttr translate(llvm::DINode *node) {
+    return translate(cast<llvm::MDNode>(node));
+  }
 
   /// Infers the metadata type and translates it to MLIR.
-  template <typename DINodeT>
-  auto translate(DINodeT *node) {
+  template <typename MDNodeT>
+  auto translate(MDNodeT *node) {
     // Infer the MLIR type from the LLVM metadata type.
     using MLIRTypeT = decltype(translateImpl(node));
     return cast_or_null<MLIRTypeT>(
-        translate(static_cast<llvm::DINode *>(node)));
+        translate(static_cast<llvm::MDNode *>(node)));
   }
 
 private:
@@ -61,6 +64,9 @@ class DebugImporter {
   DILabelAttr translateImpl(llvm::DILabel *node);
   DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
   DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
+  DIExpressionAttr translateImpl(llvm::DIExpression *node);
+  DIGlobalVariableExpressionAttr translateImpl(llvm::DIGlobalVariableExpression *node);
+  DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node);
   DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);
   DIModuleAttr translateImpl(llvm::DIModule *node);
   DINamespaceAttr translateImpl(llvm::DINamespace *node);
@@ -75,11 +81,11 @@ class DebugImporter {
   StringAttr getStringAttrOrNull(llvm::MDString *stringNode);
 
   /// A mapping between LLVM debug metadata and the corresponding attribute.
-  DenseMap<llvm::DINode *, DINodeAttr> nodeToAttr;
+  DenseMap<llvm::MDNode *, MDNodeAttr> nodeToAttr;
 
   /// A stack that stores the metadata nodes that are being traversed. The stack
   /// is used to detect cyclic dependencies during the metadata translation.
-  SetVector<llvm::DINode *> translationStack;
+  SetVector<llvm::MDNode *> translationStack;
 
   MLIRContext *context;
   ModuleOp mlirModule;
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index a15ffb40065a08b..49f69c2376220a9 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -189,6 +189,25 @@ DebugTranslation::translateImpl(DILocalVariableAttr attr) {
       /*Annotations=*/nullptr);
 }
 
+llvm::DIExpression *DebugTranslation::translateImpl(DIExpressionAttr attr) {
+  return llvm::DIExpression::get(llvmCtx, attr.getOperations());
+}
+
+llvm::DIGlobalVariableExpression *
+DebugTranslation::translateImpl(DIGlobalVariableExpressionAttr attr) {
+  return llvm::DIGlobalVariableExpression::get(
+      llvmCtx, translate(attr.getVar()), translate(attr.getExpr()));
+}
+
+llvm::DIGlobalVariable *
+DebugTranslation::translateImpl(DIGlobalVariableAttr attr) {
+  return llvm::DIGlobalVariable::getDistinct(
+      llvmCtx, translate(attr.getScope()), getMDStringOrNull(attr.getName()),
+      getMDStringOrNull(attr.getLinkageName()), translate(attr.getFile()),
+      attr.getLine(), translate(attr.getType()), attr.getIsLocalToUnit(),
+      attr.getIsDefined(), nullptr, nullptr, attr.getAlignInBits(), nullptr);
+}
+
 llvm::DIScope *DebugTranslation::translateImpl(DIScopeAttr attr) {
   return cast<llvm::DIScope>(translate(DINodeAttr(attr)));
 }
@@ -250,20 +269,22 @@ llvm::DIType *DebugTranslation::translateImpl(DITypeAttr attr) {
   return cast<llvm::DIType>(translate(DINodeAttr(attr)));
 }
 
-llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
+llvm::MDNode *DebugTranslation::translate(MDNodeAttr attr) {
   if (!attr)
     return nullptr;
   // Check for a cached instance.
-  if (llvm::DINode *node = attrToNode.lookup(attr))
+  if (llvm::MDNode *node = attrToNode.lookup(attr))
     return node;
 
-  llvm::DINode *node =
-      TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
+  llvm::MDNode *node =
+      TypeSwitch<MDNodeAttr, llvm::MDNode *>(attr)
           .Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
-                DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
-                DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
-                DINamespaceAttr, DINullTypeAttr, DISubprogramAttr,
-                DISubrangeAttr, DISubroutineTypeAttr>(
+                DIDerivedTypeAttr, DIExpressionAttr, DIFileAttr,
+                DIGlobalVariableAttr, DIGlobalVariableExpressionAttr,
+                DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
+                DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
+                DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
+                DISubroutineTypeAttr>(
               [&](auto attr) { return translateImpl(attr); });
   attrToNode.insert({attr, node});
   return node;
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h
index d22c3d80dafd5f9..a9b5adf9bdf2c59 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.h
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h
@@ -41,14 +41,17 @@ class DebugTranslation {
   void translate(LLVMFuncOp func, llvm::Function &llvmFunc);
 
   /// Translate the given LLVM debug metadata to LLVM.
-  llvm::DINode *translate(DINodeAttr attr);
+  llvm::MDNode *translate(MDNodeAttr attr);
+  llvm::MDNode *translate(DINodeAttr attr) {
+    return translate(cast<MDNodeAttr>(attr));
+  }
 
   /// Translate the given derived LLVM debug metadata to LLVM.
   template <typename DIAttrT>
   auto translate(DIAttrT attr) {
     // Infer the LLVM type from the attribute type.
     using LLVMTypeT = std::remove_pointer_t<decltype(translateImpl(attr))>;
-    return cast_or_null<LLVMTypeT>(translate(DINodeAttr(attr)));
+    return cast_or_null<LLVMTypeT>(translate(MDNodeAttr(attr)));
   }
 
 private:
@@ -72,6 +75,10 @@ class DebugTranslation {
   llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr);
   llvm::DILocalScope *translateImpl(DILocalScopeAttr attr);
   llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr);
+  llvm::DIExpression *translateImpl(DIExpressionAttr attr);
+  llvm::DIGlobalVariableExpression *
+  translateImpl(DIGlobalVariableExpressionAttr attr);
+  llvm::DIGlobalVariable *translateImpl(DIGlobalVariableAttr attr);
   llvm::DIModule *translateImpl(DIModuleAttr attr);
   llvm::DINamespace *translateImpl(DINamespaceAttr attr);
   llvm::DIScope *translateImpl(DIScopeAttr attr);
@@ -92,7 +99,7 @@ class DebugTranslation {
 
   /// A mapping between debug attribute and the corresponding llvm debug
   /// metadata.
-  DenseMap<Attribute, llvm::DINode *> attrToNode;
+  DenseMap<Attribute, llvm::MDNode *> attrToNode;
 
   /// A map...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Nov 24, 2023

@llvm/pr-subscribers-mlir

Author: Justin Wilson (waj334)

Changes

This PR introduces DIGlobalVariableAttr, DIGlobalVariableExpressionAttr and DIExpressionAttr so that ModuleTranslation can emit the required metadata needed for debug information about global variable. The translator implementation for debug metadata needed to be refactored in order to allow translation of nodes based on MDNode (DIGlobalVariableExpressionAttr and DIExpression) in addition to DINode-based nodes.

A DIGlobalVariableExpressionAttr can now be passed to the GlobalOp operation directly and ModuleTranslation will create the respective DIGlobalVariable and DIGlobalVariableExpression nodes. The compile unit that DIGlobalVariable is expected to be configured with will be updated with the created DIGlobalVariableExpression.


Patch is 21.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73367.diff

12 Files Affected:

  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+45)
  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h (+11-2)
  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+3-1)
  • (modified) mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h (+1)
  • (modified) mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp (+9-1)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp (+16-2)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+5-1)
  • (modified) mlir/lib/Target/LLVMIR/DebugImporter.cpp (+32-5)
  • (modified) mlir/lib/Target/LLVMIR/DebugImporter.h (+12-6)
  • (modified) mlir/lib/Target/LLVMIR/DebugTranslation.cpp (+29-8)
  • (modified) mlir/lib/Target/LLVMIR/DebugTranslation.h (+10-3)
  • (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+15)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 9e35bf1ba977725..09f2f7c8048349f 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -11,6 +11,7 @@
 
 include "mlir/Dialect/LLVMIR/LLVMDialect.td"
 include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/CommonAttrConstraints.td"
 
 // All of the attributes will extend this class.
 class LLVM_Attr<string name, string attrMnemonic,
@@ -447,6 +448,50 @@ def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable",
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// DIExpressionAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression",
+                                          /*traits=*/[], "MDNodeAttr"> {
+  let parameters = (ins
+    ArrayRefParameter<"uint64_t">:$operations
+  );
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
+//===----------------------------------------------------------------------===//
+// DIGlobalVariableExpressionAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIGlobalVariableExpressionAttr : LLVM_Attr<"DIGlobalVariableExpression", "di_global_variable_expression",
+                                          /*traits=*/[], "MDNodeAttr"> {
+  let parameters = (ins
+    "DIGlobalVariableAttr":$var,
+    OptionalParameter<"DIExpressionAttr">:$expr
+  );
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
+//===----------------------------------------------------------------------===//
+// DIGlobalVariableAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DIGlobalVariable : LLVM_Attr<"DIGlobalVariable", "di_global_variable",
+                                      /*traits=*/[], "DINodeAttr"> {
+  let parameters = (ins
+    "DIScopeAttr":$scope,
+    OptionalParameter<"StringAttr">:$name,
+    OptionalParameter<"StringAttr">:$linkageName,
+    OptionalParameter<"DIFileAttr">:$file,
+    OptionalParameter<"unsigned">:$line,
+    OptionalParameter<"DITypeAttr">:$type,
+    OptionalParameter<"bool">:$isLocalToUnit,
+    OptionalParameter<"bool">:$isDefined,
+    OptionalParameter<"unsigned">:$alignInBits);
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // DISubprogramAttr
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
index c370bfa2b733d65..e49b40e2d487dc8 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
@@ -23,8 +23,8 @@
 namespace mlir {
 namespace LLVM {
 
-/// This class represents the base attribute for all debug info attributes.
-class DINodeAttr : public Attribute {
+/// This class represents the base attribute for all metadata attributes.
+class MDNodeAttr : public Attribute {
 public:
   using Attribute::Attribute;
 
@@ -32,6 +32,15 @@ class DINodeAttr : public Attribute {
   static bool classof(Attribute attr);
 };
 
+/// This class represents the base attribute for all debug info attributes.
+class DINodeAttr : public MDNodeAttr {
+public:
+  using MDNodeAttr::MDNodeAttr;
+
+  // Support LLVM type casting.
+  static bool classof(Attribute attr);
+};
+
 /// This class represents a LLVM attribute that describes a debug info scope.
 class DIScopeAttr : public DINodeAttr {
 public:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 88f4f81735372b9..ecfdced641299fe 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1087,6 +1087,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
     OptionalAttr<UnnamedAddr>:$unnamed_addr,
     OptionalAttr<StrAttr>:$section,
     OptionalAttr<SymbolRefAttr>:$comdat,
+    OptionalAttr<LLVM_DIGlobalVariableExpressionAttr>:$dbg_expr,
     DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
   );
   let summary = "LLVM dialect global.";
@@ -1196,7 +1197,8 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
       CArg<"bool", "false">:$dsoLocal,
       CArg<"bool", "false">:$thread_local_,
       CArg<"SymbolRefAttr", "{}">:$comdat,
-      CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
+      CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
+      CArg<"DIGlobalVariableExpressionAttr", "{}">:$dbgExpr)>
   ];
 
   let extraClassDeclaration = [{
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 4820e826d0ca357..a94596cc9583b1f 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -46,6 +46,7 @@ class LoopAnnotationTranslation;
 
 class AliasScopeAttr;
 class AliasScopeDomainAttr;
+class MDNodeAttr;
 class DINodeAttr;
 class LLVMFuncOp;
 class ComdatSelectorOp;
diff --git a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
index 3a01795ce3f53e5..a306007953d5b7b 100644
--- a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
+++ b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
@@ -86,7 +86,15 @@ LLVMTypeConverter::LLVMTypeConverter(MLIRContext *ctx,
 
     if (type.isIdentified()) {
       auto convertedType = LLVM::LLVMStructType::getIdentified(
-          type.getContext(), ("_Converted." + type.getName()).str());
+          type.getContext(), ("_Converted_" + type.getName()).str());
+      unsigned counter = 1;
+      while (convertedType.isInitialized()) {
+        assert(counter != UINT_MAX &&
+               "about to overflow struct renaming counter in conversion");
+        convertedType = LLVM::LLVMStructType::getIdentified(
+            type.getContext(),
+            ("_Converted_" + std::to_string(counter) + type.getName()).str());
+      }
 
       SmallVectorImpl<Type> &recursiveStack = getCurrentThreadRecursiveStack();
       if (llvm::count(recursiveStack, type)) {
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 3d45ab8fac4d705..1f5ed86f8d875e9 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -37,14 +37,28 @@ void LLVMDialect::registerAttributes() {
       >();
 }
 
+//===----------------------------------------------------------------------===//
+// MDNodeAttr
+//===----------------------------------------------------------------------===//
+
+bool MDNodeAttr::classof(Attribute attr) {
+  return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
+                   DIDerivedTypeAttr, DIExpressionAttr, DIFileAttr,
+                   DIGlobalVariableAttr, DIGlobalVariableExpressionAttr,
+                   DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
+                   DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
+                   DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
+                   DISubroutineTypeAttr>(attr);
+}
+
 //===----------------------------------------------------------------------===//
 // DINodeAttr
 //===----------------------------------------------------------------------===//
 
 bool DINodeAttr::classof(Attribute attr) {
   return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
-                   DIDerivedTypeAttr, DIFileAttr, DILabelAttr,
-                   DILexicalBlockAttr, DILexicalBlockFileAttr,
+                   DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
+                   DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
                    DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
                    DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
                    DISubroutineTypeAttr>(attr);
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f6c8f388732c3da..53c0c9b70a8824a 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1781,7 +1781,7 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
                      bool isConstant, Linkage linkage, StringRef name,
                      Attribute value, uint64_t alignment, unsigned addrSpace,
                      bool dsoLocal, bool threadLocal, SymbolRefAttr comdat,
-                     ArrayRef<NamedAttribute> attrs) {
+                     ArrayRef<NamedAttribute> attrs, DIGlobalVariableExpressionAttr dbgExpr) {
   result.addAttribute(getSymNameAttrName(result.name),
                       builder.getStringAttr(name));
   result.addAttribute(getGlobalTypeAttrName(result.name), TypeAttr::get(type));
@@ -1812,6 +1812,10 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
     result.addAttribute(getAddrSpaceAttrName(result.name),
                         builder.getI32IntegerAttr(addrSpace));
   result.attributes.append(attrs.begin(), attrs.end());
+
+  if (dbgExpr)
+    result.addAttribute(getDbgExprAttrName(result.name), dbgExpr);
+
   result.addRegion();
 }
 
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 36a03ec71c0c6c6..ae221bd1779eeeb 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -61,7 +61,7 @@ DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) {
   SmallVector<DINodeAttr> elements;
   for (llvm::DINode *element : node->getElements()) {
     assert(element && "expected a non-null element type");
-    elements.push_back(translate(element));
+    elements.push_back(cast<DINodeAttr>(translate(element)));
   }
   // Drop the elements parameter if a cyclic dependency is detected. We
   // currently cannot model these cycles and thus drop the parameter if
@@ -116,6 +116,27 @@ DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
                                      node->getDiscriminator());
 }
 
+DIExpressionAttr DebugImporter::translateImpl(llvm::DIExpression *node) {
+  return DIExpressionAttr::get(context, node->getElements());
+}
+
+DIGlobalVariableExpressionAttr
+DebugImporter::translateImpl(llvm::DIGlobalVariableExpression *node) {
+  return DIGlobalVariableExpressionAttr::get(context,
+                                             translate(node->getVariable()),
+                                             translate(node->getExpression()));
+}
+
+DIGlobalVariableAttr
+DebugImporter::translateImpl(llvm::DIGlobalVariable *node) {
+  return DIGlobalVariableAttr::get(
+      context, translate(node->getScope()),
+      StringAttr::get(context, node->getName()),
+      StringAttr::get(context, node->getLinkageName()),
+      translate(node->getFile()), node->getLine(), translate(node->getType()),
+      node->isLocalToUnit(), node->isDefinition(), node->getAlignInBits());
+}
+
 DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
   return DILocalVariableAttr::get(context, translate(node->getScope()),
                                   getStringAttrOrNull(node->getRawName()),
@@ -204,12 +225,12 @@ DITypeAttr DebugImporter::translateImpl(llvm::DIType *node) {
   return cast<DITypeAttr>(translate(static_cast<llvm::DINode *>(node)));
 }
 
-DINodeAttr DebugImporter::translate(llvm::DINode *node) {
+MDNodeAttr DebugImporter::translate(llvm::MDNode *node) {
   if (!node)
     return nullptr;
 
   // Check for a cached instance.
-  if (DINodeAttr attr = nodeToAttr.lookup(node))
+  if (MDNodeAttr attr = nodeToAttr.lookup(node))
     return attr;
 
   // Return nullptr if a cyclic dependency is detected since the same node is
@@ -220,7 +241,7 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
   auto guard = llvm::make_scope_exit([&]() { translationStack.pop_back(); });
 
   // Convert the debug metadata if possible.
-  auto translateNode = [this](llvm::DINode *node) -> DINodeAttr {
+  auto translateNode = [this](llvm::MDNode *node) -> MDNodeAttr {
     if (auto *casted = dyn_cast<llvm::DIBasicType>(node))
       return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DICompileUnit>(node))
@@ -231,6 +252,12 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
       return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DIFile>(node))
       return translateImpl(casted);
+    if (auto *casted = dyn_cast<llvm::DIExpression>(node))
+      return translateImpl(casted);
+    if (auto *casted = dyn_cast<llvm::DIGlobalVariableExpression>(node))
+      return translateImpl(casted);
+    if (auto *casted = dyn_cast<llvm::DIGlobalVariable>(node))
+      return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DILabel>(node))
       return translateImpl(casted);
     if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
@@ -251,7 +278,7 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
       return translateImpl(casted);
     return nullptr;
   };
-  if (DINodeAttr attr = translateNode(node)) {
+  if (MDNodeAttr attr = translateNode(node)) {
     nodeToAttr.insert({node, attr});
     return attr;
   }
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.h b/mlir/lib/Target/LLVMIR/DebugImporter.h
index 5c07ec82d0191bc..6e92a8823889387 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.h
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.h
@@ -40,15 +40,18 @@ class DebugImporter {
   Location translateFuncLocation(llvm::Function *func);
 
   /// Translates the given LLVM debug metadata to MLIR.
-  DINodeAttr translate(llvm::DINode *node);
+  MDNodeAttr translate(llvm::MDNode *node);
+  MDNodeAttr translate(llvm::DINode *node) {
+    return translate(cast<llvm::MDNode>(node));
+  }
 
   /// Infers the metadata type and translates it to MLIR.
-  template <typename DINodeT>
-  auto translate(DINodeT *node) {
+  template <typename MDNodeT>
+  auto translate(MDNodeT *node) {
     // Infer the MLIR type from the LLVM metadata type.
     using MLIRTypeT = decltype(translateImpl(node));
     return cast_or_null<MLIRTypeT>(
-        translate(static_cast<llvm::DINode *>(node)));
+        translate(static_cast<llvm::MDNode *>(node)));
   }
 
 private:
@@ -61,6 +64,9 @@ class DebugImporter {
   DILabelAttr translateImpl(llvm::DILabel *node);
   DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
   DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
+  DIExpressionAttr translateImpl(llvm::DIExpression *node);
+  DIGlobalVariableExpressionAttr translateImpl(llvm::DIGlobalVariableExpression *node);
+  DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node);
   DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);
   DIModuleAttr translateImpl(llvm::DIModule *node);
   DINamespaceAttr translateImpl(llvm::DINamespace *node);
@@ -75,11 +81,11 @@ class DebugImporter {
   StringAttr getStringAttrOrNull(llvm::MDString *stringNode);
 
   /// A mapping between LLVM debug metadata and the corresponding attribute.
-  DenseMap<llvm::DINode *, DINodeAttr> nodeToAttr;
+  DenseMap<llvm::MDNode *, MDNodeAttr> nodeToAttr;
 
   /// A stack that stores the metadata nodes that are being traversed. The stack
   /// is used to detect cyclic dependencies during the metadata translation.
-  SetVector<llvm::DINode *> translationStack;
+  SetVector<llvm::MDNode *> translationStack;
 
   MLIRContext *context;
   ModuleOp mlirModule;
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index a15ffb40065a08b..49f69c2376220a9 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -189,6 +189,25 @@ DebugTranslation::translateImpl(DILocalVariableAttr attr) {
       /*Annotations=*/nullptr);
 }
 
+llvm::DIExpression *DebugTranslation::translateImpl(DIExpressionAttr attr) {
+  return llvm::DIExpression::get(llvmCtx, attr.getOperations());
+}
+
+llvm::DIGlobalVariableExpression *
+DebugTranslation::translateImpl(DIGlobalVariableExpressionAttr attr) {
+  return llvm::DIGlobalVariableExpression::get(
+      llvmCtx, translate(attr.getVar()), translate(attr.getExpr()));
+}
+
+llvm::DIGlobalVariable *
+DebugTranslation::translateImpl(DIGlobalVariableAttr attr) {
+  return llvm::DIGlobalVariable::getDistinct(
+      llvmCtx, translate(attr.getScope()), getMDStringOrNull(attr.getName()),
+      getMDStringOrNull(attr.getLinkageName()), translate(attr.getFile()),
+      attr.getLine(), translate(attr.getType()), attr.getIsLocalToUnit(),
+      attr.getIsDefined(), nullptr, nullptr, attr.getAlignInBits(), nullptr);
+}
+
 llvm::DIScope *DebugTranslation::translateImpl(DIScopeAttr attr) {
   return cast<llvm::DIScope>(translate(DINodeAttr(attr)));
 }
@@ -250,20 +269,22 @@ llvm::DIType *DebugTranslation::translateImpl(DITypeAttr attr) {
   return cast<llvm::DIType>(translate(DINodeAttr(attr)));
 }
 
-llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
+llvm::MDNode *DebugTranslation::translate(MDNodeAttr attr) {
   if (!attr)
     return nullptr;
   // Check for a cached instance.
-  if (llvm::DINode *node = attrToNode.lookup(attr))
+  if (llvm::MDNode *node = attrToNode.lookup(attr))
     return node;
 
-  llvm::DINode *node =
-      TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
+  llvm::MDNode *node =
+      TypeSwitch<MDNodeAttr, llvm::MDNode *>(attr)
           .Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
-                DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
-                DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
-                DINamespaceAttr, DINullTypeAttr, DISubprogramAttr,
-                DISubrangeAttr, DISubroutineTypeAttr>(
+                DIDerivedTypeAttr, DIExpressionAttr, DIFileAttr,
+                DIGlobalVariableAttr, DIGlobalVariableExpressionAttr,
+                DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
+                DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
+                DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
+                DISubroutineTypeAttr>(
               [&](auto attr) { return translateImpl(attr); });
   attrToNode.insert({attr, node});
   return node;
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h
index d22c3d80dafd5f9..a9b5adf9bdf2c59 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.h
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h
@@ -41,14 +41,17 @@ class DebugTranslation {
   void translate(LLVMFuncOp func, llvm::Function &llvmFunc);
 
   /// Translate the given LLVM debug metadata to LLVM.
-  llvm::DINode *translate(DINodeAttr attr);
+  llvm::MDNode *translate(MDNodeAttr attr);
+  llvm::MDNode *translate(DINodeAttr attr) {
+    return translate(cast<MDNodeAttr>(attr));
+  }
 
   /// Translate the given derived LLVM debug metadata to LLVM.
   template <typename DIAttrT>
   auto translate(DIAttrT attr) {
     // Infer the LLVM type from the attribute type.
     using LLVMTypeT = std::remove_pointer_t<decltype(translateImpl(attr))>;
-    return cast_or_null<LLVMTypeT>(translate(DINodeAttr(attr)));
+    return cast_or_null<LLVMTypeT>(translate(MDNodeAttr(attr)));
   }
 
 private:
@@ -72,6 +75,10 @@ class DebugTranslation {
   llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr);
   llvm::DILocalScope *translateImpl(DILocalScopeAttr attr);
   llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr);
+  llvm::DIExpression *translateImpl(DIExpressionAttr attr);
+  llvm::DIGlobalVariableExpression *
+  translateImpl(DIGlobalVariableExpressionAttr attr);
+  llvm::DIGlobalVariable *translateImpl(DIGlobalVariableAttr attr);
   llvm::DIModule *translateImpl(DIModuleAttr attr);
   llvm::DINamespace *translateImpl(DINamespaceAttr attr);
   llvm::DIScope *translateImpl(DIScopeAttr attr);
@@ -92,7 +99,7 @@ class DebugTranslation {
 
   /// A mapping between debug attribute and the corresponding llvm debug
   /// metadata.
-  DenseMap<Attribute, llvm::DINode *> attrToNode;
+  DenseMap<Attribute, llvm::MDNode *> attrToNode;
 
   /// A map...
[truncated]

Copy link

github-actions bot commented Nov 24, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 2 times, most recently from cd225ba to 8046482 Compare November 24, 2023 22:46
@waj334 waj334 changed the title [mlir] Add support for DIGlobalVariable, DIGlobalVariableExpression and DIExpression [mlir] Add support for DIGlobalVariable and DIGlobalVariableExpression Nov 24, 2023
@waj334
Copy link
Contributor Author

waj334 commented Nov 24, 2023

@zero9178 @zyx-billy This affects the previous work on DIExpression.

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 2 times, most recently from 73d5317 to 32e813c Compare November 25, 2023 00:42
Copy link
Contributor

@zyx-billy zyx-billy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for improving DIExpressions with op names! 🙏 I'm not familiar with the global variable part so I'll leave approvals to the experienced folks. Just leaving some questions for the DIExpression part.

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 5 times, most recently from 92b04a8 to a2e6542 Compare November 25, 2023 08:59
Copy link
Contributor

@gysit gysit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on debug info!

I did a first pass focusing on some of the design choices and did not yet look into the details.

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 3 times, most recently from 0e95b65 to ddd7738 Compare November 26, 2023 17:18
Copy link
Contributor

@gysit gysit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direction looks good to me!

Can you do a formatting / cleanup pass and then re request review so that I can do an in-depth review? I think there is some rebase issue since some type converter things show up in the revision. Also note that tablegen requires hand formatting (i.e., the code should not use more than 80 columns and an indention of 2 spaces).

I would also remove the MDNode base class and introduce a translateExpr and translateGlobalExpr function. But let's see maybe other reviewers have different preferences there.

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 3 times, most recently from ec80948 to 83e52e0 Compare November 28, 2023 04:43
Copy link
Contributor

@Dinistro Dinistro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the comments. I dropped a bunch of further comments, but this is getting into a good shape 🙂

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 2 times, most recently from d1ac8a8 to a358fe9 Compare November 29, 2023 02:02
@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 4 times, most recently from 0f34d87 to ddf2d74 Compare December 1, 2023 01:10
Copy link
Contributor

@gysit gysit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for you effort! We are almost there.

I have put some mostly minor nit comments. And as @Dinistro already mentioned it would be great to have a global import test.

@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch 7 times, most recently from 27f4326 to 9c1589f Compare December 2, 2023 23:11
Copy link
Contributor

@gysit gysit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the test.

It looks like accidentally some tests got deleted though?

…nd DIExpression

Introduces DIGlobalVariableAttr, DIGlobalVariableExpressionAttr and DIExpressionAttr so that ModuleTranslation can emit the required metadata needed for debug information about global variable. The translator implementation for debug metadata needed to be refactored in order to allow translation of nodes based on MDNode (DIGlobalVariableExpressionAttr and DIExpression) in addition to DINode-based nodes.

A DIGlobalVariableExpressionAttr can now be passed to the GlobalOp operation directly and ModuleTranslation will create the respective DIGlobalVariable and DIGlobalVariableExpression nodes. The compile unit that DIGlobalVariable is expected to be configured with will be updated with the created DIGlobalVariableExpression.
@waj334 waj334 force-pushed the mlir-add-diglobalvariable-support branch from 9c1589f to a03a508 Compare December 3, 2023 23:24
@waj334
Copy link
Contributor Author

waj334 commented Dec 3, 2023

Thanks for adding the test.

It looks like accidentally some tests got deleted though?

That was definitely by accident. I've restored the tests.

Copy link
Contributor

@Dinistro Dinistro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing all the comments. LGTM!

Let us/me know when we should land this PR for you.

Copy link
Contributor

@gysit gysit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@waj334
Copy link
Contributor Author

waj334 commented Dec 4, 2023

Thanks for reviewing! I would prefer this to land ASAP since debug information for globals would be non-existent and there are some other areas that can start making use of DIExpressionAttr.

@gysit gysit merged commit 6da578c into llvm:main Dec 4, 2023
@tblah
Copy link
Contributor

tblah commented Dec 4, 2023

I think this patch broke builds with clang and -Werror

In file included from /home/tomecl01/llvm-project/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp:39:
tools/mlir/include/mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc:2738:5: error: ignoring return value of function declared with 'nodiscard' attribute [-Werror,-Wunused-result]
 2738 |     printExpressionArg(odsPrinter,
          |    ^~~~~~~~~~~~~ ~~~~~~~
 2739 |       getOpcode(),
          |       ~~~~~~~~~
 2740 |       getArguments());
          |       ~~~~~~~~~~~
1 error generated.

Please let me know if you won't have time to fix this, in which case I'll do something.

@gysit
Copy link
Contributor

gysit commented Dec 4, 2023

Please let me know if you won't have time to fix this, in which case I'll do something.

#74351 should hopefully fix the warning. The print function should not return a value.

gysit added a commit that referenced this pull request Dec 4, 2023
This commit fixes a compilation warning caused by the printExpressionArg
function that previously returned LogicalResult instead of void.

The warning has been introduced by #73367.
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.

6 participants