From 03c5b6047eeedbfc10ca3626934c463cdb9e6abf Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 22 Jul 2015 17:58:46 +0000 Subject: [PATCH] MIR Serialization: Serialize the metadata machine operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242916 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MIRParser/MILexer.cpp | 2 + lib/CodeGen/MIRParser/MILexer.h | 1 + lib/CodeGen/MIRParser/MIParser.cpp | 20 ++++++ lib/CodeGen/MIRPrinter.cpp | 3 + .../expected-metadata-node-after-exclaim.mir | 61 ++++++++++++++++++ test/CodeGen/MIR/X86/metadata-operands.mir | 64 +++++++++++++++++++ .../CodeGen/MIR/X86/unknown-metadata-node.mir | 61 ++++++++++++++++++ 7 files changed, 212 insertions(+) create mode 100644 test/CodeGen/MIR/X86/expected-metadata-node-after-exclaim.mir create mode 100644 test/CodeGen/MIR/X86/metadata-operands.mir create mode 100644 test/CodeGen/MIR/X86/unknown-metadata-node.mir diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index c88333e6f59..6c3d2e064ac 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -310,6 +310,8 @@ static MIToken::TokenKind symbolToken(char C) { return MIToken::equal; case ':': return MIToken::colon; + case '!': + return MIToken::exclaim; default: return MIToken::Error; } diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index 771f6047e5c..79972bbc533 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -36,6 +36,7 @@ struct MIToken { equal, underscore, colon, + exclaim, // Keywords kw_implicit, diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 498ca0615d5..212996bfaf5 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -112,6 +112,7 @@ public: bool parseConstantPoolIndexOperand(MachineOperand &Dest); bool parseJumpTableIndexOperand(MachineOperand &Dest); bool parseExternalSymbolOperand(MachineOperand &Dest); + bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest); @@ -575,6 +576,23 @@ bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseMetadataOperand(MachineOperand &Dest) { + assert(Token.is(MIToken::exclaim)); + auto Loc = Token.location(); + lex(); + if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) + return error("expected metadata id after '!'"); + unsigned ID; + if (getUnsigned(ID)) + return true; + auto NodeInfo = IRSlots.MetadataNodes.find(ID); + if (NodeInfo == IRSlots.MetadataNodes.end()) + return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'"); + lex(); + Dest = MachineOperand::CreateMetadata(NodeInfo->second.get()); + return false; +} + bool MIParser::parseCFIOffset(int &Offset) { if (Token.isNot(MIToken::IntegerLiteral)) return error("expected a cfi offset"); @@ -628,6 +646,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { case MIToken::ExternalSymbol: case MIToken::QuotedExternalSymbol: return parseExternalSymbolOperand(Dest); + case MIToken::exclaim: + return parseMetadataOperand(Dest); case MIToken::kw_cfi_def_cfa_offset: return parseCFIOperand(Dest); case MIToken::Error: diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index 08eafb6f0ec..a789237eca1 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -453,6 +453,9 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { llvm_unreachable("Can't print this machine register mask yet."); break; } + case MachineOperand::MO_Metadata: + Op.getMetadata()->printAsOperand(OS, MST); + break; case MachineOperand::MO_CFIIndex: { const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); print(MMI.getFrameInstructions()[Op.getCFIIndex()]); diff --git a/test/CodeGen/MIR/X86/expected-metadata-node-after-exclaim.mir b/test/CodeGen/MIR/X86/expected-metadata-node-after-exclaim.mir new file mode 100644 index 00000000000..8cbce13b0c0 --- /dev/null +++ b/test/CodeGen/MIR/X86/expected-metadata-node-after-exclaim.mir @@ -0,0 +1,61 @@ +# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define i32 @test(i32 %x) #0 { + entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %x.addr, metadata !12, metadata !13), !dbg !14 + %0 = load i32, i32* %x.addr, align 4, !dbg !15 + ret i32 %0, !dbg !15 + } + + declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + + attributes #0 = { nounwind "no-frame-pointer-elim"="false" } + attributes #1 = { nounwind readnone } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!9, !10} + !llvm.ident = !{!11} + + !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) + !1 = !DIFile(filename: "test.ll", directory: "") + !2 = !{} + !3 = !{!4} + !4 = !DISubprogram(name: "test", scope: !5, file: !5, line: 4, type: !6, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, function: i32 (i32)* @test, variables: !2) + !5 = !DIFile(filename: "test.c", directory: "") + !6 = !DISubroutineType(types: !7) + !7 = !{!8, !8} + !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) + !9 = !{i32 2, !"Dwarf Version", i32 4} + !10 = !{i32 2, !"Debug Info Version", i32 3} + !11 = !{!"clang version 3.7.0"} + !12 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "x", arg: 1, scope: !4, file: !5, line: 4, type: !8) + !13 = !DIExpression() + !14 = !DILocation(line: 4, scope: !4) + !15 = !DILocation(line: 8, scope: !4) + +... +--- +name: test +isSSA: true +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + maxAlignment: 4 +stack: + - { id: 0, name: x.addr, size: 4, alignment: 4 } +body: + - id: 0 + name: entry + instructions: + - '%0 = COPY %edi' + # CHECK: [[@LINE+1]]:33: expected metadata id after '!' + - 'DBG_VALUE _, 0, !12, ! _' + - 'MOV32mr %stack.0.x.addr, 1, _, 0, _, %0' + - '%eax = COPY %0' + - 'RETQ %eax' +... diff --git a/test/CodeGen/MIR/X86/metadata-operands.mir b/test/CodeGen/MIR/X86/metadata-operands.mir new file mode 100644 index 00000000000..36f0ad86666 --- /dev/null +++ b/test/CodeGen/MIR/X86/metadata-operands.mir @@ -0,0 +1,64 @@ +# RUN: llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s | FileCheck %s +# This test ensures that the MIR parser parses the metadata machine operands +# correctly. + +--- | + + define i32 @test(i32 %x) #0 { + entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %x.addr, metadata !12, metadata !13), !dbg !14 + %0 = load i32, i32* %x.addr, align 4, !dbg !15 + ret i32 %0, !dbg !15 + } + + declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + + attributes #0 = { nounwind "no-frame-pointer-elim"="false" } + attributes #1 = { nounwind readnone } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!9, !10} + !llvm.ident = !{!11} + + !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) + !1 = !DIFile(filename: "test.ll", directory: "") + !2 = !{} + !3 = !{!4} + !4 = !DISubprogram(name: "test", scope: !5, file: !5, line: 4, type: !6, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, function: i32 (i32)* @test, variables: !2) + !5 = !DIFile(filename: "test.c", directory: "") + !6 = !DISubroutineType(types: !7) + !7 = !{!8, !8} + !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) + !9 = !{i32 2, !"Dwarf Version", i32 4} + !10 = !{i32 2, !"Debug Info Version", i32 3} + !11 = !{!"clang version 3.7.0"} + !12 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "x", arg: 1, scope: !4, file: !5, line: 4, type: !8) + !13 = !DIExpression() + !14 = !DILocation(line: 4, scope: !4) + !15 = !DILocation(line: 8, scope: !4) + +... +--- +name: test +isSSA: true +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + maxAlignment: 4 +stack: + - { id: 0, name: x.addr, size: 4, alignment: 4 } +body: + - id: 0 + name: entry + instructions: + # CHECK: %0 = COPY %edi + # CHECK-NEXT: DBG_VALUE _, 0, !12, !13 + - '%0 = COPY %edi' + - 'DBG_VALUE _, 0, !12, ! 13' + - 'MOV32mr %stack.0.x.addr, 1, _, 0, _, %0' + - '%eax = COPY %0' + - 'RETQ %eax' +... diff --git a/test/CodeGen/MIR/X86/unknown-metadata-node.mir b/test/CodeGen/MIR/X86/unknown-metadata-node.mir new file mode 100644 index 00000000000..194537fa8e2 --- /dev/null +++ b/test/CodeGen/MIR/X86/unknown-metadata-node.mir @@ -0,0 +1,61 @@ +# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define i32 @test(i32 %x) #0 { + entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %x.addr, metadata !12, metadata !13), !dbg !14 + %0 = load i32, i32* %x.addr, align 4, !dbg !15 + ret i32 %0, !dbg !15 + } + + declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + + attributes #0 = { nounwind "no-frame-pointer-elim"="false" } + attributes #1 = { nounwind readnone } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!9, !10} + !llvm.ident = !{!11} + + !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) + !1 = !DIFile(filename: "test.ll", directory: "") + !2 = !{} + !3 = !{!4} + !4 = !DISubprogram(name: "test", scope: !5, file: !5, line: 4, type: !6, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, function: i32 (i32)* @test, variables: !2) + !5 = !DIFile(filename: "test.c", directory: "") + !6 = !DISubroutineType(types: !7) + !7 = !{!8, !8} + !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) + !9 = !{i32 2, !"Dwarf Version", i32 4} + !10 = !{i32 2, !"Debug Info Version", i32 3} + !11 = !{!"clang version 3.7.0"} + !12 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "x", arg: 1, scope: !4, file: !5, line: 4, type: !8) + !13 = !DIExpression() + !14 = !DILocation(line: 4, scope: !4) + !15 = !DILocation(line: 8, scope: !4) + +... +--- +name: test +isSSA: true +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + maxAlignment: 4 +stack: + - { id: 0, name: x.addr, size: 4, alignment: 4 } +body: + - id: 0 + name: entry + instructions: + - '%0 = COPY %edi' + # CHECK: [[@LINE+1]]:26: use of undefined metadata '!42' + - 'DBG_VALUE _, 0, !42, !13' + - 'MOV32mr %stack.0.x.addr, 1, _, 0, _, %0' + - '%eax = COPY %0' + - 'RETQ %eax' +... -- 2.34.1