[Mlir-commits] [mlir] b14c84c - [MLIR][LLVM] Support DWARF v6 source language names in DICompileUnitAttr (#217432)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Aug 20 17:07:12 PDT 2026
Author: Gibran Essa
Date: 2026-08-20T17:07:06-07:00
New Revision: b14c84c4322503461ac3666d2767f70fe77a6db1
URL: https://github.com/llvm/llvm-project/commit/b14c84c4322503461ac3666d2767f70fe77a6db1
DIFF: https://github.com/llvm/llvm-project/commit/b14c84c4322503461ac3666d2767f70fe77a6db1.diff
LOG: [MLIR][LLVM] Support DWARF v6 source language names in DICompileUnitAttr (#217432)
Adds support to the LLVM dialect `DICompileUnitAttr` for DWARF v6 source
language name and version .
`DICompileUnitAttr`'s `sourceLanugage` field now points to a
`DISourceLanguageNameAttr`, which contains all source language
information, including dialect, name, and version. This is done to map
as closely as possible to `llvm::DISourceLanguageName`.
`DISourceLanguageNameAttr` has parameters for:
- An DW_LANG_* language.
- A DWARF v6 DW_LNAME_* name, which can only be set if the language is
not.
- An optional language-dependent version.
- An optional target-specific language dialect.
Parsers and printers are added so if only a language is passed, it is
parsed and printed in as before this change.
Assistance from codex was used in this PR.
Added:
mlir/test/Dialect/LLVMIR/di-compile-unit-source-language.mlir
mlir/test/Dialect/LLVMIR/invalid-di-compile-unit-source-language.mlir
Modified:
mlir/include/mlir-c/Dialect/LLVM.h
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
mlir/lib/CAPI/Dialect/LLVM.cpp
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
mlir/lib/Target/LLVMIR/DebugImporter.cpp
mlir/lib/Target/LLVMIR/DebugTranslation.cpp
mlir/test/CAPI/llvm.c
mlir/test/Dialect/LLVMIR/bytecode.mlir
mlir/test/Dialect/LLVMIR/debuginfo.mlir
mlir/test/Target/LLVMIR/Import/debug-info.ll
mlir/test/Target/LLVMIR/llvmir-debug.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 30137faaaa8d8..5c8e24bef3798 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -386,6 +386,18 @@ mlirLLVMDICompileUnitAttrGetWithSourceLanguageDialect(
MlirLLVMDINameTableKind nameTableKind, MlirAttribute splitDebugFilename,
intptr_t nImportedEntities, MlirAttribute const *importedEntities);
+/// Creates an LLVM DICompileUnit attribute with a DWARF v6 source language
+/// name, version, and optional source language dialect.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMDICompileUnitAttrGetWithSourceLanguageName(
+ MlirContext ctx, MlirAttribute recId, bool isRecSelf, MlirAttribute id,
+ unsigned int sourceLanguageName, uint32_t sourceLanguageVersion,
+ unsigned int sourceLanguageDialect, 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);
/// Creates a LLVM DIFlags attribute.
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index a9fd24e605120..88888e5c462b9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -360,6 +360,24 @@ def LLVM_DILanguageParameter : LLVM_DIParameter<
"language", /*default=*/"0", "Language", /*errorCase=*/"0"
>;
+def LLVM_DISourceLanguageNameParameter : AttrOrTypeParameter<
+ "unsigned", "debug info source language name"> {
+ let parser = [{ [&]() -> FailureOr<unsigned> {
+ SMLoc loc = $_parser.getCurrentLocation();
+ StringRef name;
+ if ($_parser.parseKeyword(&name))
+ return failure();
+ unsigned value = llvm::dwarf::getSourceLanguageName(name);
+ if (!value)
+ return $_parser.emitError(loc)
+ << "invalid debug info source language name: " << name;
+ return value;
+ }() }];
+ let printer = [{ $_printer << llvm::dwarf::SourceLanguageNameString(
+ static_cast<llvm::dwarf::SourceLanguageName>($_self)) }];
+ let defaultValue = "0";
+}
+
// Source-language dialect values are defined by LLVM's
// dwarf::LanguageDialectAttribute enum in llvm/BinaryFormat/Dwarf.h. LLVM
// represents "no source-language dialect" as 0; the LLVM IR printer omits the
@@ -443,6 +461,30 @@ def LLVM_DIBasicTypeAttr : LLVM_Attr<"DIBasicType", "di_basic_type",
let genMnemonicAlias = 1;
}
+//===----------------------------------------------------------------------===//
+// DISourceLanguageNameAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DISourceLanguageNameAttr : LLVM_Attr<"DISourceLanguageName",
+ "di_source_language_name"> {
+ let parameters = (ins
+ // An unversioned source-language name (a DW_LANG_* value). This maps to
+ // llvm::DISourceLanguageName::Name when HasVersion is false.
+ LLVM_DILanguageParameter:$language,
+ // A version-independent source-language name (a DW_LNAME_* value). This
+ // maps to llvm::DISourceLanguageName::Name when HasVersion is true.
+ LLVM_DISourceLanguageNameParameter:$name,
+ // The language-dependent version. Its presence maps to
+ // llvm::DISourceLanguageName::HasVersion and its value maps to Version.
+ OptionalParameter<"std::optional<uint32_t>">:$version,
+ // An optional target-specific source-language dialect. Zero represents no
+ // dialect, its value maps to llvm::DISourceLanguageName::Dialect.
+ LLVM_DILanguageDialectParameter:$dialect
+ );
+ let assemblyFormat = "`<` struct(params) `>`";
+ let genVerifyDecl = 1;
+}
+
//===----------------------------------------------------------------------===//
// DICompileUnitAttr
//===----------------------------------------------------------------------===//
@@ -456,8 +498,10 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
OptionalParameter<"bool">:$isRecSelf,
// DICompileUnitAttr specific parameters.
OptionalParameter<"DistinctAttr">:$id,
- LLVM_DILanguageParameter:$sourceLanguage,
- LLVM_DILanguageDialectParameter:$sourceLanguageDialect,
+ // A plain DW_LANG value uses the historical inline syntax. Source language
+ // names, versions, and dialects are represented by
+ // DISourceLanguageNameAttr.
+ OptionalParameter<"DISourceLanguageNameAttr">:$sourceLanguage,
OptionalParameter<"DIFileAttr">:$file,
OptionalParameter<"StringAttr">:$producer,
OptionalParameter<"bool">:$isOptimized,
@@ -478,8 +522,11 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
CArg<"StringAttr", "{}">:$splitDebugFilename,
CArg<"ArrayRef<DINodeAttr>", "{}">:$importedEntities
), [{
+ auto language = DISourceLanguageNameAttr::get(
+ id.getContext(), sourceLanguage, /*name=*/0,
+ /*version=*/std::nullopt, sourceLanguageDialect);
return $_get(id.getContext(), /*recId=*/nullptr, /*isRecSelf=*/false, id,
- sourceLanguage, sourceLanguageDialect, file, producer,
+ language, file, producer,
isOptimized, emissionKind, isDebugInfoForProfiling,
nameTableKind, splitDebugFilename, importedEntities);
}]>,
@@ -492,13 +539,25 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
CArg<"StringAttr", "{}">:$splitDebugFilename,
CArg<"ArrayRef<DINodeAttr>", "{}">:$importedEntities
), [{
+ auto language = DISourceLanguageNameAttr::get(
+ id.getContext(), sourceLanguage, /*name=*/0,
+ /*version=*/std::nullopt, /*dialect=*/0);
return $_get(id.getContext(), /*recId=*/nullptr, /*isRecSelf=*/false, id,
- sourceLanguage, /*sourceLanguageDialect=*/0, file, producer,
+ language, file, producer,
isOptimized, emissionKind, isDebugInfoForProfiling,
nameTableKind, splitDebugFilename, importedEntities);
}]>
];
- let assemblyFormat = "`<` struct(params) `>`";
+ let assemblyFormat = [{
+ `<` struct(
+ $recId, $isRecSelf, $id,
+ custom<SourceLanguage>($sourceLanguage),
+ $file, $producer, $isOptimized, $emissionKind,
+ $isDebugInfoForProfiling, $nameTableKind, $splitDebugFilename,
+ $importedEntities
+ ) `>`
+ }];
+ let genVerifyDecl = 1;
let extraClassDeclaration = [{
/// Requirements of DIRecursiveTypeAttrInterface.
/// @{
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index fe63c106a3e7c..15d81c4449ac5 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -124,6 +124,17 @@ def DISubroutineTypeAttr : DialectAttribute<(attr
OptionalArrayRef<"DITypeAttr">:$types
)>;
+//===----------------------------------------------------------------------===//
+// DISourceLanguageNameAttr
+//===----------------------------------------------------------------------===//
+
+def DISourceLanguageNameAttr : DialectAttribute<(attr
+ VarInt:$language,
+ VarInt:$name,
+ OptionalInt<"uint32_t">:$version,
+ VarInt:$dialect
+)>;
+
//===----------------------------------------------------------------------===//
// DICompileUnitAttr
//===----------------------------------------------------------------------===//
@@ -132,8 +143,7 @@ def DICompileUnitAttr : DialectAttribute<(attr
OptionalAttribute<"DistinctAttr">:$recId,
Bool:$isRecSelf,
OptionalAttribute<"DistinctAttr">:$id,
- VarInt:$sourceLanguage,
- VarInt:$sourceLanguageDialect,
+ OptionalAttribute<"DISourceLanguageNameAttr">:$sourceLanguage,
OptionalAttribute<"DIFileAttr">:$file,
OptionalAttribute<"StringAttr">:$producer,
Bool:$isOptimized,
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 9885ae7b2b77f..c9a0cc1f15af4 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -372,9 +372,37 @@ MlirAttribute mlirLLVMDICompileUnitAttrGetWithSourceLanguageDialect(
intptr_t nImportedEntities, MlirAttribute const *importedEntities) {
SmallVector<Attribute> importsStorage;
importsStorage.reserve(nImportedEntities);
+ auto sourceLanguageAttr = DISourceLanguageNameAttr::get(
+ unwrap(ctx), sourceLanguage, /*name=*/0, /*version=*/std::nullopt,
+ sourceLanguageDialect);
return wrap(DICompileUnitAttr::get(
unwrap(ctx), cast<DistinctAttr>(unwrap(recId)), isRecSelf,
- cast<DistinctAttr>(unwrap(id)), sourceLanguage, sourceLanguageDialect,
+ cast<DistinctAttr>(unwrap(id)), sourceLanguageAttr,
+ cast<DIFileAttr>(unwrap(file)), cast<StringAttr>(unwrap(producer)),
+ isOptimized, DIEmissionKind(emissionKind), isDebugInfoForProfiling,
+ DINameTableKind(nameTableKind),
+ cast<StringAttr>(unwrap(splitDebugFilename)),
+ llvm::map_to_vector(
+ unwrapList(nImportedEntities, importedEntities, importsStorage),
+ llvm::CastTo<DINodeAttr>)));
+}
+
+MlirAttribute mlirLLVMDICompileUnitAttrGetWithSourceLanguageName(
+ MlirContext ctx, MlirAttribute recId, bool isRecSelf, MlirAttribute id,
+ unsigned int sourceLanguageName, uint32_t sourceLanguageVersion,
+ unsigned int sourceLanguageDialect, 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);
+ auto sourceLanguageAttr = DISourceLanguageNameAttr::get(
+ unwrap(ctx), /*language=*/0, sourceLanguageName,
+ std::optional<uint32_t>(sourceLanguageVersion), sourceLanguageDialect);
+ return wrap(DICompileUnitAttr::get(
+ unwrap(ctx), cast<DistinctAttr>(unwrap(recId)), isRecSelf,
+ cast<DistinctAttr>(unwrap(id)), sourceLanguageAttr,
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 77a8b9d3846ab..b81b3121f2e18 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/ErrorHandling.h"
@@ -38,6 +39,17 @@ static ParseResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
static void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
ArrayRef<uint64_t> args);
+/// Parses a source language from either the historical inline `DW_LANG_*`
+/// syntax or a nested `DISourceLanguageNameAttr`.
+static ParseResult parseSourceLanguage(AsmParser &parser,
+ DISourceLanguageNameAttr &language);
+
+/// Prints an unversioned source language without a dialect using the
+/// historical inline `DW_LANG_*` syntax. All other source languages are
+/// printed as a nested `DISourceLanguageNameAttr`.
+static void printSourceLanguage(AsmPrinter &printer,
+ DISourceLanguageNameAttr language);
+
#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.cpp.inc"
#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
#define GET_ATTRDEF_CLASSES
@@ -382,6 +394,60 @@ DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
{}, {}, {}, {}, {});
}
+//===----------------------------------------------------------------------===//
+// DISourceLanguageNameAttr
+//===----------------------------------------------------------------------===//
+
+static ParseResult parseSourceLanguage(AsmParser &parser,
+ DISourceLanguageNameAttr &language) {
+ DISourceLanguageNameAttr nestedLanguage;
+ OptionalParseResult nestedResult =
+ parser.parseOptionalAttribute(nestedLanguage);
+ if (nestedResult.has_value()) {
+ if (failed(*nestedResult))
+ return failure();
+ language = nestedLanguage;
+ return success();
+ }
+
+ // If we cannot parse the full attr, try to just parse a DWARF language.
+ SMLoc loc = parser.getCurrentLocation();
+ StringRef spelling;
+ if (parser.parseKeyword(&spelling))
+ return failure();
+ if (unsigned value = llvm::dwarf::getLanguage(spelling)) {
+ language = DISourceLanguageNameAttr::get(
+ parser.getContext(), value, /*name=*/0, /*version=*/std::nullopt,
+ /*dialect=*/0);
+ return success();
+ }
+ return parser.emitError(loc)
+ << "invalid debug info source language: " << spelling;
+}
+
+static void printSourceLanguage(AsmPrinter &printer,
+ DISourceLanguageNameAttr language) {
+ // Print only the DWARF language if the other fields are not set.
+ if (language.getLanguage() && !language.getName() && !language.getVersion() &&
+ !language.getDialect()) {
+ printer << llvm::dwarf::LanguageString(language.getLanguage());
+ return;
+ }
+ printer.printAttribute(language);
+}
+
+LogicalResult DISourceLanguageNameAttr::verify(
+ function_ref<InFlightDiagnostic()> emitError, unsigned language,
+ unsigned name, std::optional<uint32_t> version, unsigned /*dialect*/) {
+ if (static_cast<bool>(language) == static_cast<bool>(name))
+ return emitError() << "expected exactly one of language or name";
+ if (name && !version)
+ return emitError() << "DW_LNAME requires a version";
+ if (language && version)
+ return emitError() << "DW_LANG cannot have a version";
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// DICompileUnitAttr
//===----------------------------------------------------------------------===//
@@ -389,21 +455,35 @@ DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
DIRecursiveTypeAttrInterface DICompileUnitAttr::withRecId(DistinctAttr recId) {
return DICompileUnitAttr::get(
getContext(), recId, getIsRecSelf(), getId(), getSourceLanguage(),
- getSourceLanguageDialect(), getFile(), getProducer(), getIsOptimized(),
- getEmissionKind(), getIsDebugInfoForProfiling(), getNameTableKind(),
- getSplitDebugFilename(), getImportedEntities());
+ getFile(), getProducer(), getIsOptimized(), getEmissionKind(),
+ getIsDebugInfoForProfiling(), getNameTableKind(), getSplitDebugFilename(),
+ getImportedEntities());
}
DIRecursiveTypeAttrInterface DICompileUnitAttr::getRecSelf(DistinctAttr recId) {
return DICompileUnitAttr::get(
recId.getContext(), recId, /*isRecSelf=*/true, /*id=*/{},
- /*sourceLanguage=*/0u, /*sourceLanguageDialect=*/0u, /*file=*/{},
- /*producer=*/{}, /*isOptimized=*/false, DIEmissionKind::None,
+ /*sourceLanguage=*/{},
+ /*file=*/{}, /*producer=*/{}, /*isOptimized=*/false, DIEmissionKind::None,
/*isDebugInfoForProfiling=*/false, DINameTableKind::Default,
/*splitDebugFilename=*/{}, /*importedEntities=*/{});
}
+LogicalResult DICompileUnitAttr::verify(
+ function_ref<InFlightDiagnostic()> emitError, DistinctAttr recId,
+ bool isRecSelf, DistinctAttr id, DISourceLanguageNameAttr sourceLanguage,
+ DIFileAttr file, StringAttr producer, bool isOptimized,
+ DIEmissionKind emissionKind, bool isDebugInfoForProfiling,
+ DINameTableKind nameTableKind, StringAttr splitDebugFilename,
+ ArrayRef<DINodeAttr> importedEntities) {
+ if (isRecSelf)
+ return success();
+ if (!sourceLanguage)
+ return emitError() << "sourceLanguage must be set";
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// DISubprogramAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 82beb2984b043..92a8c9aad249f 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -65,13 +65,22 @@ DICompileUnitAttr DebugImporter::translateImpl(llvm::DICompileUnit *node) {
imports.push_back(nodeAttr);
}
llvm::DISourceLanguageName sourceLanguage = node->getSourceLanguage();
+ DISourceLanguageNameAttr sourceLanguageAttr;
+ if (sourceLanguage.hasVersionedName()) {
+ sourceLanguageAttr = DISourceLanguageNameAttr::get(
+ context, /*language=*/0, sourceLanguage.getName(),
+ sourceLanguage.getVersion(), sourceLanguage.getDialect());
+ } else {
+ sourceLanguageAttr = DISourceLanguageNameAttr::get(
+ context, sourceLanguage.getName(), /*name=*/0,
+ /*version=*/std::nullopt, sourceLanguage.getDialect());
+ }
return DICompileUnitAttr::get(
context, /*recId=*/DistinctAttr{}, /*isRecSelf=*/false,
- getOrCreateDistinctID(node), sourceLanguage.getUnversionedName(),
- sourceLanguage.getDialect(), translate(node->getFile()),
- getStringAttrOrNull(node->getRawProducer()), node->isOptimized(),
- emissionKind.value(), node->isDebugInfoForProfiling(),
- nameTableKind.value(),
+ getOrCreateDistinctID(node), sourceLanguageAttr,
+ translate(node->getFile()), getStringAttrOrNull(node->getRawProducer()),
+ node->isOptimized(), emissionKind.value(),
+ node->isDebugInfoForProfiling(), nameTableKind.value(),
getStringAttrOrNull(node->getRawSplitDebugFilename()), imports);
}
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 4dc9e91b4e1c2..3ac2ccd506df3 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -139,11 +139,17 @@ llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
}
static llvm::DISourceLanguageName getSourceLanguage(DICompileUnitAttr attr) {
- // DISourceLanguageName represents "no source-language dialect" as 0; the
- // LLVM IR printer omits the `dialect:` field for that value.
+ DISourceLanguageNameAttr sourceLanguage = attr.getSourceLanguage();
+ // A DW_LNAME value selects the versioned source-language representation;
+ // otherwise, the value is an unversioned DW_LANG value.
+ if (sourceLanguage.getName())
+ return llvm::DISourceLanguageName(
+ static_cast<uint16_t>(sourceLanguage.getName()),
+ *sourceLanguage.getVersion(),
+ static_cast<uint16_t>(sourceLanguage.getDialect()));
return llvm::DISourceLanguageName(
- static_cast<uint16_t>(attr.getSourceLanguage()),
- static_cast<uint16_t>(attr.getSourceLanguageDialect()));
+ static_cast<uint16_t>(sourceLanguage.getLanguage()),
+ static_cast<uint16_t>(sourceLanguage.getDialect()));
}
llvm::TempDICompileUnit
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index 692a846d3b3c9..554c570943396 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -280,15 +280,30 @@ static void testDebugInfoAttributes(MlirContext ctx) {
// LLVM's dwarf::LanguageDialectAttribute enum.
MlirAttribute compile_unit =
mlirLLVMDICompileUnitAttrGetWithSourceLanguageDialect(
- ctx, recId0, false, id, LLVMDWARFSourceLanguageC99,
+ ctx, recId0, false, id, /*DW_LANG_C99=*/0x000c,
/*sourceLanguageDialect=*/1, file, foo, false,
MlirLLVMDIEmissionKindFull, false, MlirLLVMDINameTableKindDefault,
bar, 0, NULL);
- // CHECK: #llvm.di_compile_unit<{{.*}}sourceLanguageDialect =
- // CHECK-SAME: DW_LLVM_LANG_DIALECT_simt{{.*}}>
+ // CHECK: #llvm.di_compile_unit<{{.*}}sourceLanguage =
+ // CHECK-SAME: #llvm.di_source_language_name<language = DW_LANG_C99
+ // CHECK-SAME: dialect = DW_LLVM_LANG_DIALECT_simt>
mlirAttributeDump(compile_unit);
+ // sourceLanguageName 4 is DW_LNAME_C_plus_plus.
+ MlirAttribute versioned_compile_unit =
+ mlirLLVMDICompileUnitAttrGetWithSourceLanguageName(
+ ctx, recId0, false, id, /*sourceLanguageName=*/4,
+ /*sourceLanguageVersion=*/202002,
+ /*sourceLanguageDialect=*/1, file, foo, false,
+ MlirLLVMDIEmissionKindFull, false, MlirLLVMDINameTableKindDefault,
+ bar, 0, NULL);
+
+ // CHECK: #llvm.di_compile_unit<{{.*}}sourceLanguage =
+ // CHECK-SAME: #llvm.di_source_language_name<name = DW_LNAME_C_plus_plus
+ // CHECK-SAME: version = 202002
+ mlirAttributeDump(versioned_compile_unit);
+
// CHECK: #llvm.di_compile_unit<recId = {{.*}}, isRecSelf = true>
mlirAttributeDump(mlirLLVMDICompileUnitAttrGetRecSelf(recId1));
diff --git a/mlir/test/Dialect/LLVMIR/bytecode.mlir b/mlir/test/Dialect/LLVMIR/bytecode.mlir
index 02409c8adab94..095684a5bdd93 100644
--- a/mlir/test/Dialect/LLVMIR/bytecode.mlir
+++ b/mlir/test/Dialect/LLVMIR/bytecode.mlir
@@ -8,7 +8,14 @@
#loc6 = loc(fused<#di_subprogram>[#loc1])
#loc7 = loc(fused<#di_subprogram>[#loc2])
#loop_annotation = #llvm.loop_annotation<disableNonforced = false, mustProgress = true, startLoc = #loc6, endLoc = #loc7, parallelAccesses = #access_group, #access_group1>
-module {
+#versioned_file = #llvm.di_file<"test.f90" in "">
+#versioned_cu = #llvm.di_compile_unit<
+ id = distinct[7]<>, sourceLanguage = #llvm.di_source_language_name<
+ name = DW_LNAME_Fortran, version = 2018,
+ dialect = DW_LLVM_LANG_DIALECT_tile>,
+ file = #versioned_file, isOptimized = false, emissionKind = Full
+>
+module attributes {test.versioned_cu = #versioned_cu} {
llvm.func @imp_fn() {
llvm.return loc(#loc2)
} loc(#loc8)
@@ -24,7 +31,7 @@ module {
#loc3 = loc("test-path":36:3)
#loc4 = loc("test-path":37:5)
#loc5 = loc("test-path":39:5)
-#di_compile_unit = #llvm.di_compile_unit<id = distinct[3]<>, sourceLanguage = DW_LANG_Fortran95, sourceLanguageDialect = DW_LLVM_LANG_DIALECT_tile, file = #di_file, isOptimized = false, emissionKind = Full>
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[3]<>, sourceLanguage = #llvm.di_source_language_name<language = DW_LANG_Fortran95, dialect = DW_LLVM_LANG_DIALECT_tile>, file = #di_file, isOptimized = false, emissionKind = Full>
#di_compile_unit1 = #llvm.di_compile_unit<id = distinct[4]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full>
#di_compile_unit2 = #llvm.di_compile_unit<id = distinct[5]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full>
#di_module = #llvm.di_module<file = #di_file, scope = #di_compile_unit1, name = "mod1">
diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
index 020f3b3b0ee7a..15ebd664d99af 100644
--- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir
+++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
@@ -5,12 +5,12 @@
// CHECK-DAG: #[[NS:.*]] = #llvm.di_namespace<name = "cu_import_ns", exportSymbols = false>
// CHECK-DAG: #[[IE:.*]] = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #[[FILE]], entity = #[[NS]], file = #[[FILE]]>
-// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, sourceLanguageDialect = DW_LLVM_LANG_DIALECT_simt, file = #[[FILE]], producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true, importedEntities = #[[IE]]>
+// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = #llvm.di_source_language_name<language = DW_LANG_C, dialect = DW_LLVM_LANG_DIALECT_simt>, file = #[[FILE]], producer = "MLIR", isOptimized = true, emissionKind = Full, isDebugInfoForProfiling = true, importedEntities = #[[IE]]>
#cu_import_ns = #llvm.di_namespace<name = "cu_import_ns", exportSymbols = false>
#cu_import_ie = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #file, entity = #cu_import_ns, file = #file>
#cu = #llvm.di_compile_unit<
- id = distinct[0]<>, sourceLanguage = DW_LANG_C,
- sourceLanguageDialect = DW_LLVM_LANG_DIALECT_simt, file = #file,
+ id = distinct[0]<>, sourceLanguage = #llvm.di_source_language_name<
+ language = DW_LANG_C, dialect = DW_LLVM_LANG_DIALECT_simt>, file = #file,
producer = "MLIR", isOptimized = true, emissionKind = Full,
isDebugInfoForProfiling = true, importedEntities = #cu_import_ie
>
diff --git a/mlir/test/Dialect/LLVMIR/di-compile-unit-source-language.mlir b/mlir/test/Dialect/LLVMIR/di-compile-unit-source-language.mlir
new file mode 100644
index 0000000000000..34d86a1aa0948
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/di-compile-unit-source-language.mlir
@@ -0,0 +1,24 @@
+// RUN: mlir-opt %s --verify-roundtrip | FileCheck %s
+
+#file = #llvm.di_file<"source.cpp" in "/test/">
+
+// A plain DW_LANG retains the historical inline syntax.
+// CHECK: sourceLanguage = DW_LANG_C_plus_plus_20
+module attributes {test.language = #llvm.di_compile_unit<
+ id = distinct[0]<>, sourceLanguage = DW_LANG_C_plus_plus_20, file = #file
+>} {}
+
+// CHECK: sourceLanguage = #llvm.di_source_language_name<name = DW_LNAME_C_plus_plus, version = 202002, dialect = DW_LLVM_LANG_DIALECT_simt>
+module attributes {test.versioned = #llvm.di_compile_unit<
+ id = distinct[1]<>, sourceLanguage = #llvm.di_source_language_name<
+ name = DW_LNAME_C_plus_plus, version = 202002,
+ dialect = DW_LLVM_LANG_DIALECT_simt>, file = #file
+>} {}
+
+// An explicitly set zero version selects a source language name.
+// CHECK: #llvm.di_compile_unit<
+// CHECK-SAME: sourceLanguage = #llvm.di_source_language_name<name = DW_LNAME_Rust, version = 0>
+module attributes {test.unversioned_name = #llvm.di_compile_unit<
+ id = distinct[2]<>, sourceLanguage = #llvm.di_source_language_name<
+ version = 0, name = DW_LNAME_Rust>, file = #file
+>} {}
diff --git a/mlir/test/Dialect/LLVMIR/invalid-di-compile-unit-source-language.mlir b/mlir/test/Dialect/LLVMIR/invalid-di-compile-unit-source-language.mlir
new file mode 100644
index 0000000000000..7a285c91e30d4
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/invalid-di-compile-unit-source-language.mlir
@@ -0,0 +1,31 @@
+// RUN: mlir-opt %s -split-input-file -verify-diagnostics
+
+#file = #llvm.di_file<"source.cpp" in "/test/">
+
+// expected-error @+1 {{expected exactly one of language or name}}
+module attributes {test.language = #llvm.di_source_language_name<>} {}
+
+// -----
+
+// expected-error @+1 {{expected exactly one of language or name}}
+module attributes {test.language = #llvm.di_source_language_name<language = DW_LANG_C, name = DW_LNAME_C, version = 199901>} {}
+
+// -----
+
+// expected-error @+1 {{duplicate or unknown struct parameter name: sourceLanguage}}
+module attributes {test.cu = #llvm.di_compile_unit<sourceLanguage = DW_LANG_C_plus_plus_20, sourceLanguage = #llvm.di_source_language_name<name = DW_LNAME_C_plus_plus, version = 202002>, file = #file>} {}
+
+// -----
+
+// expected-error @+1 {{sourceLanguage must be set}}
+module attributes {test.cu = #llvm.di_compile_unit<>} {}
+
+// -----
+
+// expected-error @+1 {{DW_LANG cannot have a version}}
+module attributes {test.cu = #llvm.di_compile_unit<sourceLanguage = #llvm.di_source_language_name<language = DW_LANG_C, version = 202002>>} {}
+
+// -----
+
+// expected-error @+1 {{DW_LNAME requires a version}}
+module attributes {test.cu = #llvm.di_compile_unit<sourceLanguage = #llvm.di_source_language_name<name = DW_LNAME_Rust>>} {}
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index f00fd792e77fa..5d222ad08f91e 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -1050,7 +1050,7 @@ define void @fn_with_static_local() !dbg !3 {
; // -----
; CHECK-DAG: #[[DIALECT_FILE:.+]] = #llvm.di_file<"dialect.ll" in "/">
-; CHECK-DAG: #[[DIALECT_CU:.+]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, sourceLanguageDialect = DW_LLVM_LANG_DIALECT_tile, file = #[[DIALECT_FILE]]>
+; CHECK-DAG: #[[DIALECT_CU:.+]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = #llvm.di_source_language_name<language = DW_LANG_C, dialect = DW_LLVM_LANG_DIALECT_tile>, file = #[[DIALECT_FILE]]>
define void @fn_cu_dialect() !dbg !3 {
ret void
@@ -1065,3 +1065,22 @@ define void @fn_cu_dialect() !dbg !3 {
!3 = distinct !DISubprogram(name: "fn_cu_dialect", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4)
!4 = !DISubroutineType(types: !5)
!5 = !{null}
+
+; // -----
+
+; CHECK-DAG: #[[LNAME_FILE:.+]] = #llvm.di_file<"language-name.cpp" in "/test/">
+; CHECK-DAG: #[[LNAME_CU:.+]] = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = #llvm.di_source_language_name<name = DW_LNAME_C_plus_plus, version = 202002, dialect = DW_LLVM_LANG_DIALECT_simt>, file = #[[LNAME_FILE]]>
+
+define void @fn_cu_source_language_name() !dbg !3 {
+ ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 202002, file: !2, dialect: DW_LLVM_LANG_DIALECT_simt)
+!2 = !DIFile(filename: "language-name.cpp", directory: "/test/")
+!3 = distinct !DISubprogram(name: "fn_cu_source_language_name", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4)
+!4 = !DISubroutineType(types: !5)
+!5 = !{null}
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 6628b2882a26c..27858cc008956 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -872,8 +872,8 @@ llvm.func @fn_cu_import_cycle() {
#file = #llvm.di_file<"dialect.mlir" in "/test/">
#cu = #llvm.di_compile_unit<
- id = distinct[0]<>, sourceLanguage = DW_LANG_C,
- sourceLanguageDialect = DW_LLVM_LANG_DIALECT_simt, file = #file,
+ id = distinct[0]<>, sourceLanguage = #llvm.di_source_language_name<
+ language = DW_LANG_C, dialect = DW_LLVM_LANG_DIALECT_simt>, file = #file,
isOptimized = false, emissionKind = Full
>
#sp_ty = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
@@ -892,6 +892,28 @@ llvm.func @fn_cu_dialect() {
// -----
+#file = #llvm.di_file<"language-name.cpp" in "/test/">
+#cu = #llvm.di_compile_unit<
+ id = distinct[0]<>, sourceLanguage = #llvm.di_source_language_name<
+ name = DW_LNAME_C_plus_plus, version = 202002,
+ dialect = DW_LLVM_LANG_DIALECT_simt>, file = #file,
+ isOptimized = false, emissionKind = Full
+>
+#sp_ty = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
+#sp = #llvm.di_subprogram<
+ compileUnit = #cu, scope = #file, name = "fn_cu_source_language_name",
+ file = #file, line = 1, scopeLine = 1, subprogramFlags = Definition,
+ type = #sp_ty
+>
+
+// CHECK-LABEL: define void @fn_cu_source_language_name()
+// CHECK-DAG: ![[LNAME_CU:[0-9]+]] = distinct !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 202002, file: !{{[0-9]+}}, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, dialect: DW_LLVM_LANG_DIALECT_simt)
+llvm.func @fn_cu_source_language_name() {
+ llvm.return
+} loc(fused<#sp>["language-name.cpp":1:1])
+
+// -----
+
#di_file = #llvm.di_file<"foo.mlir" in "/tmp">
#di_cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = Full>
#di_uint8 = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "uint8", sizeInBits = 8, encoding = DW_ATE_unsigned>
More information about the Mlir-commits
mailing list