[mlir] Add importedEntities field in DIComplileUnitAttr.#188576
Conversation
|
@llvm/pr-subscribers-mlir-llvm @llvm/pr-subscribers-mlir Author: Abid Qadeer (abidh) ChangesMostly mechanical changes to add the missing field. It can help when importing something at non-local level like Fortran modules or C++ namespaces. Full diff: https://github.com/llvm/llvm-project/pull/188576.diff 8 Files Affected:
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 4c359b17f7e14..993f85ace1cf2 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -344,7 +344,8 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompileUnitAttrGet(
MlirContext ctx, MlirAttribute id, unsigned int sourceLanguage,
MlirAttribute file, MlirAttribute producer, bool isOptimized,
MlirLLVMDIEmissionKind emissionKind, MlirLLVMDINameTableKind nameTableKind,
- MlirAttribute splitDebugFilename);
+ 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 36acf244865eb..e10818bad56d6 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -426,7 +426,8 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
"bool":$isOptimized,
"DIEmissionKind":$emissionKind,
OptionalParameter<"DINameTableKind">:$nameTableKind,
- OptionalParameter<"StringAttr">:$splitDebugFilename
+ OptionalParameter<"StringAttr">:$splitDebugFilename,
+ OptionalArrayRefParameter<"DINodeAttr">:$importedEntities
);
let builders = [
AttrBuilderWithInferredContext<(ins
@@ -434,10 +435,12 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
"StringAttr":$producer, "bool":$isOptimized,
"DIEmissionKind":$emissionKind,
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, nameTableKind, splitDebugFilename);
+ isOptimized, emissionKind, nameTableKind, splitDebugFilename,
+ importedEntities);
}]>
];
let assemblyFormat = "`<` struct(params) `>`";
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index ce5c111b048e4..2e031bae3aa8d 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -322,12 +322,18 @@ MlirAttribute mlirLLVMDICompileUnitAttrGet(
MlirContext ctx, MlirAttribute id, unsigned int sourceLanguage,
MlirAttribute file, MlirAttribute producer, bool isOptimized,
MlirLLVMDIEmissionKind emissionKind, MlirLLVMDINameTableKind nameTableKind,
- MlirAttribute splitDebugFilename) {
+ 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), 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 37140e3a949c7..713fefc7a1f9c 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -57,12 +57,19 @@ 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(), 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 08eee68c195db..411335ee8e873 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, false,
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 922491a1f39d6..13b560371d9c9 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -270,7 +270,7 @@ static void testDebugInfoAttributes(MlirContext ctx) {
MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
ctx, id, LLVMDWARFSourceLanguageC99, file, foo, false,
- MlirLLVMDIEmissionKindFull, MlirLLVMDINameTableKindDefault, bar);
+ MlirLLVMDIEmissionKindFull, 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 3c2691217e0bf..f365ea50a44c2 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 1aa6362fc42d3..a579a2adb5857 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]])
|
gysit
left a comment
There was a problem hiding this comment.
Thanks for extending the debug info!
I believe the bytecode tablegen needs to be updated as well?
There was a problem hiding this comment.
Can you also update the byte code tablegen mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td to reflect this change, and add a byte code roundtrip test in mlir/test/Dialect/LLVMIR/debuginfo.mlir?
There was a problem hiding this comment.
Thanks for pointing it out. Done.
There was a problem hiding this comment.
| if (node->getImportedEntities()) | |
| for (llvm::DIImportedEntity *ie : node->getImportedEntities()) | |
| if (DINodeAttr import = translate(static_cast<llvm::DINode *>(ie))) | |
| imports.push_back(import); | |
ultra nit: I think the braces are not recommended here plus I would use a slightly longer variable name.
There was a problem hiding this comment.
| for (DINodeAttr importNode : attr.getImportedEntities()) | |
| importNodes.push_back(translate(importNode)); |
ultra nit: I prefer longer variable names.
gysit
left a comment
There was a problem hiding this comment.
Thanks for addressing the comments.
LGTM
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.
1. Added field in LLVMDialectBytecode.td. Also added another missing field. 2. Updated test in debuginfo.mlir 3. Improve variable names
Mostly mechanical changes to add the missing field. It can help when importing something at non-local level like Fortran modules or C++ namespaces.
Mostly mechanical changes to add the missing field. It can help when importing something at non-local level like Fortran modules or C++ namespaces.
|
It seems that these An example input is |
|
I think |
|
@abidh What's the status of this? This is currently blocking down-stream integration for us. |
|
Hi @Dinistro |
I guess the cycle was only introduced once the DIImportedEntity are being properly imported. Before that, the cycle was broken during the import. |
Mostly mechanical changes to add the missing field. It can help when importing something at non-local level like Fortran modules or C++ namespaces.