diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h index e754318d66856..902b45444d6c4 100644 --- a/mlir/include/mlir-c/Dialect/LLVM.h +++ b/mlir/include/mlir-c/Dialect/LLVM.h @@ -251,6 +251,12 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIDerivedTypeAttrGet( MlirAttribute baseType, uint64_t sizeInBits, uint32_t alignInBits, uint64_t offsetInBits, int64_t dwarfAddressSpace, MlirAttribute extraData); +MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIStringTypeAttrGet( + MlirContext ctx, unsigned int tag, MlirAttribute name, uint64_t sizeInBits, + uint32_t alignInBits, MlirAttribute stringLength, + MlirAttribute stringLengthExp, MlirAttribute stringLocationExp, + MlirLLVMTypeEncoding encoding); + /// Constant to represent std::nullopt for dwarfAddressSpace to omit the field. #define MLIR_CAPI_DWARF_ADDRESS_SPACE_NULL -1 diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index ec58cf368b593..b05366d2a635d 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -676,6 +676,25 @@ def LLVM_DILabelAttr : LLVM_Attr<"DILabel", "di_label", let assemblyFormat = "`<` struct(params) `>`"; } +//===----------------------------------------------------------------------===// +// DIStringTypeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DIStringTypeAttr : LLVM_Attr<"DIStringType", "di_string_type", + /*traits=*/[], "DITypeAttr"> { + let parameters = (ins + LLVM_DITagParameter:$tag, + "StringAttr":$name, + OptionalParameter<"uint64_t">:$sizeInBits, + OptionalParameter<"uint32_t">:$alignInBits, + OptionalParameter<"DIVariableAttr">:$stringLength, + OptionalParameter<"DIExpressionAttr">:$stringLengthExp, + OptionalParameter<"DIExpressionAttr">:$stringLocationExp, + LLVM_DIEncodingParameter:$encoding + ); + let assemblyFormat = "`<` struct(params) `>`"; +} + //===----------------------------------------------------------------------===// // MemoryEffectsAttr //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h index 091a817caf3d6..3a93be21da375 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h @@ -60,6 +60,15 @@ class DITypeAttr : public DINodeAttr { static bool classof(Attribute attr); }; +/// This class represents a LLVM attribute that describes a debug info variable. +class DIVariableAttr : public DINodeAttr { +public: + using DINodeAttr::DINodeAttr; + + /// Support LLVM type casting. + static bool classof(Attribute attr); +}; + /// Base class for LLVM attributes participating in the TBAA graph. class TBAANodeAttr : public Attribute { public: diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp index f6fb2cbedfac0..754c94511524d 100644 --- a/mlir/lib/CAPI/Dialect/LLVM.cpp +++ b/mlir/lib/CAPI/Dialect/LLVM.cpp @@ -195,6 +195,18 @@ MlirAttribute mlirLLVMDIDerivedTypeAttrGet( addressSpace, cast(unwrap(extraData)))); } +MlirAttribute mlirLLVMDIStringTypeAttrGet( + MlirContext ctx, unsigned int tag, MlirAttribute name, uint64_t sizeInBits, + uint32_t alignInBits, MlirAttribute stringLength, + MlirAttribute stringLengthExp, MlirAttribute stringLocationExp, + MlirLLVMTypeEncoding encoding) { + return wrap(DIStringTypeAttr::get( + unwrap(ctx), tag, cast(unwrap(name)), sizeInBits, alignInBits, + cast(unwrap(stringLength)), + cast(unwrap(stringLengthExp)), + cast(unwrap(stringLocationExp)), encoding)); +} + MlirAttribute mlirLLVMDIDerivedTypeAttrGetBaseType(MlirAttribute diDerivedType) { return wrap(cast(unwrap(diDerivedType)).getBaseType()); diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index 9bc71e1ebc489..963a4be25079e 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -60,8 +60,8 @@ bool DINodeAttr::classof(Attribute attr) { DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr, DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr, DINamespaceAttr, - DINullTypeAttr, DISubprogramAttr, DISubrangeAttr, - DISubroutineTypeAttr>(attr); + DINullTypeAttr, DIStringTypeAttr, DISubprogramAttr, + DISubrangeAttr, DISubroutineTypeAttr>(attr); } //===----------------------------------------------------------------------===// @@ -82,13 +82,22 @@ bool DILocalScopeAttr::classof(Attribute attr) { DISubprogramAttr>(attr); } +//===----------------------------------------------------------------------===// +// DIVariableAttr +//===----------------------------------------------------------------------===// + +bool DIVariableAttr::classof(Attribute attr) { + return llvm::isa(attr); +} + //===----------------------------------------------------------------------===// // DITypeAttr //===----------------------------------------------------------------------===// bool DITypeAttr::classof(Attribute attr) { return llvm::isa(attr); + DIDerivedTypeAttr, DIStringTypeAttr, DISubroutineTypeAttr>( + attr); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index 60b911948d4a0..76cac0b05b475 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -3031,12 +3031,12 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface { DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr, DIGlobalVariableExpressionAttr, DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr, - DINamespaceAttr, DINullTypeAttr, DISubprogramAttr, - DISubroutineTypeAttr, LoopAnnotationAttr, LoopVectorizeAttr, - LoopInterleaveAttr, LoopUnrollAttr, LoopUnrollAndJamAttr, - LoopLICMAttr, LoopDistributeAttr, LoopPipelineAttr, - LoopPeeledAttr, LoopUnswitchAttr, TBAARootAttr, TBAATagAttr, - TBAATypeDescriptorAttr>([&](auto attr) { + DINamespaceAttr, DINullTypeAttr, DIStringTypeAttr, + DISubprogramAttr, DISubroutineTypeAttr, LoopAnnotationAttr, + LoopVectorizeAttr, LoopInterleaveAttr, LoopUnrollAttr, + LoopUnrollAndJamAttr, LoopLICMAttr, LoopDistributeAttr, + LoopPipelineAttr, LoopPeeledAttr, LoopUnswitchAttr, TBAARootAttr, + TBAATagAttr, TBAATypeDescriptorAttr>([&](auto attr) { os << decltype(attr)::getMnemonic(); return AliasResult::OverridableAlias; }) diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index a373c1fb5cdab..15737aa681c59 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -113,6 +113,15 @@ DIDerivedTypeAttr DebugImporter::translateImpl(llvm::DIDerivedType *node) { node->getOffsetInBits(), node->getDWARFAddressSpace(), extraData); } +DIStringTypeAttr DebugImporter::translateImpl(llvm::DIStringType *node) { + return DIStringTypeAttr::get( + context, node->getTag(), getStringAttrOrNull(node->getRawName()), + node->getSizeInBits(), node->getAlignInBits(), + translate(node->getStringLength()), + translateExpression(node->getStringLengthExp()), + translateExpression(node->getStringLocationExp()), node->getEncoding()); +} + DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) { return DIFileAttr::get(context, node->getFilename(), node->getDirectory()); } @@ -174,6 +183,10 @@ DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) { node->getAlignInBits(), translate(node->getType())); } +DIVariableAttr DebugImporter::translateImpl(llvm::DIVariable *node) { + return cast(translate(static_cast(node))); +} + DIScopeAttr DebugImporter::translateImpl(llvm::DIScope *node) { return cast(translate(static_cast(node))); } @@ -295,6 +308,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *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)) return translateImpl(casted); if (auto *casted = dyn_cast(node)) diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.h b/mlir/lib/Target/LLVMIR/DebugImporter.h index 5f402fb0b657c..fac86dbe2cdd2 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.h +++ b/mlir/lib/Target/LLVMIR/DebugImporter.h @@ -63,12 +63,14 @@ class DebugImporter { DICompileUnitAttr translateImpl(llvm::DICompileUnit *node); DICompositeTypeAttr translateImpl(llvm::DICompositeType *node); DIDerivedTypeAttr translateImpl(llvm::DIDerivedType *node); + DIStringTypeAttr translateImpl(llvm::DIStringType *node); DIFileAttr translateImpl(llvm::DIFile *node); DILabelAttr translateImpl(llvm::DILabel *node); DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node); DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node); DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node); DILocalVariableAttr translateImpl(llvm::DILocalVariable *node); + DIVariableAttr translateImpl(llvm::DIVariable *node); DIModuleAttr translateImpl(llvm::DIModule *node); DINamespaceAttr translateImpl(llvm::DINamespace *node); DIScopeAttr translateImpl(llvm::DIScope *node); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index aef7a06f96c34..35800e993d89d 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -182,6 +182,15 @@ llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) { /*Flags=*/llvm::DINode::FlagZero, translate(attr.getExtraData())); } +llvm::DIStringType *DebugTranslation::translateImpl(DIStringTypeAttr attr) { + return llvm::DIStringType::get( + llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()), + translate(attr.getStringLength()), + getExpressionAttrOrNull(attr.getStringLengthExp()), + getExpressionAttrOrNull(attr.getStringLocationExp()), + attr.getSizeInBits(), attr.getAlignInBits(), attr.getEncoding()); +} + llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) { return llvm::DIFile::get(llvmCtx, getMDStringOrNull(attr.getName()), getMDStringOrNull(attr.getDirectory())); @@ -210,6 +219,10 @@ llvm::DILocalScope *DebugTranslation::translateImpl(DILocalScopeAttr attr) { return cast(translate(DINodeAttr(attr))); } +llvm::DIVariable *DebugTranslation::translateImpl(DIVariableAttr attr) { + return cast(translate(DINodeAttr(attr))); +} + llvm::DILocalVariable * DebugTranslation::translateImpl(DILocalVariableAttr attr) { return llvm::DILocalVariable::get( @@ -377,8 +390,8 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) { DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr, DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr, DINamespaceAttr, - DINullTypeAttr, DISubprogramAttr, DISubrangeAttr, - DISubroutineTypeAttr>( + DINullTypeAttr, DIStringTypeAttr, DISubprogramAttr, + DISubrangeAttr, DISubroutineTypeAttr>( [&](auto attr) { return translateImpl(attr); }); if (node && !node->isTemporary()) diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h index 04b7ea41add9a..16a853736226d 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -73,6 +73,7 @@ class DebugTranslation { llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr); llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr); llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr); + llvm::DIStringType *translateImpl(DIStringTypeAttr attr); llvm::DIFile *translateImpl(DIFileAttr attr); llvm::DILabel *translateImpl(DILabelAttr attr); llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr); @@ -80,6 +81,7 @@ class DebugTranslation { llvm::DILocalScope *translateImpl(DILocalScopeAttr attr); llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr); llvm::DIGlobalVariable *translateImpl(DIGlobalVariableAttr attr); + llvm::DIVariable *translateImpl(DIVariableAttr attr); llvm::DIModule *translateImpl(DIModuleAttr attr); llvm::DINamespace *translateImpl(DINamespaceAttr attr); llvm::DIScope *translateImpl(DIScopeAttr attr); diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c index f1d02b43d5232..082ddc53e6282 100644 --- a/mlir/test/CAPI/llvm.c +++ b/mlir/test/CAPI/llvm.c @@ -293,8 +293,9 @@ static void testDebugInfoAttributes(MlirContext ctx) { mlirLLVMDILexicalBlockFileAttrGet(ctx, compile_unit, file, 3)); // CHECK: #llvm.di_local_variable<{{.*}}> - mlirAttributeDump(mlirLLVMDILocalVariableAttrGet(ctx, compile_unit, foo, file, - 1, 0, 8, di_type)); + MlirAttribute local_var = mlirLLVMDILocalVariableAttrGet( + ctx, compile_unit, foo, file, 1, 0, 8, di_type); + mlirAttributeDump(local_var); // CHECK: #llvm.di_derived_type<{{.*}}> // CHECK-NOT: dwarfAddressSpace mlirAttributeDump(mlirLLVMDIDerivedTypeAttrGet( @@ -337,6 +338,12 @@ static void testDebugInfoAttributes(MlirContext ctx) { // CHECK: #llvm.di_expression<[(1)]> mlirAttributeDump(expression); + MlirAttribute string_type = + mlirLLVMDIStringTypeAttrGet(ctx, 0x0, foo, 16, 0, local_var, expression, + expression, MlirLLVMTypeEncodingSigned); + // CHECK: #llvm.di_string_type<{{.*}}> + mlirAttributeDump(string_type); + // CHECK: #llvm.di_composite_type<{{.*}}> mlirAttributeDump(mlirLLVMDICompositeTypeAttrGet( ctx, 0, id, foo, file, 1, compile_unit, di_type, 0, 64, 8, 1, &di_type, diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 0c6a7368b7b88..2173cc33e68a4 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -761,3 +761,35 @@ define void @class_field(ptr %arg1) !dbg !18 { !11 = !{!6, !7, !8} ; C -> A, B, C !18 = distinct !DISubprogram(name: "SP", scope: !3, file: !2, spFlags: DISPFlagDefinition, unit: !1) + +; // ----- + +; Verify the string type is handled correctly + +define void @string_type(ptr %arg1) { + call void @llvm.dbg.value(metadata ptr %arg1, metadata !4, metadata !DIExpression()), !dbg !10 + call void @llvm.dbg.value(metadata ptr %arg1, metadata !9, metadata !DIExpression()), !dbg !10 + 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) +!2 = !DIFile(filename: "debug-info.ll", directory: "/") +!3 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!4 = !DILocalVariable(scope: !5, name: "string_size", file: !2, type: !3); +!5 = distinct !DISubprogram(name: "test", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1) +!6 = !DIStringType(name: "character(*)", stringLength: !4, size: 32, align: 8, stringLengthExpression: !8, stringLocationExpression: !7) +!7 = !DIExpression(DW_OP_push_object_address, DW_OP_deref) +!8 = !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8) +!9 = !DILocalVariable(scope: !5, name: "str", file: !2, type: !6); +!10 = !DILocation(line: 1, column: 2, scope: !5) + +; CHECK: #[[VAR:.+]] = #llvm.di_local_variable<{{.*}}name = "string_size"{{.*}}> +; CHECK: #llvm.di_string_type +; CHECK-SAME: stringLocationExp = <[DW_OP_push_object_address, DW_OP_deref]>> diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index 724f45f0d2a87..c6e7ca6f3f21d 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -564,3 +564,30 @@ llvm.func @subranges(%arg: !llvm.ptr) { // CHECK: ![[ELEMENTS2]] = !{![[ELEMENT2:[0-9]+]]} // CHECK: ![[ELEMENT2]] = !DISubrange(count: ![[LV:[0-9]+]], stride: ![[GV:[0-9]+]]) // CHECK: ![[LV]] = !DILocalVariable(name: "size"{{.*}}) + +// ----- + +#bt = #llvm.di_basic_type +#file = #llvm.di_file<"debug-info.ll" in "/"> +#cu = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C, + file = #file, isOptimized = false, emissionKind = Full> +#sp = #llvm.di_subprogram +#var = #llvm.di_local_variable +#ty = #llvm.di_string_type, + stringLocationExp = <[DW_OP_push_object_address, DW_OP_deref]>> +#var1 = #llvm.di_local_variable + +llvm.func @string_ty(%arg0: !llvm.ptr) { + llvm.intr.dbg.value #var1 = %arg0 : !llvm.ptr + llvm.intr.dbg.value #var = %arg0 : !llvm.ptr + llvm.return +} loc(#loc2) + +#loc1 = loc("test.f90":1:1) +#loc2 = loc(fused<#sp>[#loc1]) + +// CHECK-DAG: !DIStringType(name: "character(*)", stringLength: ![[VAR:[0-9]+]], stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), size: 32, align: 8) +// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "string_size"{{.*}})