]> granicus.if.org Git - llvm/commitdiff
MIR Serialization: Serialize the machine function's liveins.
authorAlex Lorenz <arphaman@gmail.com>
Mon, 27 Jul 2015 17:42:45 +0000 (17:42 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Mon, 27 Jul 2015 17:42:45 +0000 (17:42 +0000)
Reviewers: Duncan P. N. Exon Smith

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243288 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MIRYamlMapping.h
lib/CodeGen/MIRParser/MIParser.cpp
lib/CodeGen/MIRParser/MIParser.h
lib/CodeGen/MIRParser/MIRParser.cpp
lib/CodeGen/MIRPrinter.cpp
test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir [new file with mode: 0644]
test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir [new file with mode: 0644]
test/CodeGen/MIR/X86/function-liveins.mir [new file with mode: 0644]

index 138882809e2cea9710ac2369b6e3296bd132af1a..e14a1fd6327f5b75645f37292db020145810f0eb 100644 (file)
@@ -116,6 +116,22 @@ template <> struct MappingTraits<VirtualRegisterDefinition> {
   static const bool flow = true;
 };
 
+struct MachineFunctionLiveIn {
+  StringValue Register;
+  StringValue VirtualRegister;
+};
+
+template <> struct MappingTraits<MachineFunctionLiveIn> {
+  static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) {
+    YamlIO.mapRequired("reg", LiveIn.Register);
+    YamlIO.mapOptional(
+        "virtual-reg", LiveIn.VirtualRegister,
+        StringValue()); // Don't print the virtual register when it's empty.
+  }
+
+  static const bool flow = true;
+};
+
 struct MachineBasicBlock {
   unsigned ID;
   StringValue Name;
@@ -266,6 +282,7 @@ template <> struct MappingTraits<MachineJumpTable::Entry> {
 } // end namespace yaml
 } // end namespace llvm
 
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
@@ -337,8 +354,8 @@ struct MachineFunction {
   bool TracksRegLiveness = false;
   bool TracksSubRegLiveness = false;
   std::vector<VirtualRegisterDefinition> VirtualRegisters;
+  std::vector<MachineFunctionLiveIn> LiveIns;
   // TODO: Serialize the various register masks.
-  // TODO: Serialize live in registers.
   // Frame information
   MachineFrameInfo FrameInfo;
   std::vector<FixedMachineStackObject> FixedStackObjects;
@@ -359,6 +376,7 @@ template <> struct MappingTraits<MachineFunction> {
     YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
     YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
     YamlIO.mapOptional("registers", MF.VirtualRegisters);
+    YamlIO.mapOptional("liveins", MF.LiveIns);
     YamlIO.mapOptional("frameInfo", MF.FrameInfo);
     YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
     YamlIO.mapOptional("stack", MF.StackObjects);
index 656f23143151c1d3ff75959879dbdc047adb5179..bb25ec39eb06b2f56065287829a6671255deb0af 100644 (file)
@@ -98,6 +98,7 @@ public:
   bool parse(MachineInstr *&MI);
   bool parseMBB(MachineBasicBlock *&MBB);
   bool parseNamedRegister(unsigned &Reg);
+  bool parseStandaloneVirtualRegister(unsigned &Reg);
 
   bool parseRegister(unsigned &Reg);
   bool parseRegisterFlag(unsigned &Flags);
@@ -289,6 +290,18 @@ bool MIParser::parseNamedRegister(unsigned &Reg) {
   return false;
 }
 
+bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) {
+  lex();
+  if (Token.isNot(MIToken::VirtualRegister))
+    return error("expected a virtual register");
+  if (parseRegister(Reg))
+    return 0;
+  lex();
+  if (Token.isNot(MIToken::Eof))
+    return error("expected end of string after the register reference");
+  return false;
+}
+
 static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
   assert(MO.isImplicit());
   return MO.isDef() ? "implicit-def" : "implicit";
@@ -843,3 +856,12 @@ bool llvm::parseNamedRegisterReference(unsigned &Reg, SourceMgr &SM,
                                        SMDiagnostic &Error) {
   return MIParser(SM, MF, Error, Src, PFS, IRSlots).parseNamedRegister(Reg);
 }
+
+bool llvm::parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
+                                         MachineFunction &MF, StringRef Src,
+                                         const PerFunctionMIParsingState &PFS,
+                                         const SlotMapping &IRSlots,
+                                         SMDiagnostic &Error) {
+  return MIParser(SM, MF, Error, Src, PFS, IRSlots)
+      .parseStandaloneVirtualRegister(Reg);
+}
index 888f2f57a3181a4c87b22897f12c90dca56b0abb..49530f1a36e2cd05a310e727d141ac383e2b4dc7 100644 (file)
@@ -50,6 +50,12 @@ bool parseNamedRegisterReference(unsigned &Reg, SourceMgr &SM,
                                  const SlotMapping &IRSlots,
                                  SMDiagnostic &Error);
 
