[llvm] r349035 - [mir] Serialize DILocation inline when not possible to use a metadata reference

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 13 06:25:27 PST 2018


Author: dsanders
Date: Thu Dec 13 06:25:27 2018
New Revision: 349035

URL: http://llvm.org/viewvc/llvm-project?rev=349035&view=rev
Log:
[mir] Serialize DILocation inline when not possible to use a metadata reference

Summary:
Sometimes MIR-level passes create DILocations that were not present in the
LLVM-IR. For example, it may merge two DILocations together to produce a
DILocation that points to line 0.

Previously, the address of these DILocations were printed which prevented the
MIR from being read back into LLVM. With this patch, DILocations will use
metadata references where possible and fall back on serializing them inline like so:
    MOV32mr %stack.0.x.addr, 1, _, 0, _, %0, debug-location !DILocation(line: 1, scope: !15)

Reviewers: aprantl, vsk, arphaman

Reviewed By: aprantl

Subscribers: probinson, llvm-commits

Tags: #debug-info

Differential Revision: https://reviews.llvm.org/D55243

Modified:
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/IR/AsmWriter.cpp
    llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir
    llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp?rev=349035&r1=349034&r2=349035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Thu Dec 13 06:25:27 2018
@@ -576,6 +576,7 @@ static MIToken::TokenKind getMetadataKey
       .Case("!noalias", MIToken::md_noalias)
       .Case("!range", MIToken::md_range)
       .Case("!DIExpression", MIToken::md_diexpr)
+      .Case("!DILocation", MIToken::md_dilocation)
       .Default(MIToken::Error);
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=349035&r1=349034&r2=349035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Thu Dec 13 06:25:27 2018
@@ -126,6 +126,7 @@ struct MIToken {
     md_noalias,
     md_range,
     md_diexpr,
+    md_dilocation,
 
     // Identifier tokens
     Identifier,

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=349035&r1=349034&r2=349035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Thu Dec 13 06:25:27 2018
@@ -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(MDN
   } 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
   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)) {

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=349035&r1=349034&r2=349035&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Thu Dec 13 06:25:27 2018
@@ -2294,11 +2294,15 @@ static void WriteAsOperandInternal(raw_o
       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;
   }

Modified: llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir?rev=349035&r1=349034&r2=349035&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir (original)
+++ llvm/trunk/test/CodeGen/Hexagon/packetize-debug-loc.mir Thu Dec 13 06:25:27 2018
@@ -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]]

Modified: llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir?rev=349035&r1=349034&r2=349035&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/X86/instructions-debug-location.mir Thu Dec 13 06:25:27 2018
@@ -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
+...




More information about the llvm-commits mailing list