[Mlir-commits] [flang] [mlir] [mlir][debug] Make DICompileUnitAttr recursive. (PR #190808)
Abid Qadeer
llvmlistbot at llvm.org
Wed Apr 8 14:50:15 PDT 2026
https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/190808
>From 0eee735c6f3f82647c83bd00286c74764233f31d Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Tue, 7 Apr 2026 16:40:23 +0100
Subject: [PATCH 1/2] [mlir][debug] Make DICompileUnitAttr recursive.
This PR add DIRecursiveTypeAttrInterface to DICompileUnitAttr. It should fix the circular dependency problem we have since imports field was added.
---
mlir/include/mlir-c/Dialect/LLVM.h | 15 +++++---
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 28 ++++++++++++---
.../Dialect/LLVMIR/LLVMDialectBytecode.td | 4 ++-
mlir/lib/CAPI/Dialect/LLVM.cpp | 22 ++++++++----
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp | 23 ++++++++++++
mlir/lib/Target/LLVMIR/DebugImporter.cpp | 11 ++++--
mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 35 +++++++++++++++++++
mlir/lib/Target/LLVMIR/DebugTranslation.h | 1 +
mlir/test/CAPI/llvm.c | 6 +++-
.../compile-unit-imported-entity-cycle.ll | 30 ++++++++++++++++
10 files changed, 154 insertions(+), 21 deletions(-)
create mode 100644 mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 90ef9305145a8..5170f01a2f621 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -362,13 +362,18 @@ enum MlirLLVMDINameTableKind {
typedef enum MlirLLVMDINameTableKind MlirLLVMDINameTableKind;
+/// Creates a self-referencing LLVM DICompileUnitAttr attribute.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMDICompileUnitAttrGetRecSelf(MlirAttribute recId);
+
/// Creates a LLVM DICompileUnit attribute.
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,
- intptr_t nImportedEntities, MlirAttribute const *importedEntities);
+ MlirContext ctx, MlirAttribute recId, bool isRecSelf, MlirAttribute id,
+ unsigned int sourceLanguage, MlirAttribute file, MlirAttribute producer,
+ bool isOptimized, MlirLLVMDIEmissionKind emissionKind,
+ bool isDebugInfoForProfiling, 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 d53f522e646fb..dfedee9420465 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -417,9 +417,14 @@ def LLVM_DIBasicTypeAttr : LLVM_Attr<"DIBasicType", "di_basic_type",
//===----------------------------------------------------------------------===//
def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
- /*traits=*/[], "DIScopeAttr"> {
+ [LLVM_DIRecursiveTypeAttrInterface],
+ "DIScopeAttr"> {
let parameters = (ins
- "DistinctAttr":$id,
+ // DIRecursiveTypeAttrInterface specific parameters.
+ OptionalParameter<"DistinctAttr">:$recId,
+ OptionalParameter<"bool">:$isRecSelf,
+ // DICompileUnitAttr specific parameters.
+ OptionalParameter<"DistinctAttr">:$id,
LLVM_DILanguageParameter:$sourceLanguage,
"DIFileAttr":$file,
OptionalParameter<"StringAttr">:$producer,
@@ -440,12 +445,25 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
CArg<"StringAttr", "{}">:$splitDebugFilename,
CArg<"ArrayRef<DINodeAttr>", "{}">:$importedEntities
), [{
- return $_get(id.getContext(), id, sourceLanguage, file, producer,
- isOptimized, emissionKind, isDebugInfoForProfiling,
- nameTableKind, splitDebugFilename, importedEntities);
+ return $_get(id.getContext(), /*recId=*/nullptr, /*isRecSelf=*/false, id,
+ sourceLanguage, file, producer, isOptimized, emissionKind,
+ isDebugInfoForProfiling, nameTableKind, splitDebugFilename,
+ importedEntities);
}]>
];
let assemblyFormat = "`<` struct(params) `>`";
+ let extraClassDeclaration = [{
+ /// Requirements of DIRecursiveTypeAttrInterface.
+ /// @{
+
+ /// Get a copy of this attr but with the recursive ID set to `recId`.
+ DIRecursiveTypeAttrInterface withRecId(DistinctAttr recId);
+
+ /// Build a rec-self instance using the provided `recId`.
+ static DIRecursiveTypeAttrInterface getRecSelf(DistinctAttr recId);
+
+ /// @}
+ }];
// Generate mnemonic alias for the attribute.
let genMnemonicAlias = 1;
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index d4e1450d2f516..989db9cfcbf41 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -129,7 +129,9 @@ def DISubroutineTypeAttr : DialectAttribute<(attr
//===----------------------------------------------------------------------===//
def DICompileUnitAttr : DialectAttribute<(attr
- Attr<"DistinctAttr">:$id,
+ OptionalAttribute<"DistinctAttr">:$recId,
+ Bool:$isRecSelf,
+ OptionalAttribute<"DistinctAttr">:$id,
VarInt:$sourceLanguage,
Attr<"DIFileAttr">:$file,
OptionalAttribute<"StringAttr">:$producer,
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index dbd4b1213491b..99f2702462002 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -342,16 +342,26 @@ MlirAttribute mlirLLVMDIFileAttrGet(MlirContext ctx, MlirAttribute name,
MlirStringRef mlirLLVMDIFileAttrGetName(void) { return wrap(DIFileAttr::name); }
+MlirAttribute mlirLLVMDICompileUnitAttrGetRecSelf(MlirAttribute recId) {
+ return wrap(DICompileUnitAttr::getRecSelf(cast<DistinctAttr>(unwrap(recId))));
+}
+
MlirAttribute mlirLLVMDICompileUnitAttrGet(
- MlirContext ctx, MlirAttribute id, unsigned int sourceLanguage,
- MlirAttribute file, MlirAttribute producer, bool isOptimized,
- MlirLLVMDIEmissionKind emissionKind, bool isDebugInfoForProfiling,
- MlirLLVMDINameTableKind nameTableKind, MlirAttribute splitDebugFilename,
- intptr_t nImportedEntities, MlirAttribute const *importedEntities) {
+ MlirContext ctx, MlirAttribute recId, bool isRecSelf, MlirAttribute id,
+ unsigned int sourceLanguage, MlirAttribute file, MlirAttribute producer,
+ bool isOptimized, MlirLLVMDIEmissionKind emissionKind,
+ bool isDebugInfoForProfiling, MlirLLVMDINameTableKind nameTableKind,
+ MlirAttribute splitDebugFilename, intptr_t nImportedEntities,
+ MlirAttribute const *importedEntities) {
SmallVector<Attribute> importsStorage;
importsStorage.reserve(nImportedEntities);
+ DistinctAttr recIdAttr = mlirAttributeIsNull(recId)
+ ? DistinctAttr{}
+ : cast<DistinctAttr>(unwrap(recId));
+ DistinctAttr idAttr =
+ mlirAttributeIsNull(id) ? DistinctAttr{} : cast<DistinctAttr>(unwrap(id));
return wrap(DICompileUnitAttr::get(
- unwrap(ctx), cast<DistinctAttr>(unwrap(id)), sourceLanguage,
+ unwrap(ctx), recIdAttr, isRecSelf, idAttr, sourceLanguage,
cast<DIFileAttr>(unwrap(file)), cast<StringAttr>(unwrap(producer)),
isOptimized, DIEmissionKind(emissionKind), isDebugInfoForProfiling,
DINameTableKind(nameTableKind),
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 9f87e502a0bf1..932880548335d 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -330,6 +330,29 @@ DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
{}, {}, {});
}
+//===----------------------------------------------------------------------===//
+// DICompileUnitAttr
+//===----------------------------------------------------------------------===//
+
+DIRecursiveTypeAttrInterface DICompileUnitAttr::withRecId(DistinctAttr recId) {
+ return DICompileUnitAttr::get(
+ getContext(), recId, getIsRecSelf(), getId(), getSourceLanguage(),
+ getFile(), getProducer(), getIsOptimized(), getEmissionKind(),
+ getIsDebugInfoForProfiling(), getNameTableKind(), getSplitDebugFilename(),
+ getImportedEntities());
+}
+
+DIRecursiveTypeAttrInterface DICompileUnitAttr::getRecSelf(DistinctAttr recId) {
+ MLIRContext *ctx = recId.getContext();
+ auto emptyStr = StringAttr::get(ctx, "");
+ return DICompileUnitAttr::get(
+ ctx, recId, /*isRecSelf=*/true, /*id=*/DistinctAttr{},
+ llvm::dwarf::DW_LANG_C89, DIFileAttr::get(ctx, "<rec>", ""), emptyStr,
+ /*isOptimized=*/false, DIEmissionKind::Full,
+ /*isDebugInfoForProfiling=*/false, DINameTableKind::Default, emptyStr,
+ /*importedEntities=*/{});
+}
+
//===----------------------------------------------------------------------===//
// DISubprogramAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 1a6703fd4056a..ab37c21fdacf8 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -65,7 +65,8 @@ DICompileUnitAttr DebugImporter::translateImpl(llvm::DICompileUnit *node) {
imports.push_back(nodeAttr);
}
return DICompileUnitAttr::get(
- context, getOrCreateDistinctID(node),
+ context, /*recId=*/DistinctAttr{}, /*isRecSelf=*/false,
+ getOrCreateDistinctID(node),
node->getSourceLanguage().getUnversionedName(),
translate(node->getFile()), getStringAttrOrNull(node->getRawProducer()),
node->isOptimized(), emissionKind.value(),
@@ -434,8 +435,9 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
return nullptr;
}
-/// Get the `getRecSelf` constructor for the translated type of `node` if its
-/// translated DITypeAttr supports recursion. Otherwise, returns nullptr.
+/// Get the `getRecSelf` constructor for the translated node if it participates
+/// in CyclicReplacerCache cycle breaking (recursive composite types,
+/// subprograms, or compile units).
static function_ref<DIRecursiveTypeAttrInterface(DistinctAttr)>
getRecSelfConstructor(llvm::DINode *node) {
using CtorType = function_ref<DIRecursiveTypeAttrInterface(DistinctAttr)>;
@@ -446,6 +448,9 @@ getRecSelfConstructor(llvm::DINode *node) {
.Case([&](llvm::DISubprogram *) {
return CtorType(DISubprogramAttr::getRecSelf);
})
+ .Case([&](llvm::DICompileUnit *) {
+ return CtorType(DICompileUnitAttr::getRecSelf);
+ })
.Default(CtorType());
}
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index dce5806d48034..db9bc874314bb 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -119,7 +119,32 @@ llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
/*AlignInBits=*/0, attr.getEncoding(), llvm::DINode::FlagZero);
}
+llvm::TempDICompileUnit
+DebugTranslation::translateTemporaryImpl(DICompileUnitAttr attr) {
+ return llvm::DICompileUnit::getTemporary(
+ llvmCtx,
+ static_cast<llvm::DISourceLanguageName>(attr.getSourceLanguage()),
+ /*File=*/nullptr, "", attr.getIsOptimized(),
+ /*Flags=*/"", /*RuntimeVersion=*/0,
+ /*splitDebugFileName=*/"",
+ static_cast<llvm::DICompileUnit::DebugEmissionKind>(
+ attr.getEmissionKind()),
+ /*EnumTypes=*/nullptr, /*RetainedTypes=*/nullptr,
+ /*GlobalVariables=*/nullptr, /*ImportedEntities=*/nullptr,
+ /*Macros=*/nullptr,
+ /*DWOId=*/0, /*SplitDebugInlining=*/true,
+ attr.getIsDebugInfoForProfiling(),
+ static_cast<llvm::DICompileUnit::DebugNameTableKind>(
+ attr.getNameTableKind()),
+ /*RangesBaseAddress=*/false, /*SysRoot=*/"", /*SDK=*/"");
+}
+
llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
+ if (attr.getId())
+ if (auto iter = distinctAttrToNode.find(attr.getId());
+ iter != distinctAttrToNode.end())
+ return cast<llvm::DICompileUnit>(iter->second);
+
llvm::DIBuilder builder(llvmModule);
llvm::DICompileUnit *cu = builder.createCompileUnit(
attr.getSourceLanguage(), translate(attr.getFile()),
@@ -140,6 +165,9 @@ llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
if (!importNodes.empty())
cu->replaceImportedEntities(llvm::MDTuple::get(llvmCtx, importNodes));
+ if (attr.getId())
+ distinctAttrToNode.try_emplace(attr.getId(), cu);
+
return cu;
}
@@ -310,6 +338,13 @@ DebugTranslation::translateRecursive(DIRecursiveTypeAttrInterface attr) {
auto *concrete = translateImpl(attr);
temporary->replaceAllUsesWith(concrete);
return concrete;
+ })
+ .Case([&](DICompileUnitAttr attr) {
+ auto temporary = translateTemporaryImpl(attr);
+ setRecursivePlaceholder(temporary.get());
+ auto *concrete = translateImpl(attr);
+ temporary->replaceAllUsesWith(concrete);
+ return concrete;
});
assert(recursiveNodeMap.back().first == recursiveId &&
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h
index b690d4820d7b0..c12ddb42fe238 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.h
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h
@@ -104,6 +104,7 @@ class DebugTranslation {
/// corresponding type.
llvm::TempDICompositeType translateTemporaryImpl(DICompositeTypeAttr attr);
llvm::TempDISubprogram translateTemporaryImpl(DISubprogramAttr attr);
+ llvm::TempDICompileUnit translateTemporaryImpl(DICompileUnitAttr attr);
/// Constructs a string metadata node from the string attribute. Returns
/// nullptr if `stringAttr` is null or contains and empty string.
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index 205bdf19f733a..291c30556dc15 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -276,14 +276,18 @@ static void testDebugInfoAttributes(MlirContext ctx) {
// CHECK: #llvm.di_file<"foo" in "bar">
mlirAttributeDump(file);
+ MlirAttribute nullAttr = {0};
MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
- ctx, id, LLVMDWARFSourceLanguageC99, file, foo, false,
+ ctx, nullAttr, false, id, LLVMDWARFSourceLanguageC99, file, foo, false,
MlirLLVMDIEmissionKindFull, false, MlirLLVMDINameTableKindDefault, bar, 0,
NULL);
// CHECK: #llvm.di_compile_unit<{{.*}}>
mlirAttributeDump(compile_unit);
+ // CHECK: #llvm.di_compile_unit<{{.*}}isRecSelf = true{{.*}}>
+ mlirAttributeDump(mlirLLVMDICompileUnitAttrGetRecSelf(recId1));
+
MlirAttribute di_module = mlirLLVMDIModuleAttrGet(
ctx, file, compile_unit, foo,
mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("")), bar, foo, 1,
diff --git a/mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll b/mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll
new file mode 100644
index 0000000000000..bac508f0e01cf
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll
@@ -0,0 +1,30 @@
+; RUN: mlir-translate -import-llvm -mlir-print-debuginfo %s | FileCheck %s
+
+; CHECK-DAG: #[[CU_SELF:.+]] = #llvm.di_compile_unit<{{.*}}recId = distinct[{{[0-9]+}}]<>{{.*}}isRecSelf = true{{.*}}>
+; CHECK-DAG: #llvm.di_imported_entity<{{.*}}tag = DW_TAG_imported_declaration{{.*}}scope = #[[CU_SELF]]{{.*}}>
+; CHECK-DAG: #llvm.di_compile_unit<{{.*}}recId = distinct[{{[0-9]+}}]<>{{.*}}id = distinct[{{[0-9]+}}]<>{{.*}}importedEntities{{.*}}>
+
+source_filename = "compile-unit-imported-entity-cycle.ll"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f64:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at g = external global i32, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!17}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !12, line: 7, type: !13, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "cu.cpp", directory: "/build")
+!4 = !{}
+!5 = !{!6}
+!6 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !2, entity: !7, file: !11, line: 10)
+!7 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "S", scope: !9, file: !8, line: 5, size: 32, flags: DIFlagTypePassByValue, elements: !4)
+!8 = !DIFile(filename: "hdr.hpp", directory: "/build")
+!9 = !DINamespace(name: "ns", scope: !10)
+!10 = !DINamespace(name: "outer", scope: null)
+!11 = !DIFile(filename: "import.hpp", directory: "/build")
+!12 = !DIFile(filename: "cu.hpp", directory: "/build")
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!17 = !{i32 2, !"Debug Info Version", i32 3}
>From 660400c694a50b5e30a8409594501cc07eae9a9d Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 8 Apr 2026 22:29:03 +0100
Subject: [PATCH 2/2] Handle review comments.
Also adjusted some testcases after as many fields are now optional and printed output could be a little different.
---
.../Transforms/debug-line-table-inc-file.fir | 2 +-
flang/test/Transforms/debug-line-table.fir | 4 +--
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 8 ++---
.../Dialect/LLVMIR/LLVMDialectBytecode.td | 2 +-
mlir/lib/CAPI/Dialect/LLVM.cpp | 8 ++---
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp | 13 ++++----
mlir/test/CAPI/llvm.c | 5 ++-
.../compile-unit-imported-entity-cycle.ll | 30 -----------------
mlir/test/Target/LLVMIR/Import/debug-info.ll | 31 +++++++++++++++++-
.../Target/LLVMIR/Import/global-variables.ll | 2 +-
mlir/test/Target/LLVMIR/llvmir-debug.mlir | 32 +++++++++++++++++++
11 files changed, 81 insertions(+), 56 deletions(-)
delete mode 100644 mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll
diff --git a/flang/test/Transforms/debug-line-table-inc-file.fir b/flang/test/Transforms/debug-line-table-inc-file.fir
index d29e2fd6683b6..9e623dde153b7 100644
--- a/flang/test/Transforms/debug-line-table-inc-file.fir
+++ b/flang/test/Transforms/debug-line-table-inc-file.fir
@@ -30,7 +30,7 @@ module {
// CHECK: #[[MODULE_LOC]] = loc("{{.*}}simple.f90":0:0)
// CHECK: #[[LOC_INC_FILE:.*]] = loc("{{.*}}inc.f90":1:1)
// CHECK: #[[LOC_FILE:.*]] = loc("{{.*}}simple.f90":3:1)
-// CHECK: #[[DI_CU:.*]] = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #[[DI_FILE]], producer = "{{.*}}flang{{.*}}", isOptimized = false, emissionKind = LineTablesOnly>
+// CHECK: #[[DI_CU:.*]] = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #[[DI_FILE]], producer = "{{.*}}flang{{.*}}", emissionKind = LineTablesOnly>
// CHECK: #[[DI_SP_INC:.*]] = #llvm.di_subprogram<{{.*}}id = distinct[{{.*}}]<>, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "sinc", linkageName = "_QPsinc", file = #[[DI_INC_FILE]], {{.*}}>
// CHECK: #[[DI_SP:.*]] = #llvm.di_subprogram<{{.*}}id = distinct[{{.*}}]<>, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "_QQmain", linkageName = "_QQmain", file = #[[DI_FILE]], {{.*}}>
// CHECK: #[[FUSED_LOC_INC_FILE]] = loc(fused<#[[DI_SP_INC]]>[#[[LOC_INC_FILE]]])
diff --git a/flang/test/Transforms/debug-line-table.fir b/flang/test/Transforms/debug-line-table.fir
index 81aebf026882a..7cec163c22c5e 100644
--- a/flang/test/Transforms/debug-line-table.fir
+++ b/flang/test/Transforms/debug-line-table.fir
@@ -24,9 +24,9 @@ module {
// CHECK: #[[MODULE_LOC]] = loc("[[DIR_NAME]]/[[FILE_NAME]]":1:1)
// CHECK: #[[SB_LOC]] = loc("./simple.f90":2:1)
// CHECK: #[[DECL_LOC:.*]] = loc("./simple.f90":10:1)
-// FULL: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "{{.*}}flang{{.*}}", isOptimized = false, emissionKind = Full>
+// FULL: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "{{.*}}flang{{.*}}", emissionKind = Full>
// OPT: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "{{.*}}flang{{.*}}", isOptimized = true, emissionKind = Full>
-// LINETABLE: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "{{.*}}flang{{.*}}", isOptimized = false, emissionKind = LineTablesOnly>
+// LINETABLE: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "{{.*}}flang{{.*}}", emissionKind = LineTablesOnly>
// CHECK: #di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_basic_type, #di_basic_type>
// CHECK: #[[SB_SUBPROGRAM:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "[[SB_NAME]]", linkageName = "[[SB_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
// CHECK: #[[DECL_SUBPROGRAM:.*]] = #llvm.di_subprogram<scope = #di_file, name = "[[DECL_NAME]]", linkageName = "[[DECL_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = Optimized, type = #di_subroutine_type>
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index dfedee9420465..22face8b9d4b0 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -335,7 +335,7 @@ def LLVM_DIEncodingParameter : LLVM_DIParameter<
>;
def LLVM_DILanguageParameter : LLVM_DIParameter<
- "language", /*default=*/"", "Language", /*errorCase=*/"0"
+ "language", /*default=*/"0", "Language", /*errorCase=*/"0"
>;
def LLVM_DITagParameter : LLVM_DIParameter<
@@ -426,10 +426,10 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
// DICompileUnitAttr specific parameters.
OptionalParameter<"DistinctAttr">:$id,
LLVM_DILanguageParameter:$sourceLanguage,
- "DIFileAttr":$file,
+ OptionalParameter<"DIFileAttr">:$file,
OptionalParameter<"StringAttr">:$producer,
- "bool":$isOptimized,
- "DIEmissionKind":$emissionKind,
+ OptionalParameter<"bool">:$isOptimized,
+ OptionalParameter<"DIEmissionKind">:$emissionKind,
OptionalParameter<"bool">:$isDebugInfoForProfiling,
OptionalParameter<"DINameTableKind">:$nameTableKind,
OptionalParameter<"StringAttr">:$splitDebugFilename,
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index 989db9cfcbf41..05b88b428102c 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -133,7 +133,7 @@ def DICompileUnitAttr : DialectAttribute<(attr
Bool:$isRecSelf,
OptionalAttribute<"DistinctAttr">:$id,
VarInt:$sourceLanguage,
- Attr<"DIFileAttr">:$file,
+ OptionalAttribute<"DIFileAttr">:$file,
OptionalAttribute<"StringAttr">:$producer,
Bool:$isOptimized,
EnumClassFlag<"DIEmissionKind", "getEmissionKind()">:$_rawEmissionKind,
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 99f2702462002..f690af2cdb8a1 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -355,13 +355,9 @@ MlirAttribute mlirLLVMDICompileUnitAttrGet(
MlirAttribute const *importedEntities) {
SmallVector<Attribute> importsStorage;
importsStorage.reserve(nImportedEntities);
- DistinctAttr recIdAttr = mlirAttributeIsNull(recId)
- ? DistinctAttr{}
- : cast<DistinctAttr>(unwrap(recId));
- DistinctAttr idAttr =
- mlirAttributeIsNull(id) ? DistinctAttr{} : cast<DistinctAttr>(unwrap(id));
return wrap(DICompileUnitAttr::get(
- unwrap(ctx), recIdAttr, isRecSelf, idAttr, sourceLanguage,
+ unwrap(ctx), cast<DistinctAttr>(unwrap(recId)), isRecSelf,
+ cast<DistinctAttr>(unwrap(id)), sourceLanguage,
cast<DIFileAttr>(unwrap(file)), cast<StringAttr>(unwrap(producer)),
isOptimized, DIEmissionKind(emissionKind), isDebugInfoForProfiling,
DINameTableKind(nameTableKind),
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 932880548335d..18fb2e7aadfe2 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -343,14 +343,13 @@ DIRecursiveTypeAttrInterface DICompileUnitAttr::withRecId(DistinctAttr recId) {
}
DIRecursiveTypeAttrInterface DICompileUnitAttr::getRecSelf(DistinctAttr recId) {
- MLIRContext *ctx = recId.getContext();
- auto emptyStr = StringAttr::get(ctx, "");
+
return DICompileUnitAttr::get(
- ctx, recId, /*isRecSelf=*/true, /*id=*/DistinctAttr{},
- llvm::dwarf::DW_LANG_C89, DIFileAttr::get(ctx, "<rec>", ""), emptyStr,
- /*isOptimized=*/false, DIEmissionKind::Full,
- /*isDebugInfoForProfiling=*/false, DINameTableKind::Default, emptyStr,
- /*importedEntities=*/{});
+ recId.getContext(), recId, /*isRecSelf=*/true, /*id=*/{},
+ /*sourceLanguage=*/0u, /*file=*/{}, /*producer=*/{},
+ /*isOptimized=*/false, DIEmissionKind::None,
+ /*isDebugInfoForProfiling=*/false, DINameTableKind::Default,
+ /*splitDebugFilename=*/{}, /*importedEntities=*/{});
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index 291c30556dc15..fe48ec5568168 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -276,16 +276,15 @@ static void testDebugInfoAttributes(MlirContext ctx) {
// CHECK: #llvm.di_file<"foo" in "bar">
mlirAttributeDump(file);
- MlirAttribute nullAttr = {0};
MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
- ctx, nullAttr, false, id, LLVMDWARFSourceLanguageC99, file, foo, false,
+ ctx, recId0, false, id, LLVMDWARFSourceLanguageC99, file, foo, false,
MlirLLVMDIEmissionKindFull, false, MlirLLVMDINameTableKindDefault, bar, 0,
NULL);
// CHECK: #llvm.di_compile_unit<{{.*}}>
mlirAttributeDump(compile_unit);
- // CHECK: #llvm.di_compile_unit<{{.*}}isRecSelf = true{{.*}}>
+ // CHECK: #llvm.di_compile_unit<recId = {{.*}}, isRecSelf = true>
mlirAttributeDump(mlirLLVMDICompileUnitAttrGetRecSelf(recId1));
MlirAttribute di_module = mlirLLVMDIModuleAttrGet(
diff --git a/mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll b/mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll
deleted file mode 100644
index bac508f0e01cf..0000000000000
--- a/mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll
+++ /dev/null
@@ -1,30 +0,0 @@
-; RUN: mlir-translate -import-llvm -mlir-print-debuginfo %s | FileCheck %s
-
-; CHECK-DAG: #[[CU_SELF:.+]] = #llvm.di_compile_unit<{{.*}}recId = distinct[{{[0-9]+}}]<>{{.*}}isRecSelf = true{{.*}}>
-; CHECK-DAG: #llvm.di_imported_entity<{{.*}}tag = DW_TAG_imported_declaration{{.*}}scope = #[[CU_SELF]]{{.*}}>
-; CHECK-DAG: #llvm.di_compile_unit<{{.*}}recId = distinct[{{[0-9]+}}]<>{{.*}}id = distinct[{{[0-9]+}}]<>{{.*}}importedEntities{{.*}}>
-
-source_filename = "compile-unit-imported-entity-cycle.ll"
-target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f64:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
- at g = external global i32, !dbg !0
-
-!llvm.dbg.cu = !{!2}
-!llvm.module.flags = !{!17}
-
-!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
-!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !12, line: 7, type: !13, isLocal: false, isDefinition: true)
-!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !5, splitDebugInlining: false, nameTableKind: None)
-!3 = !DIFile(filename: "cu.cpp", directory: "/build")
-!4 = !{}
-!5 = !{!6}
-!6 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !2, entity: !7, file: !11, line: 10)
-!7 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "S", scope: !9, file: !8, line: 5, size: 32, flags: DIFlagTypePassByValue, elements: !4)
-!8 = !DIFile(filename: "hdr.hpp", directory: "/build")
-!9 = !DINamespace(name: "ns", scope: !10)
-!10 = !DINamespace(name: "outer", scope: null)
-!11 = !DIFile(filename: "import.hpp", directory: "/build")
-!12 = !DIFile(filename: "cu.hpp", directory: "/build")
-!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!17 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index d6e24d0c3dfbc..f87313367a54b 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -218,7 +218,7 @@ define void @composite_type() !dbg !3 {
; // -----
; CHECK-DAG: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
-; CHECK-DAG: #[[CU:.+]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #[[FILE]], isOptimized = false, emissionKind = None, isDebugInfoForProfiling = true, nameTableKind = None, splitDebugFilename = "test.dwo">
+; CHECK-DAG: #[[CU:.+]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #[[FILE]], isDebugInfoForProfiling = true, nameTableKind = None, splitDebugFilename = "test.dwo">
; Verify an empty subroutine types list is supported.
; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #[[CU]], scope = #[[FILE]], name = "subprogram", linkageName = "subprogram", file = #[[FILE]], line = 42, scopeLine = 42, subprogramFlags = Definition, type = #[[SP_TYPE]]>
@@ -918,3 +918,32 @@ define void @test() !dbg !3 {
; CHECK: #[[EXP1:.+]] = #llvm.di_global_variable_expression<var = #[[VAR1]], expr = <>>
; CHECK: #[[EXP2:.+]] = #llvm.di_global_variable_expression<var = #[[VAR2]], expr = <>>
; CHECK: llvm.mlir.global external @data() {{{.*}}dbg_exprs = [#[[EXP1]], #[[EXP2]]]} : i64
+
+; // -----
+
+; CU references itself through an imported entity (recId / isRecSelf cycle).
+
+; CHECK-DAG: #[[CU_SELF:.+]] = #llvm.di_compile_unit<recId = distinct[[REC_ID:.+]]<>{{.*}}isRecSelf = true{{.*}}>
+; CHECK-DAG: #llvm.di_imported_entity<{{.*}}tag = DW_TAG_imported_declaration{{.*}}scope = #[[CU_SELF]]{{.*}}>
+; CHECK-DAG: #llvm.di_compile_unit<{{.*}}recId = distinct[[REC_ID]]<>{{.*}}id = distinct[{{[0-9]+}}]<>{{.*}}importedEntities{{.*}}>
+
+ at g = external global i32, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!17}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !12, line: 7, type: !13, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "cu.cpp", directory: "/build")
+!4 = !{}
+!5 = !{!6}
+!6 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !2, entity: !7, file: !11, line: 10)
+!7 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "S", scope: !9, file: !8, line: 5, size: 32, flags: DIFlagTypePassByValue, elements: !4)
+!8 = !DIFile(filename: "hdr.hpp", directory: "/build")
+!9 = !DINamespace(name: "ns", scope: !10)
+!10 = !DINamespace(name: "outer", scope: null)
+!11 = !DIFile(filename: "import.hpp", directory: "/build")
+!12 = !DIFile(filename: "cu.hpp", directory: "/build")
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!17 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll
index 102162aaae9c2..6ecead10e6327 100644
--- a/mlir/test/Target/LLVMIR/Import/global-variables.ll
+++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll
@@ -281,7 +281,7 @@ define void @foo() {
; CHECK-DAG: #[[TYPE:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32, encoding = DW_ATE_signed>
; CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"source.c" in "/path/to/file">
-; CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_C99, file = #[[FILE]], isOptimized = false, emissionKind = None>
+; CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_C99, file = #[[FILE]]>
; CHECK-DAG: #[[SPROG:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, scope = #[[CU]], name = "foo", file = #[[FILE]], line = 5, subprogramFlags = Definition>
; CHECK-DAG: #[[GVAR0:.*]] = #llvm.di_global_variable<scope = #[[SPROG]], name = "foo", linkageName = "foo", file = #[[FILE]], line = 7, type = #[[TYPE]], isLocalToUnit = true>
; CHECK-DAG: #[[GVAR1:.*]] = #llvm.di_global_variable<scope = #[[SPROG]], name = "bar", linkageName = "bar", file = #[[FILE]], line = 8, type = #[[TYPE]], isLocalToUnit = true>
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 95895e3e56a05..9b1dad2910dba 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -770,3 +770,35 @@ llvm.func @fn_cu_imports() {
// 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]])
+
+// -----
+
+#file = #llvm.di_file<"m.cpp" in "/">
+#ns = #llvm.di_namespace<name = "n", exportSymbols = false>
+#self = #llvm.di_compile_unit<
+ recId = distinct[0]<>, isRecSelf = true, sourceLanguage = DW_LANG_C
+>
+#ie = #llvm.di_imported_entity<
+ tag = DW_TAG_imported_module, scope = #self,
+ entity = #ns, file = #file
+>
+#cu = #llvm.di_compile_unit<
+ recId = distinct[0]<>, id = distinct[2]<>,
+ sourceLanguage = DW_LANG_C, file = #file,
+ producer = "p", 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_import_cycle",
+ file = #file, line = 1, scopeLine = 1, subprogramFlags = Definition,
+ type = #sp_ty
+>
+
+// CHECK-LABEL: define void @fn_cu_import_cycle()
+llvm.func @fn_cu_import_cycle() {
+ llvm.return
+} loc(fused<#sp>["m.mlir":1:1])
+
+// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module{{.*}})
+// CHECK-DAG: !DICompileUnit({{.*}}imports:
More information about the Mlir-commits
mailing list