[Mlir-commits] [mlir] [mlir][debug] Make DICompileUnitAttr recursive. (PR #190808)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Apr 7 08:50:12 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Abid Qadeer (abidh)
<details>
<summary>Changes</summary>
This PR add `DIRecursiveTypeAttrInterface` to `DICompileUnitAttr`. It should fix the circular dependency problem we have since `importedEntities` field was added.
---
Full diff: https://github.com/llvm/llvm-project/pull/190808.diff
10 Files Affected:
- (modified) mlir/include/mlir-c/Dialect/LLVM.h (+10-5)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+23-5)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td (+3-1)
- (modified) mlir/lib/CAPI/Dialect/LLVM.cpp (+16-6)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp (+23)
- (modified) mlir/lib/Target/LLVMIR/DebugImporter.cpp (+8-3)
- (modified) mlir/lib/Target/LLVMIR/DebugTranslation.cpp (+35)
- (modified) mlir/lib/Target/LLVMIR/DebugTranslation.h (+1)
- (modified) mlir/test/CAPI/llvm.c (+5-1)
- (added) mlir/test/Target/LLVMIR/Import/compile-unit-imported-entity-cycle.ll (+30)
``````````diff
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}
``````````
</details>
https://github.com/llvm/llvm-project/pull/190808
More information about the Mlir-commits
mailing list