[llvm] r241959 - MIR Serialization: Serialize the virtual register operands.

Alex Lorenz arphaman at gmail.com
Fri Jul 10 15:51:20 PDT 2015


Author: arphaman
Date: Fri Jul 10 17:51:20 2015
New Revision: 241959

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

Reviewers: Duncan P. N. Exon Smith

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

Added:
    llvm/trunk/test/CodeGen/MIR/X86/undefined-virtual-register.mir
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/CodeGen/MIRParser/MIParser.h
    llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp
    llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp?rev=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Fri Jul 10 17:51:20 2015
@@ -115,9 +115,22 @@ static Cursor maybeLexMachineBasicBlock(
   return C;
 }
 
+static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
+  auto Range = C;
+  C.advance(); // Skip '%'
+  auto NumberRange = C;
+  while (isdigit(C.peek()))
+    C.advance();
+  Token = MIToken(MIToken::VirtualRegister, Range.upto(C),
+                  APSInt(NumberRange.upto(C)));
+  return C;
+}
+
 static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
   if (C.peek() != '%')
     return None;
+  if (isdigit(C.peek(1)))
+    return lexVirtualRegister(C, Token);
   auto Range = C;
   C.advance(); // Skip '%'
   while (isIdentifierChar(C.peek()))

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Fri Jul 10 17:51:20 2015
@@ -51,7 +51,8 @@ struct MIToken {
     GlobalValue,
 
     // Other tokens
-    IntegerLiteral
+    IntegerLiteral,
+    VirtualRegister
   };
 
 private:
@@ -73,7 +74,8 @@ public:
   bool isError() const { return Kind == Error; }
 
   bool isRegister() const {
-    return Kind == NamedRegister || Kind == underscore;
+    return Kind == NamedRegister || Kind == underscore ||
+           Kind == VirtualRegister;
   }
 
   bool isRegisterFlag() const {
@@ -93,7 +95,7 @@ public:
 
   bool hasIntegerValue() const {
     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
-           Kind == GlobalValue;
+           Kind == GlobalValue || Kind == VirtualRegister;
   }
 };
 

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Fri Jul 10 17:51:20 2015
@@ -288,6 +288,17 @@ bool MIParser::parseRegister(unsigned &R
       return error(Twine("unknown register name '") + Name + "'");
     break;
   }
+  case MIToken::VirtualRegister: {
+    unsigned ID;
+    if (getUnsigned(ID))
+      return true;
+    const auto RegInfo = PFS.VirtualRegisterSlots.find(ID);
+    if (RegInfo == PFS.VirtualRegisterSlots.end())
+      return error(Twine("use of undefined virtual register '%") + Twine(ID) +
+                   "'");
+    Reg = RegInfo->second;
+    break;
+  }
   // TODO: Parse other register kinds.
   default:
     llvm_unreachable("The current token should be a register");
@@ -425,6 +436,7 @@ bool MIParser::parseMachineOperand(Machi
   case MIToken::kw_undef:
   case MIToken::underscore:
   case MIToken::NamedRegister:
+  case MIToken::VirtualRegister:
     return parseRegisterOperand(Dest);
   case MIToken::IntegerLiteral:
     return parseImmediateOperand(Dest);

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.h?rev=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.h Fri Jul 10 17:51:20 2015
@@ -28,6 +28,7 @@ class SourceMgr;
 
 struct PerFunctionMIParsingState {
   DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
+  DenseMap<unsigned, unsigned> VirtualRegisterSlots;
 };
 
 bool parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF,

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Fri Jul 10 17:51:20 2015
@@ -102,9 +102,11 @@ public:
                                    const yaml::MachineBasicBlock &YamlMBB,
                                    const PerFunctionMIParsingState &PFS);
 
-  bool initializeRegisterInfo(const MachineFunction &MF,
-                              MachineRegisterInfo &RegInfo,
-                              const yaml::MachineFunction &YamlMF);
+  bool
+  initializeRegisterInfo(const MachineFunction &MF,
+                         MachineRegisterInfo &RegInfo,
+                         const yaml::MachineFunction &YamlMF,
+                         DenseMap<unsigned, unsigned> &VirtualRegisterSlots);
 
   bool initializeFrameInfo(MachineFrameInfo &MFI,
                            const yaml::MachineFunction &YamlMF);
@@ -258,12 +260,13 @@ bool MIRParserImpl::initializeMachineFun
     MF.setAlignment(YamlMF.Alignment);
   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
   MF.setHasInlineAsm(YamlMF.HasInlineAsm);
-  if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF))
+  PerFunctionMIParsingState PFS;
+  if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF,
+                             PFS.VirtualRegisterSlots))
     return true;
   if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF))
     return true;
 
