diff options
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.h | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 119 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/packetize-debug-loc.mir | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir | 41 |
6 files changed, 166 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index f7cc94e34a5..6d6d5517379 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -576,6 +576,7 @@ static MIToken::TokenKind getMetadataKeywordKind(StringRef Identifier) { .Case("!noalias", MIToken::md_noalias) .Case("!range", MIToken::md_range) .Case("!DIExpression", MIToken::md_diexpr) + .Case("!DILocation", MIToken::md_dilocation) .Default(MIToken::Error); } diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index dffa4f74544..a52f6206fb7 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -126,6 +126,7 @@ struct MIToken { md_noalias, md_range, md_diexpr, + md_dilocation, // Identifier tokens Identifier, diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 1a6174bf9ee..16cade09f21 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -226,6 +226,7 @@ public: bool parseMCSymbolOperand(MachineOperand &Dest); bool parseMDNode(MDNode *&Node); bool parseDIExpression(MDNode *&Expr); + bool parseDILocation(MDNode *&Expr); bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIRegister(unsigned &Reg); @@ -776,11 +777,15 @@ bool MIParser::parse(MachineInstr *&MI) { DebugLoc DebugLocation; if (Token.is(MIToken::kw_debug_location)) { lex(); - if (Token.isNot(MIToken::exclaim)) - return error("expected a metadata node after 'debug-location'"); MDNode *Node = nullptr; - if (parseMDNode(Node)) - return true; + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(Node)) + return true; + } else if (Token.is(MIToken::md_dilocation)) { + if (parseDILocation(Node)) + return true; + } else + return error("expected a metadata node after 'debug-location'"); if (!isa<DILocation>(Node)) return error("referenced metadata is not a DILocation"); DebugLocation = DebugLoc(Node); @@ -898,6 +903,9 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) { } else if (Token.is(MIToken::md_diexpr)) { if (parseDIExpression(Node)) return true; + } else if (Token.is(MIToken::md_dilocation)) { + if (parseDILocation(Node)) + return true; } else return error("expected a metadata node"); if (Token.isNot(MIToken::Eof)) @@ -1684,6 +1692,109 @@ bool MIParser::parseDIExpression(MDNode *&Expr) { return false; } +bool MIParser::parseDILocation(MDNode *&Loc) { + assert(Token.is(MIToken::md_dilocation)); + lex(); + + bool HaveLine = false; + unsigned Line = 0; + unsigned Column = 0; + MDNode *Scope = nullptr; + MDNode *InlinedAt = nullptr; + bool ImplicitCode; + + if (expectAndConsume(MIToken::lparen)) + return true; + + if (Token.isNot(MIToken::rparen)) { + do { + if (Token.is(MIToken::Identifier)) { + if (Token.stringValue() == "line") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.isNot(MIToken::IntegerLiteral) || + Token.integerValue().isSigned()) + return error("expected unsigned integer"); + Line = Token.integerValue().getZExtValue(); + HaveLine = true; + lex(); + continue; + } + if (Token.stringValue() == "column") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.isNot(MIToken::IntegerLiteral) || + Token.integerValue().isSigned()) + return error("expected unsigned integer"); + Column = Token.integerValue().getZExtValue(); + lex(); + continue; + } + if (Token.stringValue() == "scope") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (parseMDNode(Scope)) + return error("expected metadata node"); + if (!isa<DIScope>(Scope)) + return error("expected DIScope node"); + continue; + } + if (Token.stringValue() == "inlinedAt") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(InlinedAt)) + return true; + } else if (Token.is(MIToken::md_dilocation)) { + if (parseDILocation(InlinedAt)) + return true; + } else + return error("expected metadata node"); + if (!isa<DILocation>(InlinedAt)) + return error("expected DILocation node"); + continue; + } + if (Token.stringValue() == "isImplicitCode") { + lex(); + if (expectAndConsume(MIToken::colon)) + return true; + if (!Token.is(MIToken::Identifier)) + return error("expected true/false"); + // As far as I can see, we don't have any existing need for parsing + // true/false in MIR yet. Do it ad-hoc until there's something else + // that needs it. + if (Token.stringValue() == "true") + ImplicitCode = true; + else if (Token.stringValue() == "false") + ImplicitCode = false; + else + return error("expected true/false"); + lex(); + continue; + } + } + return error(Twine("invalid DILocation argument '") + + Token.stringValue() + "'"); + } while (consumeIfPresent(MIToken::comma)); + } + + if (expectAndConsume(MIToken::rparen)) + return true; + + if (!HaveLine) + return error("DILocation requires line number"); + if (!Scope) + return error("DILocation requires a scope"); + + Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope, + InlinedAt, ImplicitCode); + return false; +} + bool MIParser::parseMetadataOperand(MachineOperand &Dest) { MDNode *Node = nullptr; if (Token.is(MIToken::exclaim)) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 23aee723205..36f4f3aa876 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2294,11 +2294,15 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, Machine = MachineStorage.get(); } int Slot = Machine->getMetadataSlot(N); - if (Slot == -1) + if (Slot == -1) { + if (const DILocation *Loc = dyn_cast<DILocation>(N)) { + writeDILocation(Out, Loc, TypePrinter, Machine, Context); + return; + } // Give the pointer value instead of "badref", since this comes up all // the time when debugging. Out << "<" << N << ">"; - else + } else Out << '!' << Slot; return; } diff --git a/llvm/test/CodeGen/Hexagon/packetize-debug-loc.mir b/llvm/test/CodeGen/Hexagon/packetize-debug-loc.mir index 9bcc5ba0693..f86fb05ac67 100644 --- a/llvm/test/CodeGen/Hexagon/packetize-debug-loc.mir +++ b/llvm/test/CodeGen/Hexagon/packetize-debug-loc.mir @@ -41,9 +41,9 @@ body: | # CHECK-LABEL: name: test # CHECK: BUNDLE -# CHECK-SAME: debug-location [[DL1:[0-9x<>]+]] +# CHECK-SAME: debug-location [[DL1:!DILocation([^)]+)]] # CHECK-NEXT: L2_loadri_io $r1, 0, debug-location [[DL1]] -# CHECK-NEXT: L2_loadri_io $r1, 0, debug-location [[DL2:[0-9x<>]+]] +# CHECK-NEXT: L2_loadri_io $r1, 0, debug-location [[DL2:!DILocation([^)]+)]] # CHECK: BUNDLE # CHECK-SAME: debug-location [[DL1]] diff --git a/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir b/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir index 8b6c5cbf526..fe74f5c0535 100644 --- a/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir +++ b/llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir @@ -22,6 +22,17 @@ ret i32 %0, !dbg !14 } + define i32 @test_mir_created(i32 %x) #0 !dbg !15 { + entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + %0 = load i32, i32* %x.addr, align 4 + %1 = load i32, i32* %x.addr, align 4 + %2 = load i32, i32* %x.addr, align 4 + %3 = load i32, i32* %x.addr, align 4 + ret i32 %0, !dbg !16 + } + declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 attributes #0 = { nounwind "no-frame-pointer-elim"="false" } @@ -45,6 +56,8 @@ !12 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 4, type: !8) !13 = !DILocation(line: 4, scope: !4) !14 = !DILocation(line: 8, scope: !4) + !15 = distinct !DISubprogram(name: "test_mir_created", scope: !5, file: !5, line: 10, type: !6, isLocal: false, isDefinition: true, scopeLine: 10, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) + !16 = !DILocation(line: 20, scope: !15) ... --- @@ -96,3 +109,31 @@ body: | $eax = COPY %0 RETQ $eax ... +--- +name: test_mir_created +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + maxAlignment: 4 +stack: + - { id: 0, name: x.addr, size: 4, alignment: 4 } +body: | + bb.0.entry: + liveins: $edi + + %0 = COPY $edi + ; CHECK-LABEL: name: test_mir_created + ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 1, scope: !14) + ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 2, column: 2, scope: !14) + ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 3, column: 2, scope: !14, isImplicitCode: true) + ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 4, scope: !14, inlinedAt: !15) + ; CHECK: MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0, debug-location !DILocation(line: 5, scope: !14, inlinedAt: !DILocation(line: 4, scope: !14)) + MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 1, scope: !15) + MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 2, column: 2, scope: !15) + MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 3, column: 2, scope: !15, isImplicitCode: true) + MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 4, scope: !15, inlinedAt: !16) + MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 5, scope: !15, inlinedAt: !DILocation(line: 4, scope: !15)) + $eax = COPY %0 + RETQ $eax +... |