From 81f57b6b994907267e981e09c1789529ec0a91c9 Mon Sep 17 00:00:00 2001 From: Tobias Gysi Date: Thu, 12 Jan 2023 18:50:56 +0100 Subject: [PATCH] Revert "[mlir][llvm] Add an explicit void type debug info attribute." This commit broke the flang build bots https://lab.llvm.org/buildbot#builders/175/builds/23560. This reverts commit a960547ea12128a67c99760f57bf01609a265546. --- mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 18 +++------ mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp | 30 ++++----------- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 8 ++-- mlir/lib/Target/LLVMIR/DebugImporter.cpp | 20 ++++------ mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 20 +++------- mlir/lib/Target/LLVMIR/DebugTranslation.h | 1 - mlir/test/Dialect/LLVMIR/debuginfo.mlir | 49 ++++++------------------ mlir/test/Dialect/LLVMIR/invalid.mlir | 6 --- mlir/test/Target/LLVMIR/Import/debug-info.ll | 27 +++++++------ mlir/test/Target/LLVMIR/llvmir-debug.mlir | 34 +++++----------- 10 files changed, 63 insertions(+), 150 deletions(-) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 733d573..f38558c 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -123,15 +123,6 @@ def LLVM_DITagParameter : LLVM_DIParameter< >; //===----------------------------------------------------------------------===// -// DIVoidResultTypeAttr -//===----------------------------------------------------------------------===// - -def LLVM_DIVoidResultTypeAttr : LLVM_Attr<"DIVoidResultType", "di_void_result_type", - /*traits=*/[], "DITypeAttr"> { - let parameters = (ins); -} - -//===----------------------------------------------------------------------===// // DIBasicTypeAttr //===----------------------------------------------------------------------===// @@ -362,15 +353,16 @@ def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_typ ], "DITypeAttr"> { let parameters = (ins LLVM_DICallingConventionParameter:$callingConvention, - OptionalArrayRefParameter<"DITypeAttr">:$types + OptionalParameter<"DITypeAttr">:$resultType, + OptionalArrayRefParameter<"DITypeAttr">:$argumentTypes ); let builders = [ - TypeBuilder<(ins "ArrayRef":$types), [{ - return $_get($_ctxt, /*callingConvention=*/0, types); + TypeBuilder<(ins "DITypeAttr":$resultType, + "ArrayRef":$argumentTypes), [{ + return $_get($_ctxt, /*callingConvention=*/0, resultType, argumentTypes); }]> ]; let assemblyFormat = "`<` struct(params) `>`"; - let genVerifyDecl = 1; } #endif // LLVMIR_ATTRDEFS diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index 83e040a..2bf1cab 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -14,7 +14,6 @@ #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" @@ -42,11 +41,11 @@ void LLVMDialect::registerAttributes() { //===----------------------------------------------------------------------===// bool DINodeAttr::classof(Attribute attr) { - return llvm::isa(attr); + return llvm::isa( + attr); } //===----------------------------------------------------------------------===// @@ -64,23 +63,8 @@ bool DIScopeAttr::classof(Attribute attr) { //===----------------------------------------------------------------------===// bool DITypeAttr::classof(Attribute attr) { - return llvm::isa(attr); -} - -//===----------------------------------------------------------------------===// -// DISubroutineTypeAttr -//===----------------------------------------------------------------------===// - -LogicalResult -DISubroutineTypeAttr::verify(function_ref emitError, - unsigned int callingConventions, - ArrayRef types) { - if (llvm::any_of(llvm::drop_begin(types), [](DITypeAttr type) { - return type.isa(); - })) - return emitError() << "expected subroutine to have non-void argument types"; - return success(); + return llvm::isa(attr); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index 505addf..bb47aeb 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -2810,10 +2810,10 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface { AliasResult getAlias(Attribute attr, raw_ostream &os) const override { return TypeSwitch(attr) - .Case([&](auto attr) { + .Case([&](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 343ec92..dac737d 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -129,19 +129,15 @@ DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) { DISubroutineTypeAttr DebugImporter::translateImpl(llvm::DISubroutineType *node) { - SmallVector 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)); + // Separate the result type since it is null for void functions. + DITypeAttr resultType = translate(*node->getTypeArray().begin()); + SmallVector argumentTypes; + for (llvm::DIType *type : llvm::drop_begin(node->getTypeArray())) { + assert(type && "expected a non-null argument type"); + argumentTypes.push_back(translate(type)); } - return DISubroutineTypeAttr::get(context, node->getCC(), types); + return DISubroutineTypeAttr::get(context, node->getCC(), resultType, + argumentTypes); } DITypeAttr DebugImporter::translateImpl(llvm::DIType *node) { diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index 96f8880..2423e95 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -88,14 +88,6 @@ 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(), @@ -209,8 +201,8 @@ llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) { llvm::DISubroutineType * DebugTranslation::translateImpl(DISubroutineTypeAttr attr) { // Concatenate the result and argument types into a single array. - SmallVector types; - for (DITypeAttr type : attr.getTypes()) + SmallVector types = {translate(attr.getResultType())}; + for (DITypeAttr type : attr.getArgumentTypes()) types.push_back(translate(type)); return llvm::DISubroutineType::get( llvmCtx, llvm::DINode::FlagZero, attr.getCallingConvention(), @@ -230,10 +222,10 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) { llvm::DINode *node = TypeSwitch(attr) - .Case( + .Case( [&](auto attr) { return translateImpl(attr); }); attrToNode.insert({attr, node}); return node; diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h index f9c87ba..79f1326 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -61,7 +61,6 @@ 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); diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir index 4e13c5e..ff03643 100644 --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -9,9 +9,6 @@ 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 #int0 = #llvm.di_basic_type< // Omit the optional sizeInBits and encoding parameters. @@ -56,21 +53,15 @@ flags = "TypePassByReference|NonTrivial" > -// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type +// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type #spType0 = #llvm.di_subroutine_type< - callingConvention = DW_CC_normal, types = #void, #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2 + callingConvention = DW_CC_normal, argumentTypes = #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2 > -// CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type +// CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type #spType1 = #llvm.di_subroutine_type< // Omit the optional callingConvention parameter. - types = #int1, #int1 -> - -// CHECK-DAG: #[[SPTYPE2:.*]] = #llvm.di_subroutine_type -#spType2 = #llvm.di_subroutine_type< - // Omit the optional types parameter array. - callingConvention = DW_CC_normal + resultType = #int1, argumentTypes = #int1 > // CHECK-DAG: #[[SP0:.*]] = #llvm.di_subprogram @@ -86,38 +77,22 @@ file = #file, subprogramFlags = "Definition", type = #spType1 > -// CHECK-DAG: #[[SP2:.*]] = #llvm.di_subprogram -#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 #block0 = #llvm.di_lexical_block // CHECK-DAG: #[[BLOCK1:.*]] = #llvm.di_lexical_block #block1 = #llvm.di_lexical_block -// CHECK-DAG: #[[BLOCK2:.*]] = #llvm.di_lexical_block -#block2 = #llvm.di_lexical_block - // CHECK-DAG: #[[VAR0:.*]] = #llvm.di_local_variable #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 +// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable #var1 = #llvm.di_local_variable< // Omit the optional parameters. - scope = #block1, name = "arg1" -> - -// CHECK-DAG: #[[VAR2:.*]] = #llvm.di_local_variable -#var2 = #llvm.di_local_variable< - // Omit the optional parameters. - scope = #block2, name = "arg2" + scope = #block1, name = "arg" > // CHECK: llvm.func @addr(%[[ARG:.*]]: i64) @@ -133,11 +108,9 @@ llvm.func @addr(%arg: i64) { llvm.return } -// 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 +// 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 } diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir index e863bd3..1a50afa 100644 --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -1392,9 +1392,3 @@ 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 diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 2888b7a..4a8a43b 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -112,10 +112,9 @@ define i32 @lexical_block_file(i32 %arg1) { ; // ----- -; CHECK-DAG: #[[VOID:.+]] = #llvm.di_void_result_type -; CHECK-DAG: #[[INT1:.+]] = #llvm.di_basic_type -; CHECK-DAG: #[[INT2:.+]] = #llvm.di_basic_type -; CHECK-DAG: #llvm.di_subroutine_type +; CHECK: #[[INT1:.+]] = #llvm.di_basic_type +; CHECK: #[[INT2:.+]] = #llvm.di_basic_type +; CHECK: #llvm.di_subroutine_type define void @basic_type() !dbg !3 { ret void @@ -137,7 +136,7 @@ define void @basic_type() !dbg !3 { ; CHECK: #[[INT:.+]] = #llvm.di_basic_type ; CHECK: #[[PTR1:.+]] = #llvm.di_derived_type ; CHECK: #[[PTR2:.+]] = #llvm.di_derived_type -; CHECK: #llvm.di_subroutine_type +; CHECK: #llvm.di_subroutine_type define void @derived_type() !dbg !3 { ret void @@ -150,7 +149,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 = !{!7, !8} +!5 = !{null, !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) @@ -163,7 +162,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> ; CHECK-DAG: #[[COMP4:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange> -; CHECK-DAG: #llvm.di_subroutine_type +; CHECK-DAG: #llvm.di_subroutine_type define void @composite_type() !dbg !3 { ret void @@ -176,7 +175,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 = !{!7, !8, !9, !10} +!5 = !{null, !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) @@ -189,11 +188,11 @@ define void @composite_type() !dbg !3 { ; // ----- -; CHECK-DAG: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> -; CHECK-DAG: #[[CU:.+]] = #llvm.di_compile_unit -; Verify an empty subroutine types list is supported. -; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type -; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram +; CHECK: #[[INT:.+]] = #llvm.di_basic_type +; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> +; CHECK: #[[CU:.+]] = #llvm.di_compile_unit +; CHECK: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type +; CHECK: #[[SP:.+]] = #llvm.di_subprogram define void @subprogram() !dbg !3 { ret void @@ -206,7 +205,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 = !{} +!5 = !{!6, !6} !6 = !DIBasicType(name: "int") ; // ----- diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index 50d18eb..434207e 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -48,31 +48,24 @@ llvm.func @func_no_debug() { baseType = #si64, flags = Vector, elements = #llvm.di_subrange > -#void = #llvm.di_void_result_type -#spType0 = #llvm.di_subroutine_type -#sp0 = #llvm.di_subprogram< +#spType = #llvm.di_subroutine_type +#sp = #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 = #spType0 + file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType > #calleeType = #llvm.di_subroutine_type< - // Omit the optional callingConvention parameter. - types = #si64, #si64> + // Omit the optional callingConvention parameter but specify a result type. + resultType = #si64, argumentTypes = #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 -#blockScope = #llvm.di_lexical_block +#fileScope = #llvm.di_lexical_block_file +#blockScope = #llvm.di_lexical_block #variable = #llvm.di_local_variable #variableAddr = #llvm.di_local_variable -#spType1 = #llvm.di_subroutine_type -#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) { @@ -100,15 +93,10 @@ 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<#sp0>["foo.mlir":28:5])]) + %sum = llvm.add %arg, %arg : i64 loc(fused<#callee>[callsite("foo.mlir":2:4 at fused<#sp>["foo.mlir":28:5])]) llvm.return -} 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]) +} loc(fused<#sp>["foo.mlir":1: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/") @@ -143,7 +131,3 @@ llvm.func @empty_types() { // 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]] = !{} -- 2.7.4