[llvm] r245396 - MIR Serialization: Serialize MMI's variable debug information.

Alex Lorenz via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 17:13:25 PDT 2015


Author: arphaman
Date: Tue Aug 18 19:13:25 2015
New Revision: 245396

URL: http://llvm.org/viewvc/llvm-project?rev=245396&view=rev
Log:
MIR Serialization: Serialize MMI's variable debug information.

Added:
    llvm/trunk/test/CodeGen/MIR/X86/expected-metadata-node-in-stack-object.mir
    llvm/trunk/test/CodeGen/MIR/X86/invalid-metadata-node-type.mir
    llvm/trunk/test/CodeGen/MIR/X86/stack-object-debug-info.mir
Modified:
    llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
    llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h?rev=245396&r1=245395&r2=245396&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Tue Aug 18 19:13:25 2015
@@ -196,6 +196,9 @@ struct MachineStackObject {
   unsigned Alignment = 0;
   StringValue CalleeSavedRegister;
   Optional<int64_t> LocalOffset;
+  StringValue DebugVar;
+  StringValue DebugExpr;
+  StringValue DebugLoc;
 };
 
 template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
@@ -221,6 +224,12 @@ template <> struct MappingTraits<Machine
     YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
                        StringValue()); // Don't print it out when it's empty.
     YamlIO.mapOptional("local-offset", Object.LocalOffset);
+    YamlIO.mapOptional("di-variable", Object.DebugVar,
+                       StringValue()); // Don't print it out when it's empty.
+    YamlIO.mapOptional("di-expression", Object.DebugExpr,
+                       StringValue()); // Don't print it out when it's empty.
+    YamlIO.mapOptional("di-location", Object.DebugLoc,
+                       StringValue()); // Don't print it out when it's empty.
   }
 
   static const bool flow = true;

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=245396&r1=245395&r2=245396&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Tue Aug 18 19:13:25 2015
@@ -100,6 +100,7 @@ public:
   bool parseStandaloneNamedRegister(unsigned &Reg);
   bool parseStandaloneVirtualRegister(unsigned &Reg);
   bool parseStandaloneStackObject(int &FI);
+  bool parseStandaloneMDNode(MDNode *&Node);
 
   bool
   parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
@@ -677,6 +678,17 @@ bool MIParser::parseStandaloneStackObjec
   return false;
 }
 
+bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
+  lex();
+  if (Token.isNot(MIToken::exclaim))
+    return error("expected a metadata node");
+  if (parseMDNode(Node))
+    return true;
+  if (Token.isNot(MIToken::Eof))
+    return error("expected end of string after the metadata node");
+  return false;
+}
+
 static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
   assert(MO.isImplicit());
   return MO.isDef() ? "implicit-def" : "implicit";
@@ -1858,3 +1870,9 @@ bool llvm::parseStackObjectReference(int
   return MIParser(SM, MF, Error, Src, PFS, IRSlots)
       .parseStandaloneStackObject(FI);
 }
+
+bool llvm::parseMDNode(MDNode *&Node, SourceMgr &SM, MachineFunction &MF,
+                       StringRef Src, const PerFunctionMIParsingState &PFS,
+                       const SlotMapping &IRSlots, SMDiagnostic &Error) {
+  return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseStandaloneMDNode(Node);
+}

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.h?rev=245396&r1=245395&r2=245396&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.h Tue Aug 18 19:13:25 2015
@@ -23,6 +23,7 @@ class BasicBlock;
 class MachineBasicBlock;
 class MachineInstr;
 class MachineFunction;
+class MDNode;
 struct SlotMapping;
 class SMDiagnostic;
 class SourceMgr;
@@ -89,6 +90,10 @@ bool parseStackObjectReference(int &FI,
                                const PerFunctionMIParsingState &PFS,
                                const SlotMapping &IRSlots, SMDiagnostic &Error);
 
