[Mlir-commits] [mlir] [mlir] Add importedEntities field in DIComplileUnitAttr. (PR #188576)

Abid Qadeer llvmlistbot at llvm.org
Thu Mar 26 09:48:46 PDT 2026


https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/188576

>From dbc1ccbf7e73459611d47aa0837d1c5b172618fb Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 25 Mar 2026 19:14:38 +0000
Subject: [PATCH 1/2] [mlir] Add importedEntities field in DIComplileUnitAttr.

Mostly mechanical changes to add the missing field. It can be help when importing something at non-local level like fortran modules or C++ namespaces.
---
 mlir/include/mlir-c/Dialect/LLVM.h            |  3 +-
 .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td       |  9 ++++--
 mlir/lib/CAPI/Dialect/LLVM.cpp                | 10 +++++--
 mlir/lib/Target/LLVMIR/DebugImporter.cpp      |  9 +++++-
 mlir/lib/Target/LLVMIR/DebugTranslation.cpp   | 10 ++++++-
 mlir/test/CAPI/llvm.c                         |  3 +-
 mlir/test/Target/LLVMIR/Import/debug-info.ll  | 23 ++++++++++++++
 mlir/test/Target/LLVMIR/llvmir-debug.mlir     | 30 +++++++++++++++++++
 8 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 44628787f9805..90ef9305145a8 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -367,7 +367,8 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompileUnitAttrGet(
     MlirContext ctx, MlirAttribute id, unsigned int sourceLanguage,
     MlirAttribute file, MlirAttribute producer, bool isOptimized,
     MlirLLVMDIEmissionKind emissionKind, bool isDebugInfoForProfiling,
-    MlirLLVMDINameTableKind nameTableKind, MlirAttribute splitDebugFilename);
+    MlirLLVMDINameTableKind nameTableKind, MlirAttribute splitDebugFilename,
+    intptr_t nImportedEntities, MlirAttribute const *importedEntities);
 
 MLIR_CAPI_EXPORTED MlirStringRef mlirLLVMDICompileUnitAttrGetName(void);
 
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index ee82badadb642..d53f522e646fb 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -427,7 +427,8 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
     "DIEmissionKind":$emissionKind,
     OptionalParameter<"bool">:$isDebugInfoForProfiling,
     OptionalParameter<"DINameTableKind">:$nameTableKind,
