summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-01-18 00:59:19 +0000
committerMatthias Braun <matze@braunis.de>2017-01-18 00:59:19 +0000
commitde5fea2c30dc7ef2f8e0e30639064855260bfa0a (patch)
treeda3ce87c983233ff6707ef8a26a3b1ce2ec9023d /llvm/lib
parent34c23279c202e3f403e36883f415257abdb52005 (diff)
downloadbcm5719-llvm-de5fea2c30dc7ef2f8e0e30639064855260bfa0a.tar.gz
bcm5719-llvm-de5fea2c30dc7ef2f8e0e30639064855260bfa0a.zip
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 llvm-svn: 292321
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp71
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.h9
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp11
3 files changed, 83 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index c8bed0890dd..ff6d3097959 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -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 &Reg, VRegInfo *&Info) {
}
}
+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(MachineOperand &Dest,
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)) {
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h
index 93a4d84ba62..9b3879cf837 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.h
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.h
@@ -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);
};
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 3dff1147631..0c694c465b6 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -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::initializeMachineFunction(MachineFunction &MF) {
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::initializeMachineFunction(MachineFunction &MF) {
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(const MachineFunction &MF) {
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::getRegClass(const MachineFunction &MF,
const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF,
StringRef Name) {
- initNames2RegBanks(MF);
auto RegBankInfo = Names2RegBanks.find(Name);
if (RegBankInfo == Names2RegBanks.end())
return nullptr;
OpenPOWER on IntegriCloud