Index: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h +++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h @@ -126,6 +126,7 @@ md_noalias, md_range, md_diexpr, + md_dilocation, // Identifier tokens Identifier, Index: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp @@ -576,6 +576,7 @@ .Case("!noalias", MIToken::md_noalias) .Case("!range", MIToken::md_range) .Case("!DIExpression", MIToken::md_diexpr) + .Case("!DILocation", MIToken::md_dilocation) .Default(MIToken::Error); } Index: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp @@ -226,6 +226,7 @@ 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 @@ 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(Node)) return error("referenced metadata is not a DILocation"); DebugLocation = DebugLoc(Node); @@ -898,6 +903,9 @@ } 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 @@ 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(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(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)) { Index: llvm/trunk/lib/IR/AsmWriter.cpp =================================================================== --- llvm/trunk/lib/IR/AsmWriter.cpp +++ llvm/trunk/lib/IR/AsmWriter.cpp @@ -2294,11 +2294,15 @@ Machine = MachineStorage.get(); } int Slot = Machine->getMetadataSlot(N); - if (Slot == -1) + if (Slot == -1) { + if (const DILocation *Loc = dyn_cast(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; } Index: llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir =================================================================== --- llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir +++ llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir @@ -41,9 +41,9 @@ # 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]] Index: llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir +++ llvm/trunk/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 @@ $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 +...