+bool parseMDNode(MDNode *&Node, SourceMgr &SM, MachineFunction &MF,
+                 StringRef Src, const PerFunctionMIParsingState &PFS,
+                 const SlotMapping &IRSlots, SMDiagnostic &Error);
+
 } // end namespace llvm
 
 #endif

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=245396&r1=245395&r2=245396&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Tue Aug 18 19:13:25 2015
@@ -23,6 +23,7 @@
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MIRYamlMapping.h"
 #include "llvm/IR/BasicBlock.h"
@@ -113,6 +114,11 @@ public:
                                 const yaml::StringValue &RegisterSource,
                                 int FrameIdx);
 
+  bool parseStackObjectsDebugInfo(MachineFunction &MF,
+                                  PerFunctionMIParsingState &PFS,
+                                  const yaml::MachineStackObject &Object,
+                                  int FrameIdx);
+
   bool initializeConstantPool(MachineConstantPool &ConstantPool,
                               const yaml::MachineFunction &YamlMF,
                               const MachineFunction &MF,
@@ -123,6 +129,9 @@ public:
                                PerFunctionMIParsingState &PFS);
 
 private:
+  bool parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
+                   MachineFunction &MF, const PerFunctionMIParsingState &PFS);
+
   bool parseMBBReference(MachineBasicBlock *&MBB,
                          const yaml::StringValue &Source, MachineFunction &MF,
                          const PerFunctionMIParsingState &PFS);
@@ -489,6 +498,8 @@ bool MIRParserImpl::initializeFrameInfo(
       return true;
     if (Object.LocalOffset)
       MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
+    if (parseStackObjectsDebugInfo(MF, PFS, Object, ObjectIdx))
+      return true;
   }
   MFI.setCalleeSavedInfo(CSIInfo);
   if (!CSIInfo.empty())
@@ -522,6 +533,56 @@ bool MIRParserImpl::parseCalleeSavedRegi
   return false;
 }
 
+/// Verify that given node is of a certain type. Return true on error.
+template <typename T>
+static bool typecheckMDNode(T *&Result, MDNode *Node,
+                            const yaml::StringValue &Source,
+                            StringRef TypeString, MIRParserImpl &Parser) {
+  if (!Node)
+    return false;
+  Result = dyn_cast<T>(Node);
+  if (!Result)
+    return Parser.error(Source.SourceRange.Start,
+                        "expected a reference to a '" + TypeString +
+                            "' metadata node");
+  return false;
+}
+
+bool MIRParserImpl::parseStackObjectsDebugInfo(
+    MachineFunction &MF, PerFunctionMIParsingState &PFS,
+    const yaml::MachineStackObject &Object, int FrameIdx) {
+  // Debug information can only be attached to stack objects; Fixed stack
+  // objects aren't supported.
+  assert(FrameIdx >= 0 && "Expected a stack object frame index");
+  MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
+  if (parseMDNode(Var, Object.DebugVar, MF, PFS) ||
+      parseMDNode(Expr, Object.DebugExpr, MF, PFS) ||
+      parseMDNode(Loc, Object.DebugLoc, MF, PFS))
+    return true;
+  if (!Var && !Expr && !Loc)
+    return false;
+  DILocalVariable *DIVar = nullptr;
+  DIExpression *DIExpr = nullptr;
+  DILocation *DILoc = nullptr;
+  if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
+      typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
+      typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
+    return true;
+  MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
+  return false;
+}
+
+bool MIRParserImpl::parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
+                                MachineFunction &MF,
+                                const PerFunctionMIParsingState &PFS) {
+  if (Source.Value.empty())
+    return false;
+  SMDiagnostic Error;
+  if (llvm::parseMDNode(Node, SM, MF, Source.Value, PFS, IRSlots, Error))
+    return error(Error, Source.SourceRange);
+  return false;
+}
+
 bool MIRParserImpl::initializeConstantPool(
     MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
     const MachineFunction &MF,

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=245396&r1=245395&r2=245396&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Tue Aug 18 19:13:25 2015
@@ -84,7 +84,8 @@ public:
   void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
                const MachineJumpTableInfo &JTI);
   void convertStackObjects(yaml::MachineFunction &MF,
-                           const MachineFrameInfo &MFI, ModuleSlotTracker &MST,
+                           const MachineFrameInfo &MFI, MachineModuleInfo &MMI,
+                           ModuleSlotTracker &MST,
                            const TargetRegisterInfo *TRI);
 
 private:
