[llvm] r241868 - MIR Serialization: Serialize the virtual register definitions.

Alex Lorenz arphaman at gmail.com
Thu Jul 9 15:23:13 PDT 2015


Author: arphaman
Date: Thu Jul  9 17:23:13 2015
New Revision: 241868

URL: http://llvm.org/viewvc/llvm-project?rev=241868&view=rev
Log:
MIR Serialization: Serialize the virtual register definitions.

The virtual registers are serialized using a YAML sequence of YAML inline
mappings. Each mapping has the id of the virtual register and the register
class.

Reviewers: Duncan P. N. Exon Smith

Differential Revision: http://reviews.llvm.org/D10981

Added:
    llvm/trunk/test/CodeGen/MIR/X86/undefined-register-class.mir
    llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir
Modified:
    llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.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=241868&r1=241867&r2=241868&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Thu Jul  9 17:23:13 2015
@@ -81,6 +81,21 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::
 namespace llvm {
 namespace yaml {
 
+struct VirtualRegisterDefinition {
+  unsigned ID;
+  StringValue Class;
+  // TODO: Serialize the virtual register hints.
+};
+
+template <> struct MappingTraits<VirtualRegisterDefinition> {
+  static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
+    YamlIO.mapRequired("id", Reg.ID);
+    YamlIO.mapRequired("class", Reg.Class);
+  }
+
+  static const bool flow = true;
+};
+
 struct MachineBasicBlock {
   unsigned ID;
   StringValue Name;
@@ -109,6 +124,7 @@ template <> struct MappingTraits<Machine
 } // end namespace yaml
 } // end namespace llvm
 
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
 
 namespace llvm {
@@ -169,7 +185,7 @@ struct MachineFunction {
   bool IsSSA = false;
   bool TracksRegLiveness = false;
   bool TracksSubRegLiveness = false;
-  // TODO: Serialize virtual register definitions.
+  std::vector<VirtualRegisterDefinition> VirtualRegisters;
   // TODO: Serialize the various register masks.
   // TODO: Serialize live in registers.
   // Frame information
@@ -187,6 +203,7 @@ template <> struct MappingTraits<Machine
     YamlIO.mapOptional("isSSA", MF.IsSSA);
     YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
     YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
+    YamlIO.mapOptional("registers", MF.VirtualRegisters);
     YamlIO.mapOptional("frameInfo", MF.FrameInfo);
     YamlIO.mapOptional("body", MF.BasicBlocks);
   }

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=241868&r1=241867&r2=241868&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Thu Jul  9 17:23:13 2015
@@ -49,6 +49,8 @@ class MIRParserImpl {
   LLVMContext &Context;
   StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
   SlotMapping IRSlots;
+  /// Maps from register class names to register classes.
+  StringMap<const TargetRegisterClass *> Names2RegClasses;
 
 public:
   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
@@ -100,7 +102,8 @@ public:
                                    const yaml::MachineBasicBlock &YamlMBB,
                                    const PerFunctionMIParsingState &PFS);
 
-  bool initializeRegisterInfo(MachineRegisterInfo &RegInfo,
+  bool initializeRegisterInfo(const MachineFunction &MF,
+                              MachineRegisterInfo &RegInfo,
                               const yaml::MachineFunction &YamlMF);
 
   bool initializeFrameInfo(MachineFrameInfo &MFI,
@@ -117,6 +120,14 @@ private:
 
   /// Create an empty function with the given name.
   void createDummyFunction(StringRef Name, Module &M);
+
+  void initNames2RegClasses(const MachineFunction &MF);
+
+  /// Check if the given identifier is a name of a register class.
+  ///
+  /// Return null if the name isn't a register class.
+  const TargetRegisterClass *getRegClass(const MachineFunction &MF,
+                                         StringRef Name);
 };
 
 } // end namespace llvm
@@ -247,7 +258,7 @@ bool MIRParserImpl::initializeMachineFun
     MF.setAlignment(YamlMF.Alignment);
   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
   MF.setHasInlineAsm(YamlMF.HasInlineAsm);
-  if (initializeRegisterInfo(MF.getRegInfo(), YamlMF))
+  if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF))
     return true;
   if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF.FrameInfo))
     return true;