+bool parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
+                                   MachineFunction &MF, StringRef Src,
+                                   const PerFunctionMIParsingState &PFS,
+                                   const SlotMapping &IRSlots,
+                                   SMDiagnostic &Error);
+
 } // end namespace llvm
 
 #endif
index 7f2267138175b06407a1c089bfccc39774cc4d65..45b401917a3ee443fb1d5f97291962af45304e5d 100644 (file)
@@ -402,6 +402,21 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
       RegInfo.setSimpleHint(Reg, PreferredReg);
     }
   }
+
+  // Parse the liveins.
+  for (const auto &LiveIn : YamlMF.LiveIns) {
+    unsigned Reg = 0;
+    if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS,
+                                    IRSlots, Error))
+      return error(Error, LiveIn.Register.SourceRange);
+    unsigned VReg = 0;
+    if (!LiveIn.VirtualRegister.Value.empty()) {
+      if (parseVirtualRegisterReference(
+              VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error))
+        return error(Error, LiveIn.VirtualRegister.SourceRange);
+    }
+    RegInfo.addLiveIn(Reg, VReg);
+  }
   return false;
 }
 
index 2287dfd4480df9d32241e8c0061be8a1e9750e5b..5800db556285883e72018a5bfc1a09e1f976d123 100644 (file)
@@ -201,6 +201,15 @@ void MIRPrinter::convert(yaml::MachineFunction &MF,
       printReg(PreferredReg, VReg.PreferredRegister, TRI);
     MF.VirtualRegisters.push_back(VReg);
   }
+
+  // Print the live ins.
+  for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
+    yaml::MachineFunctionLiveIn LiveIn;
+    printReg(I->first, LiveIn.Register, TRI);
+    if (I->second)
+      printReg(I->second, LiveIn.VirtualRegister, TRI);
+    MF.LiveIns.push_back(LiveIn);
+  }
 }
 
 void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
diff --git a/test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir b/test/CodeGen/MIR/X86/expected-named-register-in-functions-livein.mir
new file mode 100644 (file)
index 0000000..b14ff32
--- /dev/null
@@ -0,0 +1,28 @@
+# 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 %a) {
+  body:
+    ret i32 %a
+  }
+
+...
+---
+name:            test
+isSSA:           true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr32 }
+liveins:
+  # CHECK: [[@LINE+1]]:13: expected a named register
+  - { reg: '%0' }
+body:
+  - id:          0
+    name:        body
+    liveins:     [ '%edi' ]
+    instructions:
+      - '%0 = COPY %edi'
+      - '%eax = COPY %0'
+      - 'RETQ %eax'
+...
diff --git a/test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir b/test/CodeGen/MIR/X86/expected-virtual-register-in-functions-livein.mir
new file mode 100644 (file)
index 0000000..edadf42
--- /dev/null
@@ -0,0 +1,28 @@
+# 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 %a) {
+  body:
+    ret i32 %a
+  }
+
+...
+---
+name:            test
+isSSA:           true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr32 }
+liveins:
+  # CHECK: [[@LINE+1]]:34: expected a virtual register
+  - { reg: '%edi', virtual-reg: '%edi' }
+body:
+  - id:          0
+    name:        body
+    liveins:     [ '%edi' ]
+    instructions:
+      - '%0 = COPY %edi'
+      - '%eax = COPY %0'
+      - 'RETQ %eax'
+...
diff --git a/test/CodeGen/MIR/X86/function-liveins.mir b/test/CodeGen/MIR/X86/function-liveins.mir
new file mode 100644 (file)
index 0000000..d3c9d3f
--- /dev/null
@@ -0,0 +1,38 @@
+# 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 machine function's liveins
+# correctly.
+
+--- |
+
+  define i32 @test(i32 %a, i32 %b) {
+  body:
+    %c = add i32 %a, %b
+    ret i32 %c
+  }
+
+...
+---
+name:            test
+isSSA:           true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr32 }
+  - { id: 1, class: gr32 }
+  - { id: 2, class: gr32 }
+# CHECK: liveins:
+# CHECK-NEXT: - { reg: '%edi', virtual-reg: '%0' }
+# CHECK-NEXT: - { reg: '%esi', virtual-reg: '%1' }
+liveins:
+  - { reg: '%edi', virtual-reg: '%0' }
+  - { reg: '%esi', virtual-reg: '%1' }
+body:
+  - id:              0
+    name:            body
+    liveins:         [ '%edi', '%esi' ]
+    instructions:
+      - '%1 = COPY %esi'
+      - '%0 = COPY %edi'
+      - '%2 = ADD32rr %0, %1, implicit-def dead %eflags'
+      - '%eax = COPY %2'
+      - 'RETQ %eax'
+...