diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -469,6 +469,21 @@ let assemblyFormat = "`<` struct(params) `>`"; } +//===----------------------------------------------------------------------===// +// DINamespaceAttr +//===----------------------------------------------------------------------===// + +def LLVM_DINamespaceAttr : LLVM_Attr<"DINamespace", "di_namespace", + /*traits=*/[], "DIScopeAttr"> { + let parameters = (ins + "StringAttr":$name, + OptionalParameter<"DIScopeAttr">:$scope, + "bool":$exportSymbols + ); + + let assemblyFormat = "`<` struct(params) `>`"; +} + //===----------------------------------------------------------------------===// // DISubrangeAttr //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -42,10 +42,10 @@ //===----------------------------------------------------------------------===// bool DINodeAttr::classof(Attribute attr) { - return llvm::isa(attr); } @@ -63,7 +63,7 @@ //===----------------------------------------------------------------------===// bool DILocalScopeAttr::classof(Attribute attr) { - return llvm::isa(attr); + return llvm::isa(attr); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -2800,17 +2800,17 @@ AliasResult getAlias(Attribute attr, raw_ostream &os) const override { return TypeSwitch(attr) - .Case( - [&](auto attr) { - os << decltype(attr)::getMnemonic(); - return AliasResult::OverridableAlias; - }) + .Case([&](auto attr) { + os << decltype(attr)::getMnemonic(); + return AliasResult::OverridableAlias; + }) .Default([](Attribute) { return AliasResult::NoAlias; }); } }; diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.h b/mlir/lib/Target/LLVMIR/DebugImporter.h --- a/mlir/lib/Target/LLVMIR/DebugImporter.h +++ b/mlir/lib/Target/LLVMIR/DebugImporter.h @@ -62,6 +62,7 @@ DILocalVariableAttr translateImpl(llvm::DILocalVariable *node); DIScopeAttr translateImpl(llvm::DIScope *node); DISubprogramAttr translateImpl(llvm::DISubprogram *node); + DINamespaceAttr translateImpl(llvm::DINamespace *node); DISubrangeAttr translateImpl(llvm::DISubrange *node); DISubroutineTypeAttr translateImpl(llvm::DISubroutineType *node); DITypeAttr translateImpl(llvm::DIType *node); diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -113,6 +113,12 @@ return cast(translate(static_cast(node))); } +DINamespaceAttr DebugImporter::translateImpl(llvm::DINamespace *node) { + return DINamespaceAttr::get( + context, StringAttr::get(context, node->getName()), + translate(node->getScope()), node->getExportSymbols()); +} + DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) { std::optional subprogramFlags = symbolizeDISubprogramFlags(node->getSubprogram()->getSPFlags()); @@ -205,6 +211,8 @@ return translateImpl(casted); if (auto *casted = dyn_cast(node)) return translateImpl(casted); + if (auto *casted = dyn_cast(node)) + return translateImpl(casted); if (auto *casted = dyn_cast(node)) return translateImpl(casted); if (auto *casted = dyn_cast(node)) diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -73,6 +73,7 @@ llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr); llvm::DIScope *translateImpl(DIScopeAttr attr); llvm::DISubprogram *translateImpl(DISubprogramAttr attr); + llvm::DINamespace *translateImpl(DINamespaceAttr attr); llvm::DISubrange *translateImpl(DISubrangeAttr attr); llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr); llvm::DIType *translateImpl(DITypeAttr attr); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -198,6 +198,11 @@ translate(attr.getCompileUnit())); } +llvm::DINamespace *DebugTranslation::translateImpl(DINamespaceAttr attr) { + return llvm::DINamespace::get(llvmCtx, translate(attr.getScope()), + attr.getName(), attr.getExportSymbols()); +} + llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) { auto getMetadataOrNull = [&](IntegerAttr attr) -> llvm::Metadata * { if (!attr) @@ -235,10 +240,11 @@ llvm::DINode *node = TypeSwitch(attr) - .Case( + .Case( [&](auto attr) { return translateImpl(attr); }); attrToNode.insert({attr, node}); return node; diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -50,9 +50,19 @@ elements = #llvm.di_subrange > -// CHECK-DAG: #[[COMP2:.*]] = #llvm.di_composite_type +// CHECK-DAG: #[[TOPLEVEL:.*]] = #llvm.di_namespace +#toplevel_namespace = #llvm.di_namespace< + name = "toplevel", exportSymbols = true +> + +// CHECK-DAG: #[[NESTED:.*]] = #llvm.di_namespace +#nested_namespace = #llvm.di_namespace< + name = "nested", scope = #toplevel_namespace, exportSymbols = false +> + +// CHECK-DAG: #[[COMP2:.*]] = #llvm.di_composite_type #comp2 = #llvm.di_composite_type< - tag = DW_TAG_class_type, name = "class_name", file = #file, scope = #file, + tag = DW_TAG_class_type, name = "class_name", file = #file, scope = #nested_namespace, flags = "TypePassByReference|NonTrivial" > diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -367,3 +367,25 @@ !7 = !DILocalVariable(scope: !8, name: "var", file: !2, type: !5); !8 = distinct !DISubprogram(name: "dbg_use_before_def", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1) !9 = !DILocation(line: 1, column: 2, scope: !8) + +; // ----- + +; CHECK-DAG: #[[NAMESPACE:.+]] = #llvm.di_namespace +; CHECK-DAG: #[[SUBPROGRAM:.+]] = #llvm.di_subprogram #null = #llvm.di_null_type #spType0 = #llvm.di_subroutine_type +#toplevel_namespace = #llvm.di_namespace< + name = "toplevel", exportSymbols = true +> +#nested_namespace = #llvm.di_namespace< + name = "nested", scope = #toplevel_namespace, exportSymbols = false +> #sp0 = #llvm.di_subprogram< - compileUnit = #cu, scope = #file, name = "func_with_debug", linkageName = "func_with_debug", + compileUnit = #cu, scope = #nested_namespace, name = "func_with_debug", linkageName = "func_with_debug", file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType0 > #calleeType = #llvm.di_subroutine_type< @@ -113,7 +119,9 @@ // CHECK: ![[CU_LOC:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[CU_FILE_LOC:.*]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) // CHECK: ![[CU_FILE_LOC]] = !DIFile(filename: "foo.mlir", directory: "/test/") -// CHECK: ![[FUNC_LOC]] = distinct !DISubprogram(name: "func_with_debug", linkageName: "func_with_debug", scope: ![[CU_FILE_LOC]], file: ![[CU_FILE_LOC]], line: 3, type: ![[FUNC_TYPE:.*]], scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU_LOC]]) +// CHECK: ![[FUNC_LOC]] = distinct !DISubprogram(name: "func_with_debug", linkageName: "func_with_debug", scope: ![[NESTED_NAMESPACE:.*]], file: ![[CU_FILE_LOC]], line: 3, type: ![[FUNC_TYPE:.*]], scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU_LOC]]) +// CHECK: ![[NESTED_NAMESPACE]] = !DINamespace(name: "nested", scope: ![[TOPLEVEL_NAMESPACE:.*]]) +// CHECK: ![[TOPLEVEL_NAMESPACE]] = !DINamespace(name: "toplevel", scope: null, exportSymbols: true) // CHECK: ![[FUNC_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[FUNC_ARGS:.*]]) // CHECK: ![[FUNC_ARGS]] = !{null, ![[ARG_TYPE:.*]], ![[PTR_TYPE:.*]], ![[NAMED_TYPE:.*]], ![[COMPOSITE_TYPE:.*]], ![[VECTOR_TYPE:.*]]} // CHECK: ![[ARG_TYPE]] = !DIBasicType(name: "si64")