@@ -318,7 +329,8 @@ bool MIRParserImpl::initializeMachineBas
 }
 
 bool MIRParserImpl::initializeRegisterInfo(
-    MachineRegisterInfo &RegInfo, const yaml::MachineFunction &YamlMF) {
+    const MachineFunction &MF, MachineRegisterInfo &RegInfo,
+    const yaml::MachineFunction &YamlMF) {
   assert(RegInfo.isSSA());
   if (!YamlMF.IsSSA)
     RegInfo.leaveSSA();
@@ -326,6 +338,18 @@ bool MIRParserImpl::initializeRegisterIn
   if (!YamlMF.TracksRegLiveness)
     RegInfo.invalidateLiveness();
   RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
+
+  // Parse the virtual register information.
+  for (const auto &VReg : YamlMF.VirtualRegisters) {
+    const auto *RC = getRegClass(MF, VReg.Class.Value);
+    if (!RC)
+      return error(VReg.Class.SourceRange.Start,
+                   Twine("use of undefined register class '") +
+                       VReg.Class.Value + "'");
+    // TODO: create the mapping from IDs to registers so that the virtual
+    // register references can be parsed correctly.
+    RegInfo.createVirtualRegister(RC);
+  }
   return false;
 }
 
@@ -395,6 +419,26 @@ SMDiagnostic MIRParserImpl::diagFromLLVM
                       Error.getFixIts());
 }
 
+void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
+  if (!Names2RegClasses.empty())
+    return;
+  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+  for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
+    const auto *RC = TRI->getRegClass(I);
+    Names2RegClasses.insert(
+        std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
+  }
+}
+
+const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
+                                                      StringRef Name) {
+  initNames2RegClasses(MF);
+  auto RegClassInfo = Names2RegClasses.find(Name);
+  if (RegClassInfo == Names2RegClasses.end())
+    return nullptr;
+  return RegClassInfo->getValue();
+}
+
 MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
     : Impl(std::move(Impl)) {}
 

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=241868&r1=241867&r2=241868&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Thu Jul  9 17:23:13 2015
@@ -42,7 +42,8 @@ public:
 
   void print(const MachineFunction &MF);
 
-  void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo);
+  void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
+               const TargetRegisterInfo *TRI);
   void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
   void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
                const MachineBasicBlock &MBB);
@@ -95,7 +96,7 @@ void MIRPrinter::print(const MachineFunc
   YamlMF.Alignment = MF.getAlignment();
   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
   YamlMF.HasInlineAsm = MF.hasInlineAsm();
-  convert(YamlMF, MF.getRegInfo());
+  convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
   convert(YamlMF.FrameInfo, *MF.getFrameInfo());
 
   int I = 0;
@@ -117,10 +118,21 @@ void MIRPrinter::print(const MachineFunc
 }
 
 void MIRPrinter::convert(yaml::MachineFunction &MF,
-                         const MachineRegisterInfo &RegInfo) {
+                         const MachineRegisterInfo &RegInfo,
+                         const TargetRegisterInfo *TRI) {
   MF.IsSSA = RegInfo.isSSA();
   MF.TracksRegLiveness = RegInfo.tracksLiveness();
   MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
+
+  // Print the virtual register definitions.
+  for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
+    unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
+    yaml::VirtualRegisterDefinition VReg;
+    VReg.ID = I;
+    VReg.Class =
+        StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
+    MF.VirtualRegisters.push_back(VReg);
+  }
 }
 
 void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,

Added: llvm/trunk/test/CodeGen/MIR/X86/undefined-register-class.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/undefined-register-class.mir?rev=241868&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/undefined-register-class.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/undefined-register-class.mir Thu Jul  9 17:23:13 2015
@@ -0,0 +1,26 @@
+# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
+# This test ensures that the MIR parser reports an error when it encounters an
+# unknown register class.
+
+--- |
+
+  define i32 @test(i32 %a) {
+  entry:
+    ret i32 %a
+  }
+
+...
+---
+name:            test
+isSSA:           true
+tracksRegLiveness: true
+registers:
+  # CHECK: [[@LINE+1]]:20: use of undefined register class 'gr3200'
+  - {id: 0, class: 'gr3200'}
+body:
+  - id:          0
+    name:        entry
+    instructions:
+      - 'RETQ %eax'
+...
+

Added: llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir?rev=241868&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir Thu Jul  9 17:23:13 2015
@@ -0,0 +1,35 @@
+# 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 virtual register definitions
+# correctly.
+
+--- |
+
+  define i32 @bar(i32 %a) {
+  entry:
+    %0 = icmp sle i32 %a, 10
+    br i1 %0, label %less, label %exit
+
+  less:
+    ret i32 0
+
+  exit:
+    ret i32 %a
+  }
+
+...
+---
+name:            bar
+isSSA:           true
+tracksRegLiveness: true
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: gr32 }
+# CHECK-NEXT:   - { id: 1, class: gr32 }
+# CHECK-NEXT:   - { id: 2, class: gr32 }
+registers:
+  - { id: 0, class: gr32 }
+  - { id: 1, class: gr32 }
+  - { id: 2, class: gr32 }
+body:
+  - id: 0
+...
+





More information about the llvm-commits mailing list