-  PerFunctionMIParsingState PFS;
   const auto &F = *MF.getFunction();
   for (const auto &YamlMBB : YamlMF.BasicBlocks) {
     const BasicBlock *BB = nullptr;
@@ -330,7 +333,8 @@ bool MIRParserImpl::initializeMachineBas
 
 bool MIRParserImpl::initializeRegisterInfo(
     const MachineFunction &MF, MachineRegisterInfo &RegInfo,
-    const yaml::MachineFunction &YamlMF) {
+    const yaml::MachineFunction &YamlMF,
+    DenseMap<unsigned, unsigned> &VirtualRegisterSlots) {
   assert(RegInfo.isSSA());
   if (!YamlMF.IsSSA)
     RegInfo.leaveSSA();
@@ -346,9 +350,10 @@ bool MIRParserImpl::initializeRegisterIn
       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);
+    unsigned Reg = RegInfo.createVirtualRegister(RC);
+    // TODO: Report an error when the same virtual register with the same ID is
+    // redefined.
+    VirtualRegisterSlots.insert(std::make_pair(VReg.ID, Reg));
   }
   return false;
 }

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Fri Jul 10 17:51:20 2015
@@ -250,9 +250,10 @@ void MIPrinter::print(const MachineInstr
 static void printReg(unsigned Reg, raw_ostream &OS,
                      const TargetRegisterInfo *TRI) {
   // TODO: Print Stack Slots.
-  // TODO: Print virtual registers.
   if (!Reg)
     OS << '_';
+  else if (TargetRegisterInfo::isVirtualRegister(Reg))
+    OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
   else if (Reg < TRI->getNumRegs())
     OS << '%' << StringRef(TRI->getName(Reg)).lower();
   else

Added: llvm/trunk/test/CodeGen/MIR/X86/undefined-virtual-register.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/undefined-virtual-register.mir?rev=241959&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/undefined-virtual-register.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/undefined-virtual-register.mir Fri Jul 10 17:51:20 2015
@@ -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
+# This test ensures that the MIR parser reports an error when parsing a
+# reference to an undefined virtual register.
+
+--- |
+
+  define i32 @test(i32 %a) {
+  entry:
+    ret i32 %a
+  }
+
+...
+---
+name:            test
+isSSA:           true
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr32 }
+body:
+  - id:          0
+    name:        entry
+    instructions:
+      - '%0 = COPY %edi'
+      # CHECK: [[@LINE+1]]:22: use of undefined virtual register '%10'
+      - '%eax = COPY %10'
+      - 'RETQ %eax'
+...
+

Modified: 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=241959&r1=241958&r2=241959&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/X86/virtual-registers.mir Fri Jul 10 17:51:20 2015
@@ -1,6 +1,6 @@
 # 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.
+# This test ensures that the MIR parser parses virtual register definitions and
+# references correctly.
 
 --- |
 
@@ -16,6 +16,18 @@
     ret i32 %a
   }
 
+  define i32 @foo(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
@@ -30,6 +42,64 @@ registers:
   - { id: 1, class: gr32 }
   - { id: 2, class: gr32 }
 body:
-  - id: 0
+  - id:          0
+    name:        entry
+    # CHECK:      %0 = COPY %edi
+    # CHECK-NEXT: %1 = SUB32ri8 %0, 10
+    instructions:
+      - '%0 = COPY %edi'
+      - '%1 = SUB32ri8 %0, 10, implicit-def %eflags'
+      - 'JG_1 %bb.2.exit, implicit %eflags'
+      - 'JMP_1 %bb.1.less'
+  - id:          1
+    name:        less
+    # CHECK:      %2 = MOV32r0
+    # CHECK-NEXT: %eax = COPY %2
+    instructions:
+      - '%2 = MOV32r0 implicit-def %eflags'
+      - '%eax = COPY %2'
+      - 'RETQ %eax'
+  - id:          2
+    name:        exit
+    instructions:
+      - '%eax = COPY %0'
+      - 'RETQ %eax'
+...
+---
+name:            foo
+isSSA:           true
+tracksRegLiveness: true
+# CHECK: name: foo
+# CHECK:      registers:
+# CHECK-NEXT:   - { id: 0, class: gr32 }
+# CHECK-NEXT:   - { id: 1, class: gr32 }
+# CHECK-NEXT:   - { id: 2, class: gr32 }
+registers:
+  - { id: 2, class: gr32 }
+  - { id: 0, class: gr32 }
+  - { id: 10, class: gr32 }
+body:
+  - id:          0
+    name:        entry
+    # CHECK:      %0 = COPY %edi
+    # CHECK-NEXT: %1 = SUB32ri8 %0, 10
+    instructions:
+      - '%2 = COPY %edi'
+      - '%0 = SUB32ri8 %2, 10, implicit-def %eflags'
+      - 'JG_1 %bb.2.exit, implicit %eflags'
+      - 'JMP_1 %bb.1.less'
+  - id:          1
+    name:        less
+    # CHECK:      %2 = MOV32r0
+    # CHECK-NEXT: %eax = COPY %2
+    instructions:
+      - '%10 = MOV32r0 implicit-def %eflags'
+      - '%eax = COPY %10'
+      - 'RETQ %eax'
+  - id:          2
+    name:        exit
+    # CHECK: %eax = COPY %0
+    instructions:
+      - '%eax = COPY %2'
+      - 'RETQ %eax'
 ...
-





More information about the llvm-commits mailing list