diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h index 44628787f980..90ef9305145a 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 ee82badadb64..d53f522e646f 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", "{}">:$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/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td index 5f3821f0299b..d4e1450d2f51 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/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp index 8234769ca386..dbd4b1213491 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 importsStorage; + importsStorage.reserve(nImportedEntities); return wrap(DICompileUnitAttr::get( unwrap(ctx), cast(unwrap(id)), sourceLanguage, cast(unwrap(file)), cast(unwrap(producer)), isOptimized, DIEmissionKind(emissionKind), isDebugInfoForProfiling, DINameTableKind(nameTableKind), - cast(unwrap(splitDebugFilename)))); + cast(unwrap(splitDebugFilename)), + llvm::map_to_vector( + unwrapList(nImportedEntities, importedEntities, importsStorage), + llvm::CastTo))); } MlirStringRef mlirLLVMDICompileUnitAttrGetName(void) { diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index c099865bdd16..1a6703fd4056 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>( node->getNameTableKind())); + SmallVector imports; + if (node->getImportedEntities()) { + for (llvm::DIImportedEntity *importedEntity : node->getImportedEntities()) + if (DINodeAttr nodeAttr = + translate(static_cast(importedEntity))) + imports.push_back(nodeAttr); + } 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 ab4662edf42a..dce5806d4803 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( attr.getNameTableKind())); + + llvm::SmallVector importNodes; + for (DINodeAttr importNode : attr.getImportedEntities()) + importNodes.push_back(translate(importNode)); + 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 0e9c1ce0d7cc..205bdf19f733 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/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir index 8b02d0f44ab0..e9793c15a527 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, sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true> +// CHECK-DAG: #[[NS:.*]] = #llvm.di_namespace +// CHECK-DAG: #[[IE:.*]] = #llvm.di_imported_entity +// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true, importedEntities = #[[IE]]> +#cu_import_ns = #llvm.di_namespace +#cu_import_ie = #llvm.di_imported_entity #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 diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index e4284c604131..35ab877b8258 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 +; 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 7391221fe437..0ff2bd0fc497 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 +#ie = #llvm.di_imported_entity +#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 +#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]])