[mlir][llvm] Add an explicit void type debug info attribute.
Previously, the DISubroutineType attribute used an optional result parameter and an optional argument types array to model the subroutine signature. LLVM IR debug metadata, on the other hand, has one types list whose first entry maps to the result type. That entry may be null to model a void result type. The type list may also be entirely empty not specifying any type information. The latter is problematic since the current DISubroutineType attribute cannot express it. The revision changes DISubroutineTypeAttr to closely follow the LLVM metadata design. In particular, it uses a single types parameter array to model the subroutine signature and introduces an explicit DIVoidResultTypeAttr to model the null entries. Reviewed By: Dinistro Differential Revision: https://reviews.llvm.org/D141261
This commit is contained in:
@@ -122,6 +122,15 @@ def LLVM_DITagParameter : LLVM_DIParameter<
|
||||
"tag", /*default=*/"", "Tag"
|
||||
>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIVoidResultTypeAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def LLVM_DIVoidResultTypeAttr : LLVM_Attr<"DIVoidResultType", "di_void_result_type",
|
||||
/*traits=*/[], "DITypeAttr"> {
|
||||
let parameters = (ins);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIBasicTypeAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -353,16 +362,15 @@ def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_typ
|
||||
], "DITypeAttr"> {
|
||||
let parameters = (ins
|
||||
LLVM_DICallingConventionParameter:$callingConvention,
|
||||
OptionalParameter<"DITypeAttr">:$resultType,
|
||||
OptionalArrayRefParameter<"DITypeAttr">:$argumentTypes
|
||||
OptionalArrayRefParameter<"DITypeAttr">:$types
|
||||
);
|
||||
let builders = [
|
||||
TypeBuilder<(ins "DITypeAttr":$resultType,
|
||||
"ArrayRef<DITypeAttr>":$argumentTypes), [{
|
||||
return $_get($_ctxt, /*callingConvention=*/0, resultType, argumentTypes);
|
||||
TypeBuilder<(ins "ArrayRef<DITypeAttr>":$types), [{
|
||||
return $_get($_ctxt, /*callingConvention=*/0, types);
|
||||
}]>
|
||||
];
|
||||
let assemblyFormat = "`<` struct(params) `>`";
|
||||
let genVerifyDecl = 1;
|
||||
}
|
||||
|
||||
#endif // LLVMIR_ATTRDEFS
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/DialectImplementation.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/TypeSwitch.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
@@ -41,11 +42,11 @@ void LLVMDialect::registerAttributes() {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool DINodeAttr::classof(Attribute attr) {
|
||||
return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
|
||||
DILexicalBlockFileAttr, DILocalVariableAttr,
|
||||
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
|
||||
attr);
|
||||
return llvm::isa<DIVoidResultTypeAttr, DIBasicTypeAttr, DICompileUnitAttr,
|
||||
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
|
||||
DILexicalBlockAttr, DILexicalBlockFileAttr,
|
||||
DILocalVariableAttr, DISubprogramAttr, DISubrangeAttr,
|
||||
DISubroutineTypeAttr>(attr);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -63,8 +64,23 @@ bool DIScopeAttr::classof(Attribute attr) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool DITypeAttr::classof(Attribute attr) {
|
||||
return llvm::isa<DIBasicTypeAttr, DICompositeTypeAttr, DIDerivedTypeAttr,
|
||||
DISubroutineTypeAttr>(attr);
|
||||
return llvm::isa<DIVoidResultTypeAttr, DIBasicTypeAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DISubroutineTypeAttr>(attr);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DISubroutineTypeAttr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
LogicalResult
|
||||
DISubroutineTypeAttr::verify(function_ref<InFlightDiagnostic()> emitError,
|
||||
unsigned int callingConventions,
|
||||
ArrayRef<DITypeAttr> types) {
|
||||
if (llvm::any_of(llvm::drop_begin(types), [](DITypeAttr type) {
|
||||
return type.isa<DIVoidResultTypeAttr>();
|
||||
}))
|
||||
return emitError() << "expected subroutine to have non-void argument types";
|
||||
return success();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -2810,10 +2810,10 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface {
|
||||
|
||||
AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
|
||||
return TypeSwitch<Attribute, AliasResult>(attr)
|
||||
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
|
||||
DILexicalBlockFileAttr, DILocalVariableAttr, DISubprogramAttr,
|
||||
DISubroutineTypeAttr>([&](auto attr) {
|
||||
.Case<DIVoidResultTypeAttr, DIBasicTypeAttr, DICompileUnitAttr,
|
||||
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
|
||||
DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr,
|
||||
DISubprogramAttr, DISubroutineTypeAttr>([&](auto attr) {
|
||||
os << decltype(attr)::getMnemonic();
|
||||
return AliasResult::OverridableAlias;
|
||||
})
|
||||
|
||||
@@ -129,15 +129,19 @@ DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) {
|
||||
|
||||
DISubroutineTypeAttr
|
||||
DebugImporter::translateImpl(llvm::DISubroutineType *node) {
|
||||
// Separate the result type since it is null for void functions.
|
||||
DITypeAttr resultType = translate(*node->getTypeArray().begin());
|
||||
SmallVector<DITypeAttr> argumentTypes;
|
||||
for (llvm::DIType *type : llvm::drop_begin(node->getTypeArray())) {
|
||||
assert(type && "expected a non-null argument type");
|
||||
argumentTypes.push_back(translate(type));
|
||||
SmallVector<DITypeAttr> types;
|
||||
for (llvm::DIType *type : node->getTypeArray()) {
|
||||
if (!type) {
|
||||
// A nullptr entry at the beginning of the subroutine types list models a
|
||||
// void result type. Translate the nullptr to an explicit
|
||||
// DIVoidResultTypeAttr since the attribute list cannot contain a nullptr
|
||||
// entry.
|
||||
types.push_back(DIVoidResultTypeAttr::get(context));
|
||||
continue;
|
||||
}
|
||||
types.push_back(translate(type));
|
||||
}
|
||||
return DISubroutineTypeAttr::get(context, node->getCC(), resultType,
|
||||
argumentTypes);
|
||||
return DISubroutineTypeAttr::get(context, node->getCC(), types);
|
||||
}
|
||||
|
||||
DITypeAttr DebugImporter::translateImpl(llvm::DIType *node) {
|
||||
|
||||
@@ -88,6 +88,14 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
|
||||
// Attributes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
llvm::DIType *DebugTranslation::translateImpl(DIVoidResultTypeAttr attr) {
|
||||
// A DIVoidResultTypeAttr at the beginning of the subroutine types list models
|
||||
// a void result type. Translate the explicit DIVoidResultTypeAttr to a
|
||||
// nullptr since LLVM IR metadata does not have an explicit void result type
|
||||
// representation.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
|
||||
return llvm::DIBasicType::get(
|
||||
llvmCtx, attr.getTag(), attr.getName(), attr.getSizeInBits(),
|
||||
@@ -201,8 +209,8 @@ llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
|
||||
llvm::DISubroutineType *
|
||||
DebugTranslation::translateImpl(DISubroutineTypeAttr attr) {
|
||||
// Concatenate the result and argument types into a single array.
|
||||
SmallVector<llvm::Metadata *> types = {translate(attr.getResultType())};
|
||||
for (DITypeAttr type : attr.getArgumentTypes())
|
||||
SmallVector<llvm::Metadata *> types;
|
||||
for (DITypeAttr type : attr.getTypes())
|
||||
types.push_back(translate(type));
|
||||
return llvm::DISubroutineType::get(
|
||||
llvmCtx, llvm::DINode::FlagZero, attr.getCallingConvention(),
|
||||
@@ -222,10 +230,10 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
|
||||
|
||||
llvm::DINode *node =
|
||||
TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
|
||||
.Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
|
||||
DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
|
||||
DILexicalBlockFileAttr, DILocalVariableAttr, DISubprogramAttr,
|
||||
DISubrangeAttr, DISubroutineTypeAttr>(
|
||||
.Case<DIVoidResultTypeAttr, DIBasicTypeAttr, DICompileUnitAttr,
|
||||
DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr,
|
||||
DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr,
|
||||
DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
|
||||
[&](auto attr) { return translateImpl(attr); });
|
||||
attrToNode.insert({attr, node});
|
||||
return node;
|
||||
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
llvm::DIFile *translateFile(StringRef fileName);
|
||||
|
||||
/// Translate the given attribute to the corresponding llvm debug metadata.
|
||||
llvm::DIType *translateImpl(DIVoidResultTypeAttr attr);
|
||||
llvm::DIBasicType *translateImpl(DIBasicTypeAttr attr);
|
||||
llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr);
|
||||
llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr);
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
isOptimized = true, emissionKind = Full
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[VOID:.*]] = #llvm.di_void_result_type
|
||||
#void = #llvm.di_void_result_type
|
||||
|
||||
// CHECK-DAG: #[[INT0:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int0">
|
||||
#int0 = #llvm.di_basic_type<
|
||||
// Omit the optional sizeInBits and encoding parameters.
|
||||
@@ -53,15 +56,21 @@
|
||||
flags = "TypePassByReference|NonTrivial"
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, argumentTypes = #[[INT0]], #[[PTR0]], #[[PTR1]], #[[COMP0:.*]], #[[COMP1:.*]], #[[COMP2:.*]]>
|
||||
// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[VOID]], #[[INT0]], #[[PTR0]], #[[PTR1]], #[[COMP0:.*]], #[[COMP1:.*]], #[[COMP2:.*]]>
|
||||
#spType0 = #llvm.di_subroutine_type<
|
||||
callingConvention = DW_CC_normal, argumentTypes = #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2
|
||||
callingConvention = DW_CC_normal, types = #void, #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type<resultType = #[[INT1]], argumentTypes = #[[INT1]]>
|
||||
// CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type<types = #[[INT1]], #[[INT1]]>
|
||||
#spType1 = #llvm.di_subroutine_type<
|
||||
// Omit the optional callingConvention parameter.
|
||||
resultType = #int1, argumentTypes = #int1
|
||||
types = #int1, #int1
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[SPTYPE2:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
|
||||
#spType2 = #llvm.di_subroutine_type<
|
||||
// Omit the optional types parameter array.
|
||||
callingConvention = DW_CC_normal
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[SP0:.*]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[FILE]], name = "addr", linkageName = "addr", file = #[[FILE]], line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #[[SPTYPE0]]>
|
||||
@@ -77,22 +86,38 @@
|
||||
file = #file, subprogramFlags = "Definition", type = #spType1
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[SP2:.*]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[FILE]], name = "value", file = #[[FILE]], subprogramFlags = Definition, type = #[[SPTYPE2]]>
|
||||
#sp2 = #llvm.di_subprogram<
|
||||
// Omit the optional linkageName parameter.
|
||||
compileUnit = #cu, scope = #file, name = "value",
|
||||
file = #file, subprogramFlags = "Definition", type = #spType2
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[BLOCK0:.*]] = #llvm.di_lexical_block<scope = #[[SP0]], line = 1, column = 2>
|
||||
#block0 = #llvm.di_lexical_block<scope = #sp0, line = 1, column = 2>
|
||||
|
||||
// CHECK-DAG: #[[BLOCK1:.*]] = #llvm.di_lexical_block<scope = #[[SP1]]>
|
||||
#block1 = #llvm.di_lexical_block<scope = #sp1>
|
||||
|
||||
// CHECK-DAG: #[[BLOCK2:.*]] = #llvm.di_lexical_block<scope = #[[SP2]]>
|
||||
#block2 = #llvm.di_lexical_block<scope = #sp2>
|
||||
|
||||
// CHECK-DAG: #[[VAR0:.*]] = #llvm.di_local_variable<scope = #[[BLOCK0]], name = "alloc", file = #[[FILE]], line = 6, arg = 1, alignInBits = 32, type = #[[INT0]]>
|
||||
#var0 = #llvm.di_local_variable<
|
||||
scope = #block0, name = "alloc", file = #file,
|
||||
line = 6, arg = 1, alignInBits = 32, type = #int0
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable<scope = #[[BLOCK1]], name = "arg">
|
||||
// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable<scope = #[[BLOCK1]], name = "arg1">
|
||||
#var1 = #llvm.di_local_variable<
|
||||
// Omit the optional parameters.
|
||||
scope = #block1, name = "arg"
|
||||
scope = #block1, name = "arg1"
|
||||
>
|
||||
|
||||
// CHECK-DAG: #[[VAR2:.*]] = #llvm.di_local_variable<scope = #[[BLOCK2]], name = "arg2">
|
||||
#var2 = #llvm.di_local_variable<
|
||||
// Omit the optional parameters.
|
||||
scope = #block2, name = "arg2"
|
||||
>
|
||||
|
||||
// CHECK: llvm.func @addr(%[[ARG:.*]]: i64)
|
||||
@@ -108,9 +133,11 @@ llvm.func @addr(%arg: i64) {
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// CHECK: llvm.func @value(%[[ARG:.*]]: i32)
|
||||
llvm.func @value(%arg: i32) -> i32 {
|
||||
// CHECK: llvm.intr.dbg.value #[[VAR1]] = %[[ARG]]
|
||||
llvm.intr.dbg.value #var1 = %arg : i32
|
||||
llvm.return %arg : i32
|
||||
// CHECK: llvm.func @value(%[[ARG1:.*]]: i32, %[[ARG2:.*]]: i32)
|
||||
llvm.func @value(%arg1: i32, %arg2: i32) {
|
||||
// CHECK: llvm.intr.dbg.value #[[VAR1]] = %[[ARG1]]
|
||||
llvm.intr.dbg.value #var1 = %arg1 : i32
|
||||
// CHECK: llvm.intr.dbg.value #[[VAR2]] = %[[ARG2]]
|
||||
llvm.intr.dbg.value #var2 = %arg2 : i32
|
||||
llvm.return
|
||||
}
|
||||
|
||||
@@ -1392,3 +1392,9 @@ func.func @extract_scalable_from_fixed_length_vector(%arg0 : vector<16xf32>) {
|
||||
// expected-error@+1 {{op failed to verify that it is not extracting scalable from fixed-length vectors.}}
|
||||
%0 = llvm.intr.vector.extract %arg0[0] : vector<[8]xf32> from vector<16xf32>
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
#void = #llvm.di_void_result_type
|
||||
// expected-error@below {{expected subroutine to have non-void argument types}}
|
||||
#void_argument_type = #llvm.di_subroutine_type<types = #void, #void>
|
||||
|
||||
@@ -112,9 +112,10 @@ define i32 @lexical_block_file(i32 %arg1) {
|
||||
|
||||
; // -----
|
||||
|
||||
; CHECK: #[[INT1:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int1">
|
||||
; CHECK: #[[INT2:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int2", sizeInBits = 32, encoding = DW_ATE_signed>
|
||||
; CHECK: #llvm.di_subroutine_type<argumentTypes = #[[INT1]], #[[INT2]]>
|
||||
; CHECK-DAG: #[[VOID:.+]] = #llvm.di_void_result_type
|
||||
; CHECK-DAG: #[[INT1:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int1">
|
||||
; CHECK-DAG: #[[INT2:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int2", sizeInBits = 32, encoding = DW_ATE_signed>
|
||||
; CHECK-DAG: #llvm.di_subroutine_type<types = #[[VOID]], #[[INT1]], #[[INT2]]>
|
||||
|
||||
define void @basic_type() !dbg !3 {
|
||||
ret void
|
||||
@@ -136,7 +137,7 @@ define void @basic_type() !dbg !3 {
|
||||
; CHECK: #[[INT:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int">
|
||||
; CHECK: #[[PTR1:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[INT]]>
|
||||
; CHECK: #[[PTR2:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "mypointer", baseType = #[[INT]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4>
|
||||
; CHECK: #llvm.di_subroutine_type<argumentTypes = #[[PTR1]], #[[PTR2]]>
|
||||
; CHECK: #llvm.di_subroutine_type<types = #[[PTR1]], #[[PTR2]]>
|
||||
|
||||
define void @derived_type() !dbg !3 {
|
||||
ret void
|
||||
@@ -149,7 +150,7 @@ define void @derived_type() !dbg !3 {
|
||||
!2 = !DIFile(filename: "debug-info.ll", directory: "/")
|
||||
!3 = distinct !DISubprogram(name: "derived_type", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4)
|
||||
!4 = !DISubroutineType(types: !5)
|
||||
!5 = !{null, !7, !8}
|
||||
!5 = !{!7, !8}
|
||||
!6 = !DIBasicType(name: "int")
|
||||
!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6)
|
||||
!8 = !DIDerivedType(name: "mypointer", tag: DW_TAG_pointer_type, baseType: !6, size: 64, align: 32, offset: 4)
|
||||
@@ -162,7 +163,7 @@ define void @derived_type() !dbg !3 {
|
||||
; CHECK-DAG: #[[COMP2:.+]] = #llvm.di_composite_type<{{.*}}, file = #[[FILE]], scope = #[[FILE]], baseType = #[[INT]]>
|
||||
; CHECK-DAG: #[[COMP3:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange<count = 4 : i64>>
|
||||
; CHECK-DAG: #[[COMP4:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange<lowerBound = 0 : i64, upperBound = 4 : i64, stride = 1 : i64>>
|
||||
; CHECK-DAG: #llvm.di_subroutine_type<argumentTypes = #[[COMP1]], #[[COMP2]], #[[COMP3]], #[[COMP4]]>
|
||||
; CHECK-DAG: #llvm.di_subroutine_type<types = #[[COMP1]], #[[COMP2]], #[[COMP3]], #[[COMP4]]>
|
||||
|
||||
define void @composite_type() !dbg !3 {
|
||||
ret void
|
||||
@@ -175,7 +176,7 @@ define void @composite_type() !dbg !3 {
|
||||
!2 = !DIFile(filename: "debug-info.ll", directory: "/")
|
||||
!3 = distinct !DISubprogram(name: "composite_type", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4)
|
||||
!4 = !DISubroutineType(types: !5)
|
||||
!5 = !{null, !7, !8, !9, !10}
|
||||
!5 = !{!7, !8, !9, !10}
|
||||
!6 = !DIBasicType(name: "int")
|
||||
!7 = !DICompositeType(tag: DW_TAG_array_type, name: "array1", line: 10, size: 128, align: 32)
|
||||
!8 = !DICompositeType(tag: DW_TAG_array_type, name: "array2", file: !2, scope: !2, baseType: !6)
|
||||
@@ -188,11 +189,11 @@ define void @composite_type() !dbg !3 {
|
||||
|
||||
; // -----
|
||||
|
||||
; CHECK: #[[INT:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int">
|
||||
; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
|
||||
; CHECK: #[[CU:.+]] = #llvm.di_compile_unit<sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "", isOptimized = false, emissionKind = None>
|
||||
; CHECK: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, resultType = #[[INT]], argumentTypes = #[[INT]]>
|
||||
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[FILE]], name = "subprogram", linkageName = "subprogram", file = #[[FILE]], line = 42, scopeLine = 42, subprogramFlags = Definition, type = #[[SP_TYPE]]>
|
||||
; CHECK-DAG: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
|
||||
; CHECK-DAG: #[[CU:.+]] = #llvm.di_compile_unit<sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "", isOptimized = false, emissionKind = None>
|
||||
; Verify an empty subroutine types list is supported.
|
||||
; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
|
||||
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[FILE]], name = "subprogram", linkageName = "subprogram", file = #[[FILE]], line = 42, scopeLine = 42, subprogramFlags = Definition, type = #[[SP_TYPE]]>
|
||||
|
||||
define void @subprogram() !dbg !3 {
|
||||
ret void
|
||||
@@ -205,7 +206,7 @@ define void @subprogram() !dbg !3 {
|
||||
!2 = !DIFile(filename: "debug-info.ll", directory: "/")
|
||||
!3 = distinct !DISubprogram(name: "subprogram", linkageName: "subprogram", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1, type: !4)
|
||||
!4 = !DISubroutineType(cc: DW_CC_normal, types: !5)
|
||||
!5 = !{!6, !6}
|
||||
!5 = !{}
|
||||
!6 = !DIBasicType(name: "int")
|
||||
|
||||
; // -----
|
||||
|
||||
@@ -48,24 +48,31 @@ llvm.func @func_no_debug() {
|
||||
baseType = #si64, flags = Vector,
|
||||
elements = #llvm.di_subrange<lowerBound = 0, upperBound = 4, stride = 1>
|
||||
>
|
||||
#spType = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, argumentTypes = #si64, #ptr, #named, #composite, #vector>
|
||||
#sp = #llvm.di_subprogram<
|
||||
#void = #llvm.di_void_result_type
|
||||
#spType0 = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #void, #si64, #ptr, #named, #composite, #vector>
|
||||
#sp0 = #llvm.di_subprogram<
|
||||
compileUnit = #cu, scope = #file, name = "func_with_debug", linkageName = "func_with_debug",
|
||||
file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType
|
||||
file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType0
|
||||
>
|
||||
#calleeType = #llvm.di_subroutine_type<
|
||||
// Omit the optional callingConvention parameter but specify a result type.
|
||||
resultType = #si64, argumentTypes = #si64>
|
||||
// Omit the optional callingConvention parameter.
|
||||
types = #si64, #si64>
|
||||
#callee = #llvm.di_subprogram<
|
||||
// Omit the optional linkageName, line, and scopeLine parameters.
|
||||
compileUnit = #cu, scope = #composite, name = "callee",
|
||||
file = #file, subprogramFlags = "Definition", type = #calleeType
|
||||
>
|
||||
#fileScope = #llvm.di_lexical_block_file<scope = #sp, file = #file, discriminator = 0>
|
||||
#blockScope = #llvm.di_lexical_block<scope = #sp>
|
||||
#fileScope = #llvm.di_lexical_block_file<scope = #sp0, file = #file, discriminator = 0>
|
||||
#blockScope = #llvm.di_lexical_block<scope = #sp0>
|
||||
#variable = #llvm.di_local_variable<scope = #fileScope, name = "arg", file = #file, line = 6, arg = 1, alignInBits = 32, type = #si64>
|
||||
#variableAddr = #llvm.di_local_variable<scope = #blockScope, name = "alloc">
|
||||
|
||||
#spType1 = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
|
||||
#sp1 = #llvm.di_subprogram<
|
||||
compileUnit = #cu, scope = #file, name = "empty_types",
|
||||
file = #file, subprogramFlags = "Definition", type = #spType1
|
||||
>
|
||||
|
||||
// CHECK-LABEL: define void @func_with_debug(
|
||||
// CHECK-SAME: i64 %[[ARG:.*]]) !dbg ![[FUNC_LOC:[0-9]+]]
|
||||
llvm.func @func_with_debug(%arg: i64) {
|
||||
@@ -93,10 +100,15 @@ llvm.func @func_with_debug(%arg: i64) {
|
||||
llvm.call @func_no_debug() : () -> () loc(fused[callsite("mysource.cc":5:6 at "mysource.cc":1:1), "mysource.cc":1:1])
|
||||
|
||||
// CHECK: add i64 %[[ARG]], %[[ARG]], !dbg ![[FUSEDWITH_LOC:[0-9]+]]
|
||||
%sum = llvm.add %arg, %arg : i64 loc(fused<#callee>[callsite("foo.mlir":2:4 at fused<#sp>["foo.mlir":28:5])])
|
||||
%sum = llvm.add %arg, %arg : i64 loc(fused<#callee>[callsite("foo.mlir":2:4 at fused<#sp0>["foo.mlir":28:5])])
|
||||
|
||||
llvm.return
|
||||
} loc(fused<#sp>["foo.mlir":1:1])
|
||||
} loc(fused<#sp0>["foo.mlir":1:1])
|
||||
|
||||
// CHECK: define void @empty_types() !dbg ![[EMPTY_TYPES_LOC:[0-9]+]]
|
||||
llvm.func @empty_types() {
|
||||
llvm.return
|
||||
} loc(fused<#sp1>["foo.mlir":2:1])
|
||||
|
||||
// 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/")
|
||||
@@ -131,3 +143,7 @@ llvm.func @func_with_debug(%arg: i64) {
|
||||
// CHECK: ![[CALLEE_TYPE]] = !DISubroutineType(types: ![[CALLEE_ARGS:.*]])
|
||||
// CHECK: ![[CALLEE_ARGS]] = !{![[ARG_TYPE:.*]], ![[ARG_TYPE:.*]]}
|
||||
// CHECK: ![[INLINE_LOC]] = !DILocation(line: 28, column: 5,
|
||||
|
||||
// CHECK: ![[EMPTY_TYPES_LOC]] = distinct !DISubprogram(name: "empty_types", scope: ![[CU_FILE_LOC]], file: ![[CU_FILE_LOC]], type: ![[EMPTY_TYPES_TYPE:.*]], spFlags: DISPFlagDefinition
|
||||
// CHECK: ![[EMPTY_TYPES_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[EMPTY_TYPES_ARGS:.*]])
|
||||
// CHECK: ![[EMPTY_TYPES_ARGS]] = !{}
|
||||
|
||||
Reference in New Issue
Block a user