@@ -171,7 +172,7 @@ void MIRPrinter::print(const MachineFunc
   ModuleSlotTracker MST(MF.getFunction()->getParent());
   MST.incorporateFunction(*MF.getFunction());
   convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
-  convertStackObjects(YamlMF, *MF.getFrameInfo(), MST,
+  convertStackObjects(YamlMF, *MF.getFrameInfo(), MF.getMMI(), MST,
                       MF.getSubtarget().getRegisterInfo());
   if (const auto *ConstantPool = MF.getConstantPool())
     convert(YamlMF, *ConstantPool);
@@ -265,6 +266,7 @@ void MIRPrinter::convert(ModuleSlotTrack
 
 void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
                                      const MachineFrameInfo &MFI,
+                                     MachineModuleInfo &MMI,
                                      ModuleSlotTracker &MST,
                                      const TargetRegisterInfo *TRI) {
   // Process fixed stack objects.
@@ -342,6 +344,29 @@ void MIRPrinter::convertStackObjects(yam
     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
         .printStackObjectReference(MFI.getStackProtectorIndex());
   }
+
+  // Print the debug variable information.
+  for (MachineModuleInfo::VariableDbgInfo &DebugVar :
+       MMI.getVariableDbgInfo()) {
+    auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot);
+    assert(StackObjectInfo != StackObjectOperandMapping.end() &&
+           "Invalid stack object index");
+    const FrameIndexOperand &StackObject = StackObjectInfo->second;
+    assert(!StackObject.IsFixed && "Expected a non-fixed stack object");
+    auto &Object = MF.StackObjects[StackObject.ID];
+    {
+      raw_string_ostream StrOS(Object.DebugVar.Value);
+      DebugVar.Var->printAsOperand(StrOS, MST);
+    }
+    {
+      raw_string_ostream StrOS(Object.DebugExpr.Value);
+      DebugVar.Expr->printAsOperand(StrOS, MST);
+    }
+    {
+      raw_string_ostream StrOS(Object.DebugLoc.Value);
+      DebugVar.Loc->printAsOperand(StrOS, MST);
+    }
+  }
 }
 
 void MIRPrinter::convert(yaml::MachineFunction &MF,

Added: llvm/trunk/test/CodeGen/MIR/X86/expected-metadata-node-in-stack-object.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/expected-metadata-node-in-stack-object.mir?rev=245396&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/expected-metadata-node-in-stack-object.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/expected-metadata-node-in-stack-object.mir Tue Aug 18 19:13:25 2015
@@ -0,0 +1,25 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+--- |
+  define i32 @test(i32 %x) {
+  entry:
+    %xa = alloca i32, align 4
+    store i32 %x, i32* %xa, align 4
+    %0 = load i32, i32* %xa, align 4
+    ret i32 %0
+  }
+...
+---
+name:            test
+liveins:
+  - { reg: '%edi' }
+stack:
+# CHECK: [[@LINE+1]]:74: expected a metadata node
+  - { id: 0, name: xa, offset: -12, size: 4, alignment: 4, di-variable: '0' }
+body: |
+  bb.0.entry:
+    liveins: %edi
+
+    MOV32mr %rsp, 1, _, -4, _, %edi :: (store 4 into %ir.xa)
+    %eax = COPY killed %edi
+    RETQ killed %eax
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/invalid-metadata-node-type.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/invalid-metadata-node-type.mir?rev=245396&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/invalid-metadata-node-type.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/invalid-metadata-node-type.mir Tue Aug 18 19:13:25 2015
@@ -0,0 +1,53 @@
+# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
+--- |
+  declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
+
+  define void @foo() #1 {
+  entry:
+    %x.i = alloca i8, align 1
+    %y.i = alloca [256 x i8], align 16
+    %0 = bitcast [256 x i8]* %y.i to i8*
+    br label %for.body
+
+  for.body:
+    %1 = bitcast [256 x i8]* %y.i to i8*
+    call void @llvm.dbg.declare(metadata i8* %0, metadata !4, metadata !7) #3, !dbg !8
+    br label %for.body
+  }
+
+  attributes #0 = { nounwind readnone }
+  attributes #1 = { nounwind ssp uwtable }
+  attributes #3 = { nounwind }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C89, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: 0, enums: !2, retainedTypes: !2)
+  !1 = !DIFile(filename: "t.c", directory: "")
+  !2 = !{}
+  !3 = !{i32 1, !"Debug Info Version", i32 3}
+  !4 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 16, type: !6)
+  !5 = !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false)
+  !6 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
+  !7 = !DIExpression()
+  !8 = !DILocation(line: 0, scope: !5)
+...
+---
+name:            foo
+isSSA:           true
+tracksRegLiveness: true
+frameInfo:
+  maxAlignment:    16
+stack:
+# CHECK: [[@LINE+1]]:75: expected a reference to a 'DILocalVariable' metadata node
+  - { id: 0, name: y.i, offset: 0, size: 256, alignment: 16, di-variable: '!8',
+      di-expression: '!7', di-location: '!8' }
+body: |
+  bb.0.entry:
+    successors: %bb.1.for.body
+  bb.1.for.body:
+    successors: %bb.1.for.body
+
+    DBG_VALUE %stack.0.y.i, 0, !4, !7, debug-location !8
+    JMP_1 %bb.1.for.body
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/stack-object-debug-info.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/stack-object-debug-info.mir?rev=245396&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/stack-object-debug-info.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/stack-object-debug-info.mir Tue Aug 18 19:13:25 2015
@@ -0,0 +1,65 @@
+# 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 stack object's debug info
+# correctly.
+--- |
+  declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
+
+  define void @foo() #1 {
+  entry:
+    %x.i = alloca i8, align 1
+    %y.i = alloca [256 x i8], align 16
+    %0 = bitcast [256 x i8]* %y.i to i8*
+    br label %for.body
+
+  for.body:
+    %1 = bitcast [256 x i8]* %y.i to i8*
+    call void @llvm.lifetime.end(i64 -1, i8* %1) #3
+    call void @llvm.lifetime.start(i64 -1, i8* %0) #3
+    call void @llvm.dbg.declare(metadata i8* %0, metadata !4, metadata !7) #3, !dbg !8
+    br label %for.body
+  }
+
+  declare void @llvm.lifetime.start(i64, i8* nocapture) #2
+
+  declare void @llvm.lifetime.end(i64, i8* nocapture) #2
+
+  attributes #0 = { nounwind readnone }
+  attributes #1 = { nounwind ssp uwtable }
+  attributes #2 = { nounwind argmemonly }
+  attributes #3 = { nounwind }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C89, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: 0, enums: !2, retainedTypes: !2)
+  !1 = !DIFile(filename: "t.c", directory: "")
+  !2 = !{}
+  !3 = !{i32 1, !"Debug Info Version", i32 3}
+  !4 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 16, type: !6)
+  !5 = !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false)
+  !6 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
+  !7 = !DIExpression()
+  !8 = !DILocation(line: 0, scope: !5)
+...
+---
+name:            foo
+isSSA:           true
+tracksRegLiveness: true
+frameInfo:
+  maxAlignment:    16
+# CHECK-LABEL: foo
+# CHECK: stack:
+# CHECK:  - { id: 0, name: y.i, offset: 0, size: 256, alignment: 16, di-variable: '!4',
+# CHECK-NEXT: di-expression: '!7', di-location: '!8' }
+stack:
+  - { id: 0, name: y.i, offset: 0, size: 256, alignment: 16, di-variable: '!4',
+      di-expression: '!7', di-location: '!8' }
+body: |
+  bb.0.entry:
+    successors: %bb.1.for.body
+  bb.1.for.body:
+    successors: %bb.1.for.body
+
+    DBG_VALUE %stack.0.y.i, 0, !4, !7, debug-location !8
+    JMP_1 %bb.1.for.body
+...




More information about the llvm-commits mailing list