[MIR] Adding support for Named Virtual Registers in MIR.
llvm-svn: 328887
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 7104c02..0216d9b 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -410,6 +410,16 @@
return isIdentifierChar(C) && C != '.';
}
+static Cursor lexNamedVirtualRegister(Cursor C, MIToken &Token) {
+ Cursor Range = C;
+ C.advance(); // Skip '%'
+ while (isRegisterChar(C.peek()))
+ C.advance();
+ Token.reset(MIToken::NamedVirtualRegister, Range.upto(C))
+ .setStringValue(Range.upto(C).drop_front(1)); // Drop the '%'
+ return C;
+}
+
static Cursor maybeLexRegister(Cursor C, MIToken &Token,
ErrorCallbackType ErrorCallback) {
if (C.peek() != '%' && C.peek() != '$')
@@ -419,7 +429,9 @@
if (isdigit(C.peek(1)))
return lexVirtualRegister(C, Token);
- // ErrorCallback(Token.location(), "Named vregs are not yet supported.");
+ if (isRegisterChar(C.peek(1)))
+ return lexNamedVirtualRegister(C, Token);
+
return None;
}
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index c6a9b79..40666fa 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -118,6 +118,7 @@
Identifier,
IntegerType,
NamedRegister,
+ NamedVirtualRegister,
MachineBasicBlockLabel,
MachineBasicBlock,
PointerType,
@@ -170,7 +171,7 @@
bool isRegister() const {
return Kind == NamedRegister || Kind == underscore ||
- Kind == VirtualRegister;
+ Kind == NamedVirtualRegister || Kind == VirtualRegister;
}
bool isRegisterFlag() const {
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 18cc6db..de3a0cd 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -98,6 +98,18 @@
return *I.first->second;
}
+VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) {
+ assert(RegName != "" && "Expected named reg.");
+
+ auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr));
+ if (I.second) {
+ VRegInfo *Info = new (Allocator) VRegInfo;
+ Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName);
+ I.first->second = Info;
+ }
+ return *I.first->second;
+}
+
namespace {
/// A wrapper struct around the 'MachineOperand' struct that includes a source
@@ -182,6 +194,7 @@
bool parseNamedRegister(unsigned &Reg);
bool parseVirtualRegister(VRegInfo *&Info);
+ bool parseNamedVirtualRegister(VRegInfo *&Info);
bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo);
bool parseRegisterFlag(unsigned &Flags);
bool parseRegisterClassOrBank(VRegInfo &RegInfo);
@@ -949,7 +962,18 @@
return false;
}
+bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) {
+ assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token");
+ StringRef Name = Token.stringValue();
+ // TODO: Check that the VReg name is not the same as a physical register name.
+ // If it is, then print a warning (when warnings are implemented).
+ Info = &PFS.getVRegInfoNamed(Name);
+ return false;
+}
+
bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
+ if (Token.is(MIToken::NamedVirtualRegister))
+ return parseNamedVirtualRegister(Info);
assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
unsigned ID;
if (getUnsigned(ID))
@@ -965,6 +989,7 @@
return false;
case MIToken::NamedRegister:
return parseNamedRegister(Reg);
+ case MIToken::NamedVirtualRegister:
case MIToken::VirtualRegister:
if (parseVirtualRegister(Info))
return true;
@@ -1952,6 +1977,7 @@
case MIToken::underscore:
case MIToken::NamedRegister:
case MIToken::VirtualRegister:
+ case MIToken::NamedVirtualRegister:
return parseRegisterOperand(Dest, TiedDefIdx);
case MIToken::IntegerLiteral:
return parseImmediateOperand(Dest);
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h
index 2307881..e082044 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.h
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.h
@@ -56,6 +56,7 @@
DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
DenseMap<unsigned, VRegInfo*> VRegInfos;
+ StringMap<VRegInfo*> VRegInfosNamed;
DenseMap<unsigned, int> FixedStackObjectSlots;
DenseMap<unsigned, int> StackObjectSlots;
DenseMap<unsigned, unsigned> ConstantPoolSlots;
@@ -67,6 +68,7 @@
const Name2RegBankMap &Names2RegBanks);
VRegInfo &getVRegInfo(unsigned VReg);
+ VRegInfo &getVRegInfoNamed(StringRef RegName);
};
/// Parse the machine basic block definitions, and skip the machine
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 9eb94c0..51e4948 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -512,13 +512,12 @@
MachineRegisterInfo &MRI = MF.getRegInfo();
bool Error = false;
// Create VRegs
- for (auto P : PFS.VRegInfos) {
- const VRegInfo &Info = *P.second;
+ auto populateVRegInfo = [&] (const VRegInfo &Info, Twine Name) {
unsigned Reg = Info.VReg;
switch (Info.Kind) {
case VRegInfo::UNKNOWN:
error(Twine("Cannot determine class/bank of virtual register ") +
- Twine(P.first) + " in function '" + MF.getName() + "'");
+ Name + " in function '" + MF.getName() + "'");
Error = true;
break;
case VRegInfo::NORMAL:
@@ -532,6 +531,17 @@
MRI.setRegBank(Reg, *Info.D.RegBank);
break;
}
+ };
+
+ for (auto I = PFS.VRegInfosNamed.begin(), E = PFS.VRegInfosNamed.end();
+ I != E; I++) {
+ const VRegInfo &Info = *I->second;
+ populateVRegInfo(Info, Twine(I->first()));
+ }
+
+ for (auto P : PFS.VRegInfos) {
+ const VRegInfo &Info = *P.second;
+ populateVRegInfo(Info, Twine(P.first));
}
// Compute MachineRegisterInfo::UsedPhysRegMask
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 25cf937..8452b4e 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -267,6 +267,8 @@
unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
yaml::VirtualRegisterDefinition VReg;
VReg.ID = I;
+ if (RegInfo.getVRegName(Reg) != "")
+ continue;
::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);
unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
if (PreferredReg)
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index 654a831..cda9235 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -739,7 +739,15 @@
OS << "debug-use ";
if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable())
OS << "renamable ";
- OS << printReg(Reg, TRI);
+
+ const MachineRegisterInfo *MRI = nullptr;
+ if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+ if (const MachineFunction *MF = getMFIfAvailable(*this)) {
+ MRI = &MF->getRegInfo();
+ }
+ }
+
+ OS << printReg(Reg, TRI, 0, MRI);
// Print the sub register.
if (unsigned SubReg = getSubReg()) {
if (TRI)
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 983822b..725e5f4 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -150,10 +150,11 @@
return true;
}
-unsigned MachineRegisterInfo::createIncompleteVirtualRegister() {
+unsigned MachineRegisterInfo::createIncompleteVirtualRegister(StringRef Name) {
unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs());
VRegInfo.grow(Reg);
RegAllocHints.grow(Reg);
+ insertVRegByName(Name, Reg);
return Reg;
}
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index f7ef444..c824eab 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -86,14 +86,20 @@
namespace llvm {
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI,
- unsigned SubIdx) {
- return Printable([Reg, TRI, SubIdx](raw_ostream &OS) {
+ unsigned SubIdx, const MachineRegisterInfo *MRI) {
+ return Printable([Reg, TRI, SubIdx, MRI](raw_ostream &OS) {
if (!Reg)
OS << "$noreg";
else if (TargetRegisterInfo::isStackSlot(Reg))
OS << "SS#" << TargetRegisterInfo::stackSlot2Index(Reg);
- else if (TargetRegisterInfo::isVirtualRegister(Reg))
- OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
+ else if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+ StringRef Name = MRI ? MRI->getVRegName(Reg) : "";
+ if (Name != "") {
+ OS << '%' << Name;
+ } else {
+ OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
+ }
+ }
else if (!TRI)
OS << '$' << "physreg" << Reg;
else if (Reg < TRI->getNumRegs()) {