[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