MIR Serialization: Serialize the register mask machine operands.
This commit implements serialization of the register mask machine
operands. This commit serializes only the call preserved register
masks that are defined by a target, it doesn't serialize arbitrary
register masks.
This commit also extends the TargetRegisterInfo class and TableGen so that
the users of TRI can get the list of all the call preserved register masks and
their names.
Reviewers: Duncan P. N. Exon Smith
Differential Revision: http://reviews.llvm.org/D10673
llvm-svn: 240966
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 5e7871e..de74778 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -33,6 +33,7 @@
/// format.
class MIRPrinter {
raw_ostream &OS;
+ DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
public:
MIRPrinter(raw_ostream &OS) : OS(OS) {}
@@ -42,6 +43,9 @@
void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo);
void convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
const MachineBasicBlock &MBB);
+
+private:
+ void initRegisterMaskIds(const MachineFunction &MF);
};
/// This class prints out the machine instructions using the MIR serialization
@@ -49,9 +53,12 @@
class MIPrinter {
const Module &M;
raw_ostream &OS;
+ const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
public:
- MIPrinter(const Module &M, raw_ostream &OS) : M(M), OS(OS) {}
+ MIPrinter(const Module &M, raw_ostream &OS,
+ const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds)
+ : M(M), OS(OS), RegisterMaskIds(RegisterMaskIds) {}
void print(const MachineInstr &MI);
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
@@ -77,6 +84,8 @@
} // end namespace llvm
void MIRPrinter::print(const MachineFunction &MF) {
+ initRegisterMaskIds(MF);
+
yaml::MachineFunction YamlMF;
YamlMF.Name = MF.getName();
YamlMF.Alignment = MF.getAlignment();
@@ -127,12 +136,19 @@
std::string Str;
for (const auto &MI : MBB) {
raw_string_ostream StrOS(Str);
- MIPrinter(M, StrOS).print(MI);
+ MIPrinter(M, StrOS, RegisterMaskIds).print(MI);
YamlMBB.Instructions.push_back(StrOS.str());
Str.clear();
}
}
+void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
+ const auto *TRI = MF.getSubtarget().getRegisterInfo();
+ unsigned I = 0;
+ for (const uint32_t *Mask : TRI->getRegMasks())
+ RegisterMaskIds.insert(std::make_pair(Mask, I++));
+}
+
void MIPrinter::print(const MachineInstr &MI) {
const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
const auto *TRI = SubTarget.getRegisterInfo();
@@ -201,6 +217,14 @@
Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, &M);
// TODO: Print offset and target flags.
break;
+ case MachineOperand::MO_RegisterMask: {
+ auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
+ if (RegMaskInfo != RegisterMaskIds.end())
+ OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
+ else
+ llvm_unreachable("Can't print this machine register mask yet.");
+ break;
+ }
default:
// TODO: Print the other machine operands.
llvm_unreachable("Can't print this machine operand at the moment");