-    OptionalParameter<"StringAttr">:$splitDebugFilename
+    OptionalParameter<"StringAttr">:$splitDebugFilename,
+    OptionalArrayRefParameter<"DINodeAttr">:$importedEntities
   );
   let builders = [
     AttrBuilderWithInferredContext<(ins
@@ -436,10 +437,12 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
       "DIEmissionKind":$emissionKind,
       CArg<"bool", "false">:$isDebugInfoForProfiling,
       CArg<"DINameTableKind", "DINameTableKind::Default">:$nameTableKind,
-      CArg<"StringAttr", "{}">:$splitDebugFilename
+      CArg<"StringAttr", "{}">:$splitDebugFilename,
+      CArg<"ArrayRef<DINodeAttr>", "{}">:$importedEntities
     ), [{
       return $_get(id.getContext(), id, sourceLanguage, file, producer,
-                   isOptimized, emissionKind, isDebugInfoForProfiling, nameTableKind, splitDebugFilename);
+                   isOptimized, emissionKind, isDebugInfoForProfiling,
+                   nameTableKind, splitDebugFilename, importedEntities);
     }]>
   ];
   let assemblyFormat = "`<` struct(params) `>`";
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 8234769ca3865..dbd4b1213491b 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -346,13 +346,19 @@ MlirAttribute mlirLLVMDICompileUnitAttrGet(
     MlirContext ctx, MlirAttribute id, unsigned int sourceLanguage,
     MlirAttribute file, MlirAttribute producer, bool isOptimized,
     MlirLLVMDIEmissionKind emissionKind, bool isDebugInfoForProfiling,
-    MlirLLVMDINameTableKind nameTableKind, MlirAttribute splitDebugFilename) {
+    MlirLLVMDINameTableKind nameTableKind, MlirAttribute splitDebugFilename,
+    intptr_t nImportedEntities, MlirAttribute const *importedEntities) {
+  SmallVector<Attribute> importsStorage;
+  importsStorage.reserve(nImportedEntities);
   return wrap(DICompileUnitAttr::get(
       unwrap(ctx), cast<DistinctAttr>(unwrap(id)), sourceLanguage,
       cast<DIFileAttr>(unwrap(file)), cast<StringAttr>(unwrap(producer)),
       isOptimized, DIEmissionKind(emissionKind), isDebugInfoForProfiling,
       DINameTableKind(nameTableKind),
-      cast<StringAttr>(unwrap(splitDebugFilename))));
+      cast<StringAttr>(unwrap(splitDebugFilename)),
+      llvm::map_to_vector(
+          unwrapList(nImportedEntities, importedEntities, importsStorage),
+          llvm::CastTo<DINodeAttr>)));
 }
 
 MlirStringRef mlirLLVMDICompileUnitAttrGetName(void) {
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index c099865bdd16e..41be8c641d09f 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -57,13 +57,20 @@ DICompileUnitAttr DebugImporter::translateImpl(llvm::DICompileUnit *node) {
       static_cast<
           std::underlying_type_t<llvm::DICompileUnit::DebugNameTableKind>>(
           node->getNameTableKind()));
+  SmallVector<DINodeAttr> imports;
+  if (node->getImportedEntities()) {
+    for (llvm::DIImportedEntity *ie : node->getImportedEntities()) {
+      if (DINodeAttr na = translate(static_cast<llvm::DINode *>(ie)))
+        imports.push_back(na);
+    }
+  }
   return DICompileUnitAttr::get(
       context, getOrCreateDistinctID(node),
       node->getSourceLanguage().getUnversionedName(),
       translate(node->getFile()), getStringAttrOrNull(node->getRawProducer()),
       node->isOptimized(), emissionKind.value(),
       node->isDebugInfoForProfiling(), nameTableKind.value(),
-      getStringAttrOrNull(node->getRawSplitDebugFilename()));
+      getStringAttrOrNull(node->getRawSplitDebugFilename()), imports);
 }
 
 DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) {
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index ab4662edf42ab..7f26b3588c624 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -121,7 +121,7 @@ llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
 
 llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
   llvm::DIBuilder builder(llvmModule);
-  return builder.createCompileUnit(
+  llvm::DICompileUnit *cu = builder.createCompileUnit(
       attr.getSourceLanguage(), translate(attr.getFile()),
       attr.getProducer() ? attr.getProducer().getValue() : "",
       attr.getIsOptimized(),
@@ -133,6 +133,14 @@ llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
       0, true, attr.getIsDebugInfoForProfiling(),
       static_cast<llvm::DICompileUnit::DebugNameTableKind>(
           attr.getNameTableKind()));
+
+  llvm::SmallVector<llvm::Metadata *> importNodes;
+  for (DINodeAttr n : attr.getImportedEntities())
+    importNodes.push_back(translate(n));
+  if (!importNodes.empty())
+    cu->replaceImportedEntities(llvm::MDTuple::get(llvmCtx, importNodes));
+
+  return cu;
 }
 
 /// Returns a new `DINodeT` that is either distinct or not, depending on
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index 0e9c1ce0d7ccd..205bdf19f733a 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -278,7 +278,8 @@ static void testDebugInfoAttributes(MlirContext ctx) {
 
   MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
       ctx, id, LLVMDWARFSourceLanguageC99, file, foo, false,
-      MlirLLVMDIEmissionKindFull, false, MlirLLVMDINameTableKindDefault, bar);
+      MlirLLVMDIEmissionKindFull, false, MlirLLVMDINameTableKindDefault, bar, 0,
+      NULL);
 
   // CHECK: #llvm.di_compile_unit<{{.*}}>
   mlirAttributeDump(compile_unit);
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index e4284c6041312..35ab877b8258c 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -823,6 +823,29 @@ define void @imp_fn() !dbg !12 {
 
 ; // -----
 
+; CHECK-DAG: #[[M:.+]] = #llvm.di_module<{{.*}}name = "mod1"{{.*}}>
+; CHECK-DAG: #[[IE:.+]] = #llvm.di_imported_entity<tag = DW_TAG_imported_module{{.*}}entity = #[[M]]{{.*}}>
+; CHECK-DAG: #llvm.di_compile_unit<{{.*}}importedEntities = #[[IE]]>
+
+define void @compile_unit_imports() !dbg !4 {
+  ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, imports: !5)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = !DISubroutineType(types: !8)
+!4 = distinct !DISubprogram(name: "compile_unit_imports", linkageName: "compile_unit_imports", scope: !2, file: !2, line: 1, type: !3, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !1)
+!5 = !{!6}
+!6 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !7)
+!7 = !DIModule(scope: !2, name: "mod1", line: 5)
+!8 = !{}
+
+; // -----
+
 ; Test that annotations are handled correctly
 
 ; CHECK-LABEL: @fn_with_annotations
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 7391221fe4370..0ff2bd0fc4970 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -740,3 +740,33 @@ llvm.mlir.global @data() {dbg_exprs = [#var_expression, #var_expression1]} : i64
 // CHECK: ![[VAR1]] = {{.*}}!DIGlobalVariable(name: "a"{{.*}})
 // CHECK: ![[EXP2]] = !DIGlobalVariableExpression(var: ![[VAR2:[0-9]+]], expr: !DIExpression())
 // CHECK: ![[VAR2]] = {{.*}}!DIGlobalVariable(name: "b"{{.*}})
+
+// -----
+
+// Test lowering compile unit `importedEntities` to LLVM IR `imports`.
+
+#file = #llvm.di_file<"test.mlir" in "">
+#ns = #llvm.di_namespace<name = "imported_ns", exportSymbols = false>
+#ie = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #file, entity = #ns, file = #file>
+#cu = #llvm.di_compile_unit<
+  id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #file,
+  producer = "MLIR", isOptimized = false, emissionKind = Full,
+  importedEntities = #ie
+>
+#sp_ty = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
+#sp = #llvm.di_subprogram<
+  compileUnit = #cu, scope = #file, name = "fn_cu_imports",
+  file = #file, line = 1, scopeLine = 1, subprogramFlags = Definition,
+  type = #sp_ty
+>
+
+// CHECK-LABEL: define void @fn_cu_imports()
+llvm.func @fn_cu_imports() {
+  llvm.return
+} loc(fused<#sp>["cu_imports.mlir":1:1])
+
+// CHECK-DAG: ![[FILE:[0-9]+]] = !DIFile(filename: "test.mlir", directory: "")
+// CHECK-DAG: ![[NS:[0-9]+]] = !DINamespace(name: "imported_ns"{{.*}})
+// CHECK-DAG: ![[IE:[0-9]+]] = !DIImportedEntity(tag: DW_TAG_imported_module{{.*}}entity: ![[NS]]{{.*}})
+// CHECK-DAG: ![[IMP_LIST:[0-9]+]] = !{![[IE]]}
+// CHECK-DAG: !DICompileUnit({{.*}}imports: ![[IMP_LIST]])

>From fc7b5788eca7c91852b34c8ba27d8480a1b1e2bf Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Thu, 26 Mar 2026 14:08:41 +0000
Subject: [PATCH 2/2] Handle review comments.

1. Added field in LLVMDialectBytecode.td. Also added another missing field.

2. Updated test in debuginfo.mlir

3. Improve variable names
---
 mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td | 3 ++-
 mlir/lib/Target/LLVMIR/DebugImporter.cpp                | 8 ++++----
 mlir/lib/Target/LLVMIR/DebugTranslation.cpp             | 4 ++--
 mlir/test/Dialect/LLVMIR/debuginfo.mlir                 | 9 +++++++--
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index 5f3821f0299b6..d4e1450d2f516 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -140,7 +140,8 @@ def DICompileUnitAttr : DialectAttribute<(attr
   EnumClassFlag<"DINameTableKind", "getNameTableKind()">:$_rawNameTableKind,
   LocalVar<"DINameTableKind",
            "(DINameTableKind)_rawNameTableKind">:$nameTableKind,
-  OptionalAttribute<"StringAttr">:$splitDebugFilename
+  OptionalAttribute<"StringAttr">:$splitDebugFilename,
+  OptionalArrayRef<"DINodeAttr">:$importedEntities
 )>;
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 41be8c641d09f..1a6703fd4056a 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -59,10 +59,10 @@ DICompileUnitAttr DebugImporter::translateImpl(llvm::DICompileUnit *node) {
           node->getNameTableKind()));
   SmallVector<DINodeAttr> imports;
   if (node->getImportedEntities()) {
-    for (llvm::DIImportedEntity *ie : node->getImportedEntities()) {
-      if (DINodeAttr na = translate(static_cast<llvm::DINode *>(ie)))
-        imports.push_back(na);
-    }
+    for (llvm::DIImportedEntity *importedEntity : node->getImportedEntities())
+      if (DINodeAttr nodeAttr =
+              translate(static_cast<llvm::DINode *>(importedEntity)))
+        imports.push_back(nodeAttr);
   }
   return DICompileUnitAttr::get(
       context, getOrCreateDistinctID(node),
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 7f26b3588c624..dce5806d48034 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -135,8 +135,8 @@ llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
           attr.getNameTableKind()));
 
   llvm::SmallVector<llvm::Metadata *> importNodes;
-  for (DINodeAttr n : attr.getImportedEntities())
-    importNodes.push_back(translate(n));
+  for (DINodeAttr importNode : attr.getImportedEntities())
+    importNodes.push_back(translate(importNode));
   if (!importNodes.empty())
     cu->replaceImportedEntities(llvm::MDTuple::get(llvmCtx, importNodes));
 
diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
index 8b02d0f44ab0a..e9793c15a5272 100644
--- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir
+++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
@@ -3,10 +3,15 @@
 // CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"debuginfo.mlir" in "/test/">
 #file = #llvm.di_file<"debuginfo.mlir" in "/test/">
 
-// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true>
+// CHECK-DAG: #[[NS:.*]] = #llvm.di_namespace<name = "cu_import_ns", exportSymbols = false>
+// CHECK-DAG: #[[IE:.*]] = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #[[FILE]], entity = #[[NS]], file = #[[FILE]]>
+// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true, importedEntities = #[[IE]]>
+#cu_import_ns = #llvm.di_namespace<name = "cu_import_ns", exportSymbols = false>
+#cu_import_ie = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #file, entity = #cu_import_ns, file = #file>
 #cu = #llvm.di_compile_unit<
   id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #file,
-  producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true
+  producer = "MLIR", isOptimized = true, emissionKind = Full,
+  isDebugInfoForProfiling = true, importedEntities = #cu_import_ie
 >
 
 // CHECK-DAG: #[[NULL:.*]] = #llvm.di_null_type



More information about the Mlir-commits mailing list