[llvm] r292321 - MIRParser: Allow regclass specification on operand

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 17 16:59:19 PST 2017


Author: matze
Date: Tue Jan 17 18:59:19 2017
New Revision: 292321

URL: http://llvm.org/viewvc/llvm-project?rev=292321&view=rev
Log:
MIRParser: Allow regclass specification on operand

You can now define the register class of a virtual register on the
operand itself avoiding the need to use a "registers:" block.

Example: "%0:gr64 = COPY %rax"

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

Added:
    llvm/trunk/test/CodeGen/MIR/AArch64/register-operand-bank.mir
    llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid0.mir
    llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid1.mir
    llvm/trunk/test/CodeGen/MIR/X86/register-operand-class.mir
Modified:
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
    llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=292321&r1=292320&r2=292321&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Tue Jan 17 18:59:19 2017
@@ -41,8 +41,11 @@
 using namespace llvm;
 
 PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
-    SourceMgr &SM, const SlotMapping &IRSlots)
-  : MF(MF), SM(&SM), IRSlots(IRSlots) {
+    SourceMgr &SM, const SlotMapping &IRSlots,
+    const Name2RegClassMap &Names2RegClasses,
+    const Name2RegBankMap &Names2RegBanks)
+  : MF(MF), SM(&SM), IRSlots(IRSlots), Names2RegClasses(Names2RegClasses),
+    Names2RegBanks(Names2RegBanks) {
 }
 
 VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) {
@@ -139,6 +142,7 @@ public:
   bool parseVirtualRegister(VRegInfo *&Info);
   bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo);
   bool parseRegisterFlag(unsigned &Flags);
+  bool parseRegisterClassOrBank(VRegInfo &RegInfo);
   bool parseSubRegisterIndex(unsigned &SubReg);
   bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx);
   bool parseRegisterOperand(MachineOperand &Dest,
@@ -878,6 +882,62 @@ bool MIParser::parseRegister(unsigned &R
   }
 }
 
+bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
+  if (Token.isNot(MIToken::Identifier))
+    return error("expected a register class or register bank name");
+  StringRef::iterator Loc = Token.location();
+  StringRef Name = Token.stringValue();
+
+  // Was it a register class?
+  auto RCNameI = PFS.Names2RegClasses.find(Name);
+  if (RCNameI != PFS.Names2RegClasses.end()) {
+    lex();
+    const TargetRegisterClass &RC = *RCNameI->getValue();
+
+    switch (RegInfo.Kind) {
+    case VRegInfo::UNKNOWN:
+    case VRegInfo::NORMAL:
+      RegInfo.Kind = VRegInfo::NORMAL;
+      if (RegInfo.Explicit && RegInfo.D.RC != &RC) {
+        const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
+        return error(Loc, Twine("conflicting register classes, previously: ") +
+                     Twine(TRI.getRegClassName(RegInfo.D.RC)));
+      }
+      RegInfo.D.RC = &RC;
+      RegInfo.Explicit = true;
+      return false;
+
+    case VRegInfo::GENERIC:
+    case VRegInfo::REGBANK:
+      return error(Loc, "register class specification on generic register");
+    }
+    llvm_unreachable("Unexpected register kind");
+  }
+
+  // Should be a register bank.
+  auto RBNameI = PFS.Names2RegBanks.find(Name);
+  lex();
+  if (RBNameI == PFS.Names2RegBanks.end())
+    return error(Loc, "expected a register class or register bank name");
+
+  const RegisterBank &RegBank = *RBNameI->getValue();
+  switch (RegInfo.Kind) {
+  case VRegInfo::UNKNOWN:
+  case VRegInfo::GENERIC:
+  case VRegInfo::REGBANK:
+    RegInfo.Kind = VRegInfo::REGBANK;
+    if (RegInfo.Explicit && RegInfo.D.RegBank != &RegBank)
+      return error(Loc, "conflicting register banks");
+    RegInfo.D.RegBank = &RegBank;
+    RegInfo.Explicit = true;
+    return false;
+
+  case VRegInfo::NORMAL:
+    return error(Loc, "register class specification on normal register");
+  }
+  llvm_unreachable("Unexpected register kind");
+}
+
 bool MIParser::parseRegisterFlag(unsigned &Flags) {
   const unsigned OldFlags = Flags;
   switch (Token.kind()) {
@@ -1004,6 +1064,13 @@ bool MIParser::parseRegisterOperand(Mach
     if (!TargetRegisterInfo::isVirtualRegister(Reg))
       return error("subregister index expects a virtual register");
   }
+  if (Token.is(MIToken::colon)) {
+    if (!TargetRegisterInfo::isVirtualRegister(Reg))
+      return error("register class specification expects a virtual register");
+    lex();
+    if (parseRegisterClassOrBank(*RegInfo))
+        return true;
+  }
   MachineRegisterInfo &MRI = MF.getRegInfo();
   if ((Flags & RegState::Define) == 0) {
     if (consumeIfPresent(MIToken::lparen)) {

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.h?rev=292321&r1=292320&r2=292321&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.h Tue Jan 17 18:59:19 2017
@@ -45,11 +45,16 @@ struct VRegInfo {
   unsigned PreferredReg = 0;
 };
 
+typedef StringMap<const TargetRegisterClass*> Name2RegClassMap;
+typedef StringMap<const RegisterBank*> Name2RegBankMap;
+
 struct PerFunctionMIParsingState {
   BumpPtrAllocator Allocator;
   MachineFunction &MF;
   SourceMgr *SM;
   const SlotMapping &IRSlots;
+  const Name2RegClassMap &Names2RegClasses;
+  const Name2RegBankMap &Names2RegBanks;
 
   DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
   DenseMap<unsigned, VRegInfo*> VRegInfos;
@@ -59,7 +64,9 @@ struct PerFunctionMIParsingState {
   DenseMap<unsigned, unsigned> JumpTableSlots;
 
   PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM,
-                            const SlotMapping &IRSlots);
+                            const SlotMapping &IRSlots,
+                            const Name2RegClassMap &Names2RegClasses,
+                            const Name2RegBankMap &Names2RegBanks);
 
   VRegInfo &getVRegInfo(unsigned VReg);
 };

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=292321&r1=292320&r2=292321&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Tue Jan 17 18:59:19 2017
@@ -55,9 +55,9 @@ class MIRParserImpl {
   StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
   SlotMapping IRSlots;
   /// Maps from register class names to register classes.
-  StringMap<const TargetRegisterClass *> Names2RegClasses;
+  Name2RegClassMap Names2RegClasses;
   /// Maps from register bank names to register banks.
-  StringMap<const RegisterBank *> Names2RegBanks;
+  Name2RegBankMap Names2RegBanks;
 
 public:
   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
@@ -325,6 +325,8 @@ bool MIRParserImpl::initializeMachineFun
     return error(Twine("no machine function information for function '") +
                  MF.getName() + "' in the MIR file");
   // TODO: Recreate the machine function.
+  initNames2RegClasses(MF);
+  initNames2RegBanks(MF);
   const yaml::MachineFunction &YamlMF = *It->getValue();
   if (YamlMF.Alignment)
     MF.setAlignment(YamlMF.Alignment);
@@ -338,7 +340,8 @@ bool MIRParserImpl::initializeMachineFun
   if (YamlMF.Selected)
     MF.getProperties().set(MachineFunctionProperties::Property::Selected);
 
-  PerFunctionMIParsingState PFS(MF, SM, IRSlots);
+  PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
+                                Names2RegBanks);
   if (parseRegisterInfo(PFS, YamlMF))
     return true;
   if (!YamlMF.Constants.empty()) {
@@ -818,7 +821,6 @@ void MIRParserImpl::initNames2RegBanks(c
 
 const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
                                                       StringRef Name) {
-  initNames2RegClasses(MF);
   auto RegClassInfo = Names2RegClasses.find(Name);
   if (RegClassInfo == Names2RegClasses.end())
     return nullptr;
@@ -827,7 +829,6 @@ const TargetRegisterClass *MIRParserImpl
 
 const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF,
                                               StringRef Name) {
-  initNames2RegBanks(MF);
   auto RegBankInfo = Names2RegBanks.find(Name);
   if (RegBankInfo == Names2RegBanks.end())
     return nullptr;

Added: llvm/trunk/test/CodeGen/MIR/AArch64/register-operand-bank.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/AArch64/register-operand-bank.mir?rev=292321&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/AArch64/register-operand-bank.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/AArch64/register-operand-bank.mir Tue Jan 17 18:59:19 2017
@@ -0,0 +1,20 @@
+# RUN: llc -o - %s -mtriple=aarch64-- -run-pass=none | FileCheck %s
+# REQUIRES: global-isel
+# Test various aspects of register bank specification on machine operands.
+--- |
+  define void @func() { ret void }
+...
+---
+# CHECK-LABEL: name: func
+# CHECK: registers:
+# CHECK:   - { id: 0, class: gpr }
+# CHECK:   - { id: 1, class: fpr }
+name: func
+body: |
+  bb.0:
+    %0 : gpr(s64) = COPY %x9
+    %x9 = COPY %0
+
+    %3 : fpr(s64) = COPY %d0
+    %d1 = COPY %3 : fpr
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid0.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid0.mir?rev=292321&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid0.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid0.mir Tue Jan 17 18:59:19 2017
@@ -0,0 +1,13 @@
+# RUN: not llc -o /dev/null %s -march=x86-64 -run-pass none 2>&1 | FileCheck %s
+# This test ensures that an error is reported for specifying the register class
+# of a physical register.
+--- |
+  define void @t() { ret void }
+...
+---
+name: t
+body: |
+  bb.0:
+    ; CHECK: [[@LINE+1]]:10: register class specification expects a virtual register
+    %eax : gr32 = COPY %rdx
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid1.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid1.mir?rev=292321&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid1.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/register-operand-class-invalid1.mir Tue Jan 17 18:59:19 2017
@@ -0,0 +1,14 @@
+# RUN: not llc -o /dev/null %s -march=x86-64 -run-pass none 2>&1 | FileCheck %s
+# This test ensures that an error is reported for specifying the register class
+# of a physical register.
+--- |
+  define void @t() { ret void }
+...
+---
+name: t
+body: |
+  bb.0:
+    %0 : gr32 = COPY %rdx
+    ; CHECK: [[@LINE+1]]:24: conflicting register classes, previously: GR32
+    NOOP implicit %0 : gr32_abcd
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/register-operand-class.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/register-operand-class.mir?rev=292321&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/register-operand-class.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/register-operand-class.mir Tue Jan 17 18:59:19 2017
@@ -0,0 +1,24 @@
+# RUN: llc -o - %s -march=x86-64 -run-pass none | FileCheck %s
+# Test various aspects of register class specification on machine operands.
+--- |
+  define void @func() { ret void }
+...
+---
+# CHECK-LABEL: name: func
+# CHECK: registers:
+# CHECK:   - { id: 0, class: gr32 }
+# CHECK:   - { id: 1, class: gr64 }
+# CHECK:   - { id: 2, class: gr32 }
+# CHECK:   - { id: 3, class: gr16 }
+name: func
+body: |
+  bb.0:
+    %0 : gr32 = COPY %rax
+    %1.sub_32bit : gr64 = COPY %eax
+    %rdx = COPY %1
+    %2 = COPY %ecx
+    %ecx = COPY %2 : gr32
+
+    %3 : gr16 = COPY %bx
+    %bx = COPY %3 : gr16
+...




More information about the llvm-commits mailing list