1345c1449SAlex Lorenz //===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
2345c1449SAlex Lorenz //
3345c1449SAlex Lorenz //                     The LLVM Compiler Infrastructure
4345c1449SAlex Lorenz //
5345c1449SAlex Lorenz // This file is distributed under the University of Illinois Open Source
6345c1449SAlex Lorenz // License. See LICENSE.TXT for details.
7345c1449SAlex Lorenz //
8345c1449SAlex Lorenz //===----------------------------------------------------------------------===//
9345c1449SAlex Lorenz //
10345c1449SAlex Lorenz // This file implements the class that prints out the LLVM IR and machine
11345c1449SAlex Lorenz // functions using the MIR serialization format.
12345c1449SAlex Lorenz //
13345c1449SAlex Lorenz //===----------------------------------------------------------------------===//
14345c1449SAlex Lorenz 
15345c1449SAlex Lorenz #include "MIRPrinter.h"
16345c1449SAlex Lorenz #include "llvm/ADT/STLExtras.h"
17345c1449SAlex Lorenz #include "llvm/CodeGen/MachineFunction.h"
1860541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h"
1954565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h"
20345c1449SAlex Lorenz #include "llvm/CodeGen/MIRYamlMapping.h"
214f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h"
22345c1449SAlex Lorenz #include "llvm/IR/Module.h"
23900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h"
24345c1449SAlex Lorenz #include "llvm/Support/MemoryBuffer.h"
25345c1449SAlex Lorenz #include "llvm/Support/raw_ostream.h"
26345c1449SAlex Lorenz #include "llvm/Support/YAMLTraits.h"
278e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h"
288e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h"
29345c1449SAlex Lorenz 
30345c1449SAlex Lorenz using namespace llvm;
31345c1449SAlex Lorenz 
32345c1449SAlex Lorenz namespace {
33345c1449SAlex Lorenz 
34345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization
35345c1449SAlex Lorenz /// format.
36345c1449SAlex Lorenz class MIRPrinter {
37345c1449SAlex Lorenz   raw_ostream &OS;
388f6f4285SAlex Lorenz   DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
39345c1449SAlex Lorenz 
40345c1449SAlex Lorenz public:
41345c1449SAlex Lorenz   MIRPrinter(raw_ostream &OS) : OS(OS) {}
42345c1449SAlex Lorenz 
43345c1449SAlex Lorenz   void print(const MachineFunction &MF);
444f093bf1SAlex Lorenz 
4528148ba8SAlex Lorenz   void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
4628148ba8SAlex Lorenz                const TargetRegisterInfo *TRI);
4760541c1dSAlex Lorenz   void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
48900b5cb2SAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
495d6108e4SAlex Lorenz                const MachineBasicBlock &MBB);
50f6bc8667SAlex Lorenz   void convertStackObjects(yaml::MachineFunction &MF,
51f6bc8667SAlex Lorenz                            const MachineFrameInfo &MFI);
528f6f4285SAlex Lorenz 
538f6f4285SAlex Lorenz private:
548f6f4285SAlex Lorenz   void initRegisterMaskIds(const MachineFunction &MF);
55345c1449SAlex Lorenz };
56345c1449SAlex Lorenz 
578e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization
588e0a1b48SAlex Lorenz /// format.
598e0a1b48SAlex Lorenz class MIPrinter {
608e0a1b48SAlex Lorenz   raw_ostream &OS;
61900b5cb2SAlex Lorenz   ModuleSlotTracker &MST;
628f6f4285SAlex Lorenz   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
638e0a1b48SAlex Lorenz 
648e0a1b48SAlex Lorenz public:
65900b5cb2SAlex Lorenz   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
668f6f4285SAlex Lorenz             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds)
67900b5cb2SAlex Lorenz       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds) {}
688e0a1b48SAlex Lorenz 
698e0a1b48SAlex Lorenz   void print(const MachineInstr &MI);
705d26fa83SAlex Lorenz   void printMBBReference(const MachineBasicBlock &MBB);
71f3db51deSAlex Lorenz   void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
728e0a1b48SAlex Lorenz };
738e0a1b48SAlex Lorenz 
74345c1449SAlex Lorenz } // end anonymous namespace
75345c1449SAlex Lorenz 
76345c1449SAlex Lorenz namespace llvm {
77345c1449SAlex Lorenz namespace yaml {
78345c1449SAlex Lorenz 
79345c1449SAlex Lorenz /// This struct serializes the LLVM IR module.
80345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> {
81345c1449SAlex Lorenz   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
82345c1449SAlex Lorenz     Mod.print(OS, nullptr);
83345c1449SAlex Lorenz   }
84345c1449SAlex Lorenz   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
85345c1449SAlex Lorenz     llvm_unreachable("LLVM Module is supposed to be parsed separately");
86345c1449SAlex Lorenz     return "";
87345c1449SAlex Lorenz   }
88345c1449SAlex Lorenz };
89345c1449SAlex Lorenz 
90345c1449SAlex Lorenz } // end namespace yaml
91345c1449SAlex Lorenz } // end namespace llvm
92345c1449SAlex Lorenz 
93345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) {
948f6f4285SAlex Lorenz   initRegisterMaskIds(MF);
958f6f4285SAlex Lorenz 
96345c1449SAlex Lorenz   yaml::MachineFunction YamlMF;
97345c1449SAlex Lorenz   YamlMF.Name = MF.getName();
985b5f9753SAlex Lorenz   YamlMF.Alignment = MF.getAlignment();
995b5f9753SAlex Lorenz   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
1005b5f9753SAlex Lorenz   YamlMF.HasInlineAsm = MF.hasInlineAsm();
10128148ba8SAlex Lorenz   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
10260541c1dSAlex Lorenz   convert(YamlMF.FrameInfo, *MF.getFrameInfo());
103f6bc8667SAlex Lorenz   convertStackObjects(YamlMF, *MF.getFrameInfo());
10433f0aef3SAlex Lorenz 
10533f0aef3SAlex Lorenz   int I = 0;
106900b5cb2SAlex Lorenz   ModuleSlotTracker MST(MF.getFunction()->getParent());
1074f093bf1SAlex Lorenz   for (const auto &MBB : MF) {
10833f0aef3SAlex Lorenz     // TODO: Allow printing of non sequentially numbered MBBs.
10933f0aef3SAlex Lorenz     // This is currently needed as the basic block references get their index
11033f0aef3SAlex Lorenz     // from MBB.getNumber(), thus it should be sequential so that the parser can
11133f0aef3SAlex Lorenz     // map back to the correct MBBs when parsing the output.
11233f0aef3SAlex Lorenz     assert(MBB.getNumber() == I++ &&
11333f0aef3SAlex Lorenz            "Can't print MBBs that aren't sequentially numbered");
114ec6b26b9SAlex Lorenz     (void)I;
1154f093bf1SAlex Lorenz     yaml::MachineBasicBlock YamlMBB;
116900b5cb2SAlex Lorenz     convert(MST, YamlMBB, MBB);
1174f093bf1SAlex Lorenz     YamlMF.BasicBlocks.push_back(YamlMBB);
1184f093bf1SAlex Lorenz   }
119345c1449SAlex Lorenz   yaml::Output Out(OS);
120345c1449SAlex Lorenz   Out << YamlMF;
121345c1449SAlex Lorenz }
122345c1449SAlex Lorenz 
12354565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
12428148ba8SAlex Lorenz                          const MachineRegisterInfo &RegInfo,
12528148ba8SAlex Lorenz                          const TargetRegisterInfo *TRI) {
12654565cf0SAlex Lorenz   MF.IsSSA = RegInfo.isSSA();
12754565cf0SAlex Lorenz   MF.TracksRegLiveness = RegInfo.tracksLiveness();
12854565cf0SAlex Lorenz   MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
12928148ba8SAlex Lorenz 
13028148ba8SAlex Lorenz   // Print the virtual register definitions.
13128148ba8SAlex Lorenz   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
13228148ba8SAlex Lorenz     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
13328148ba8SAlex Lorenz     yaml::VirtualRegisterDefinition VReg;
13428148ba8SAlex Lorenz     VReg.ID = I;
13528148ba8SAlex Lorenz     VReg.Class =
13628148ba8SAlex Lorenz         StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
13728148ba8SAlex Lorenz     MF.VirtualRegisters.push_back(VReg);
13828148ba8SAlex Lorenz   }
13954565cf0SAlex Lorenz }
14054565cf0SAlex Lorenz 
14160541c1dSAlex Lorenz void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
14260541c1dSAlex Lorenz                          const MachineFrameInfo &MFI) {
14360541c1dSAlex Lorenz   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
14460541c1dSAlex Lorenz   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
14560541c1dSAlex Lorenz   YamlMFI.HasStackMap = MFI.hasStackMap();
14660541c1dSAlex Lorenz   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
14760541c1dSAlex Lorenz   YamlMFI.StackSize = MFI.getStackSize();
14860541c1dSAlex Lorenz   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
14960541c1dSAlex Lorenz   YamlMFI.MaxAlignment = MFI.getMaxAlignment();
15060541c1dSAlex Lorenz   YamlMFI.AdjustsStack = MFI.adjustsStack();
15160541c1dSAlex Lorenz   YamlMFI.HasCalls = MFI.hasCalls();
15260541c1dSAlex Lorenz   YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
15360541c1dSAlex Lorenz   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
15460541c1dSAlex Lorenz   YamlMFI.HasVAStart = MFI.hasVAStart();
15560541c1dSAlex Lorenz   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
15660541c1dSAlex Lorenz }
15760541c1dSAlex Lorenz 
158f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
159f6bc8667SAlex Lorenz                                      const MachineFrameInfo &MFI) {
160*de491f05SAlex Lorenz   // Process fixed stack objects.
161f6bc8667SAlex Lorenz   unsigned ID = 0;
162*de491f05SAlex Lorenz   for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
163*de491f05SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
164*de491f05SAlex Lorenz       continue;
165*de491f05SAlex Lorenz 
166*de491f05SAlex Lorenz     yaml::FixedMachineStackObject YamlObject;
167*de491f05SAlex Lorenz     YamlObject.ID = ID++;
168*de491f05SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
169*de491f05SAlex Lorenz                           ? yaml::FixedMachineStackObject::SpillSlot
170*de491f05SAlex Lorenz                           : yaml::FixedMachineStackObject::DefaultType;
171*de491f05SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
172*de491f05SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
173*de491f05SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
174*de491f05SAlex Lorenz     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
175*de491f05SAlex Lorenz     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
176*de491f05SAlex Lorenz     MF.FixedStackObjects.push_back(YamlObject);
177*de491f05SAlex Lorenz     // TODO: Store the mapping between fixed object IDs and object indices to
178*de491f05SAlex Lorenz     // print the fixed stack object references correctly.
179*de491f05SAlex Lorenz   }
180*de491f05SAlex Lorenz 
181*de491f05SAlex Lorenz   // Process ordinary stack objects.
182*de491f05SAlex Lorenz   ID = 0;
183f6bc8667SAlex Lorenz   for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
184f6bc8667SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
185f6bc8667SAlex Lorenz       continue;
186f6bc8667SAlex Lorenz 
187f6bc8667SAlex Lorenz     yaml::MachineStackObject YamlObject;
188f6bc8667SAlex Lorenz     YamlObject.ID = ID++;
189f6bc8667SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
190f6bc8667SAlex Lorenz                           ? yaml::MachineStackObject::SpillSlot
191f6bc8667SAlex Lorenz                           : yaml::MachineStackObject::DefaultType;
192f6bc8667SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
193f6bc8667SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
194f6bc8667SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
195f6bc8667SAlex Lorenz 
196f6bc8667SAlex Lorenz     MF.StackObjects.push_back(YamlObject);
197f6bc8667SAlex Lorenz     // TODO: Store the mapping between object IDs and object indices to print
198f6bc8667SAlex Lorenz     // the stack object references correctly.
199f6bc8667SAlex Lorenz   }
200f6bc8667SAlex Lorenz }
201f6bc8667SAlex Lorenz 
202900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
203900b5cb2SAlex Lorenz                          yaml::MachineBasicBlock &YamlMBB,
2044f093bf1SAlex Lorenz                          const MachineBasicBlock &MBB) {
20533f0aef3SAlex Lorenz   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
20633f0aef3SAlex Lorenz   YamlMBB.ID = (unsigned)MBB.getNumber();
2074f093bf1SAlex Lorenz   // TODO: Serialize unnamed BB references.
2084f093bf1SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock())
209b1f9ce8fSAlex Lorenz     YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>";
2104f093bf1SAlex Lorenz   else
211b1f9ce8fSAlex Lorenz     YamlMBB.Name.Value = "";
2124f093bf1SAlex Lorenz   YamlMBB.Alignment = MBB.getAlignment();
2134f093bf1SAlex Lorenz   YamlMBB.AddressTaken = MBB.hasAddressTaken();
2144f093bf1SAlex Lorenz   YamlMBB.IsLandingPad = MBB.isLandingPad();
215eb5112bfSAlex Lorenz   for (const auto *SuccMBB : MBB.successors()) {
216f09df00dSAlex Lorenz     std::string Str;
217f09df00dSAlex Lorenz     raw_string_ostream StrOS(Str);
218900b5cb2SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds).printMBBReference(*SuccMBB);
219f09df00dSAlex Lorenz     YamlMBB.Successors.push_back(StrOS.str());
220f09df00dSAlex Lorenz   }
2218e0a1b48SAlex Lorenz 
2228e0a1b48SAlex Lorenz   // Print the machine instructions.
2238e0a1b48SAlex Lorenz   YamlMBB.Instructions.reserve(MBB.size());
2248e0a1b48SAlex Lorenz   std::string Str;
2258e0a1b48SAlex Lorenz   for (const auto &MI : MBB) {
2268e0a1b48SAlex Lorenz     raw_string_ostream StrOS(Str);
227900b5cb2SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds).print(MI);
2288e0a1b48SAlex Lorenz     YamlMBB.Instructions.push_back(StrOS.str());
2298e0a1b48SAlex Lorenz     Str.clear();
2308e0a1b48SAlex Lorenz   }
2318e0a1b48SAlex Lorenz }
2328e0a1b48SAlex Lorenz 
2338f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
2348f6f4285SAlex Lorenz   const auto *TRI = MF.getSubtarget().getRegisterInfo();
2358f6f4285SAlex Lorenz   unsigned I = 0;
2368f6f4285SAlex Lorenz   for (const uint32_t *Mask : TRI->getRegMasks())
2378f6f4285SAlex Lorenz     RegisterMaskIds.insert(std::make_pair(Mask, I++));
2388f6f4285SAlex Lorenz }
2398f6f4285SAlex Lorenz 
2408e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) {
2418e0a1b48SAlex Lorenz   const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
242f3db51deSAlex Lorenz   const auto *TRI = SubTarget.getRegisterInfo();
243f3db51deSAlex Lorenz   assert(TRI && "Expected target register info");
2448e0a1b48SAlex Lorenz   const auto *TII = SubTarget.getInstrInfo();
2458e0a1b48SAlex Lorenz   assert(TII && "Expected target instruction info");
2468e0a1b48SAlex Lorenz 
247f3db51deSAlex Lorenz   unsigned I = 0, E = MI.getNumOperands();
248f3db51deSAlex Lorenz   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
249f3db51deSAlex Lorenz          !MI.getOperand(I).isImplicit();
250f3db51deSAlex Lorenz        ++I) {
251f3db51deSAlex Lorenz     if (I)
252f3db51deSAlex Lorenz       OS << ", ";
253f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
254f3db51deSAlex Lorenz   }
255f3db51deSAlex Lorenz 
256f3db51deSAlex Lorenz   if (I)
257f3db51deSAlex Lorenz     OS << " = ";
2588e0a1b48SAlex Lorenz   OS << TII->getName(MI.getOpcode());
259f3db51deSAlex Lorenz   // TODO: Print the instruction flags, machine mem operands.
260f3db51deSAlex Lorenz   if (I < E)
261f3db51deSAlex Lorenz     OS << ' ';
262f3db51deSAlex Lorenz 
263f3db51deSAlex Lorenz   bool NeedComma = false;
264f3db51deSAlex Lorenz   for (; I < E; ++I) {
265f3db51deSAlex Lorenz     if (NeedComma)
266f3db51deSAlex Lorenz       OS << ", ";
267f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
268f3db51deSAlex Lorenz     NeedComma = true;
269f3db51deSAlex Lorenz   }
270f3db51deSAlex Lorenz }
271f3db51deSAlex Lorenz 
272f3db51deSAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS,
273f3db51deSAlex Lorenz                      const TargetRegisterInfo *TRI) {
274f3db51deSAlex Lorenz   // TODO: Print Stack Slots.
27512b554e6SAlex Lorenz   if (!Reg)
27612b554e6SAlex Lorenz     OS << '_';
27753464510SAlex Lorenz   else if (TargetRegisterInfo::isVirtualRegister(Reg))
27853464510SAlex Lorenz     OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
27912b554e6SAlex Lorenz   else if (Reg < TRI->getNumRegs())
280f3db51deSAlex Lorenz     OS << '%' << StringRef(TRI->getName(Reg)).lower();
281f3db51deSAlex Lorenz   else
282f3db51deSAlex Lorenz     llvm_unreachable("Can't print this kind of register yet");
283f3db51deSAlex Lorenz }
284f3db51deSAlex Lorenz 
2855d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
2865d26fa83SAlex Lorenz   OS << "%bb." << MBB.getNumber();
2875d26fa83SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
2885d26fa83SAlex Lorenz     if (BB->hasName())
2895d26fa83SAlex Lorenz       OS << '.' << BB->getName();
2905d26fa83SAlex Lorenz   }
2915d26fa83SAlex Lorenz }
2925d26fa83SAlex Lorenz 
293f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
294f3db51deSAlex Lorenz   switch (Op.getType()) {
295f3db51deSAlex Lorenz   case MachineOperand::MO_Register:
296cb268d46SAlex Lorenz     // TODO: Print the other register flags.
297cb268d46SAlex Lorenz     if (Op.isImplicit())
298cb268d46SAlex Lorenz       OS << (Op.isDef() ? "implicit-def " : "implicit ");
299cbbfd0b1SAlex Lorenz     if (Op.isDead())
300cbbfd0b1SAlex Lorenz       OS << "dead ";
301495ad879SAlex Lorenz     if (Op.isKill())
302495ad879SAlex Lorenz       OS << "killed ";
3034d026b89SAlex Lorenz     if (Op.isUndef())
3044d026b89SAlex Lorenz       OS << "undef ";
305f3db51deSAlex Lorenz     printReg(Op.getReg(), OS, TRI);
306f3db51deSAlex Lorenz     // TODO: Print sub register.
307f3db51deSAlex Lorenz     break;
308240fc1e0SAlex Lorenz   case MachineOperand::MO_Immediate:
309240fc1e0SAlex Lorenz     OS << Op.getImm();
310240fc1e0SAlex Lorenz     break;
31133f0aef3SAlex Lorenz   case MachineOperand::MO_MachineBasicBlock:
3125d26fa83SAlex Lorenz     printMBBReference(*Op.getMBB());
31333f0aef3SAlex Lorenz     break;
3145d6108e4SAlex Lorenz   case MachineOperand::MO_GlobalAddress:
315900b5cb2SAlex Lorenz     Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
3165d6108e4SAlex Lorenz     // TODO: Print offset and target flags.
3175d6108e4SAlex Lorenz     break;
3188f6f4285SAlex Lorenz   case MachineOperand::MO_RegisterMask: {
3198f6f4285SAlex Lorenz     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
3208f6f4285SAlex Lorenz     if (RegMaskInfo != RegisterMaskIds.end())
3218f6f4285SAlex Lorenz       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
3228f6f4285SAlex Lorenz     else
3238f6f4285SAlex Lorenz       llvm_unreachable("Can't print this machine register mask yet.");
3248f6f4285SAlex Lorenz     break;
3258f6f4285SAlex Lorenz   }
326f3db51deSAlex Lorenz   default:
327f3db51deSAlex Lorenz     // TODO: Print the other machine operands.
328f3db51deSAlex Lorenz     llvm_unreachable("Can't print this machine operand at the moment");
329f3db51deSAlex Lorenz   }
3304f093bf1SAlex Lorenz }
3314f093bf1SAlex Lorenz 
332345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) {
333345c1449SAlex Lorenz   yaml::Output Out(OS);
334345c1449SAlex Lorenz   Out << const_cast<Module &>(M);
335345c1449SAlex Lorenz }
336345c1449SAlex Lorenz 
337345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
338345c1449SAlex Lorenz   MIRPrinter Printer(OS);
339345c1449SAlex Lorenz   Printer.print(MF);
340345c1449SAlex Lorenz }
341