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 
93*15a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS,
94*15a00a85SAlex Lorenz                      const TargetRegisterInfo *TRI) {
95*15a00a85SAlex Lorenz   // TODO: Print Stack Slots.
96*15a00a85SAlex Lorenz   if (!Reg)
97*15a00a85SAlex Lorenz     OS << '_';
98*15a00a85SAlex Lorenz   else if (TargetRegisterInfo::isVirtualRegister(Reg))
99*15a00a85SAlex Lorenz     OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
100*15a00a85SAlex Lorenz   else if (Reg < TRI->getNumRegs())
101*15a00a85SAlex Lorenz     OS << '%' << StringRef(TRI->getName(Reg)).lower();
102*15a00a85SAlex Lorenz   else
103*15a00a85SAlex Lorenz     llvm_unreachable("Can't print this kind of register yet");
104*15a00a85SAlex Lorenz }
105*15a00a85SAlex Lorenz 
106345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) {
1078f6f4285SAlex Lorenz   initRegisterMaskIds(MF);
1088f6f4285SAlex Lorenz 
109345c1449SAlex Lorenz   yaml::MachineFunction YamlMF;
110345c1449SAlex Lorenz   YamlMF.Name = MF.getName();
1115b5f9753SAlex Lorenz   YamlMF.Alignment = MF.getAlignment();
1125b5f9753SAlex Lorenz   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
1135b5f9753SAlex Lorenz   YamlMF.HasInlineAsm = MF.hasInlineAsm();
11428148ba8SAlex Lorenz   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
11560541c1dSAlex Lorenz   convert(YamlMF.FrameInfo, *MF.getFrameInfo());
116f6bc8667SAlex Lorenz   convertStackObjects(YamlMF, *MF.getFrameInfo());
11733f0aef3SAlex Lorenz 
11833f0aef3SAlex Lorenz   int I = 0;
119900b5cb2SAlex Lorenz   ModuleSlotTracker MST(MF.getFunction()->getParent());
1204f093bf1SAlex Lorenz   for (const auto &MBB : MF) {
12133f0aef3SAlex Lorenz     // TODO: Allow printing of non sequentially numbered MBBs.
12233f0aef3SAlex Lorenz     // This is currently needed as the basic block references get their index
12333f0aef3SAlex Lorenz     // from MBB.getNumber(), thus it should be sequential so that the parser can
12433f0aef3SAlex Lorenz     // map back to the correct MBBs when parsing the output.
12533f0aef3SAlex Lorenz     assert(MBB.getNumber() == I++ &&
12633f0aef3SAlex Lorenz            "Can't print MBBs that aren't sequentially numbered");
127ec6b26b9SAlex Lorenz     (void)I;
1284f093bf1SAlex Lorenz     yaml::MachineBasicBlock YamlMBB;
129900b5cb2SAlex Lorenz     convert(MST, YamlMBB, MBB);
1304f093bf1SAlex Lorenz     YamlMF.BasicBlocks.push_back(YamlMBB);
1314f093bf1SAlex Lorenz   }
132345c1449SAlex Lorenz   yaml::Output Out(OS);
133345c1449SAlex Lorenz   Out << YamlMF;
134345c1449SAlex Lorenz }
135345c1449SAlex Lorenz 
13654565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
13728148ba8SAlex Lorenz                          const MachineRegisterInfo &RegInfo,
13828148ba8SAlex Lorenz                          const TargetRegisterInfo *TRI) {
13954565cf0SAlex Lorenz   MF.IsSSA = RegInfo.isSSA();
14054565cf0SAlex Lorenz   MF.TracksRegLiveness = RegInfo.tracksLiveness();
14154565cf0SAlex Lorenz   MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
14228148ba8SAlex Lorenz 
14328148ba8SAlex Lorenz   // Print the virtual register definitions.
14428148ba8SAlex Lorenz   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
14528148ba8SAlex Lorenz     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
14628148ba8SAlex Lorenz     yaml::VirtualRegisterDefinition VReg;
14728148ba8SAlex Lorenz     VReg.ID = I;
14828148ba8SAlex Lorenz     VReg.Class =
14928148ba8SAlex Lorenz         StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
15028148ba8SAlex Lorenz     MF.VirtualRegisters.push_back(VReg);
15128148ba8SAlex Lorenz   }
15254565cf0SAlex Lorenz }
15354565cf0SAlex Lorenz 
15460541c1dSAlex Lorenz void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
15560541c1dSAlex Lorenz                          const MachineFrameInfo &MFI) {
15660541c1dSAlex Lorenz   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
15760541c1dSAlex Lorenz   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
15860541c1dSAlex Lorenz   YamlMFI.HasStackMap = MFI.hasStackMap();
15960541c1dSAlex Lorenz   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
16060541c1dSAlex Lorenz   YamlMFI.StackSize = MFI.getStackSize();
16160541c1dSAlex Lorenz   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
16260541c1dSAlex Lorenz   YamlMFI.MaxAlignment = MFI.getMaxAlignment();
16360541c1dSAlex Lorenz   YamlMFI.AdjustsStack = MFI.adjustsStack();
16460541c1dSAlex Lorenz   YamlMFI.HasCalls = MFI.hasCalls();
16560541c1dSAlex Lorenz   YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
16660541c1dSAlex Lorenz   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
16760541c1dSAlex Lorenz   YamlMFI.HasVAStart = MFI.hasVAStart();
16860541c1dSAlex Lorenz   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
16960541c1dSAlex Lorenz }
17060541c1dSAlex Lorenz 
171f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
172f6bc8667SAlex Lorenz                                      const MachineFrameInfo &MFI) {
173de491f05SAlex Lorenz   // Process fixed stack objects.
174f6bc8667SAlex Lorenz   unsigned ID = 0;
175de491f05SAlex Lorenz   for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
176de491f05SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
177de491f05SAlex Lorenz       continue;
178de491f05SAlex Lorenz 
179de491f05SAlex Lorenz     yaml::FixedMachineStackObject YamlObject;
180de491f05SAlex Lorenz     YamlObject.ID = ID++;
181de491f05SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
182de491f05SAlex Lorenz                           ? yaml::FixedMachineStackObject::SpillSlot
183de491f05SAlex Lorenz                           : yaml::FixedMachineStackObject::DefaultType;
184de491f05SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
185de491f05SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
186de491f05SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
187de491f05SAlex Lorenz     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
188de491f05SAlex Lorenz     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
189de491f05SAlex Lorenz     MF.FixedStackObjects.push_back(YamlObject);
190de491f05SAlex Lorenz     // TODO: Store the mapping between fixed object IDs and object indices to
191de491f05SAlex Lorenz     // print the fixed stack object references correctly.
192de491f05SAlex Lorenz   }
193de491f05SAlex Lorenz 
194de491f05SAlex Lorenz   // Process ordinary stack objects.
195de491f05SAlex Lorenz   ID = 0;
196f6bc8667SAlex Lorenz   for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
197f6bc8667SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
198f6bc8667SAlex Lorenz       continue;
199f6bc8667SAlex Lorenz 
200f6bc8667SAlex Lorenz     yaml::MachineStackObject YamlObject;
201f6bc8667SAlex Lorenz     YamlObject.ID = ID++;
202f6bc8667SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
203f6bc8667SAlex Lorenz                           ? yaml::MachineStackObject::SpillSlot
204418f3ec1SAlex Lorenz                           : MFI.isVariableSizedObjectIndex(I)
205418f3ec1SAlex Lorenz                                 ? yaml::MachineStackObject::VariableSized
206f6bc8667SAlex Lorenz                                 : yaml::MachineStackObject::DefaultType;
207f6bc8667SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
208f6bc8667SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
209f6bc8667SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
210f6bc8667SAlex Lorenz 
211f6bc8667SAlex Lorenz     MF.StackObjects.push_back(YamlObject);
212f6bc8667SAlex Lorenz     // TODO: Store the mapping between object IDs and object indices to print
213f6bc8667SAlex Lorenz     // the stack object references correctly.
214f6bc8667SAlex Lorenz   }
215f6bc8667SAlex Lorenz }
216f6bc8667SAlex Lorenz 
217900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
218900b5cb2SAlex Lorenz                          yaml::MachineBasicBlock &YamlMBB,
2194f093bf1SAlex Lorenz                          const MachineBasicBlock &MBB) {
22033f0aef3SAlex Lorenz   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
22133f0aef3SAlex Lorenz   YamlMBB.ID = (unsigned)MBB.getNumber();
2224f093bf1SAlex Lorenz   // TODO: Serialize unnamed BB references.
2234f093bf1SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock())
224b1f9ce8fSAlex Lorenz     YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>";
2254f093bf1SAlex Lorenz   else
226b1f9ce8fSAlex Lorenz     YamlMBB.Name.Value = "";
2274f093bf1SAlex Lorenz   YamlMBB.Alignment = MBB.getAlignment();
2284f093bf1SAlex Lorenz   YamlMBB.AddressTaken = MBB.hasAddressTaken();
2294f093bf1SAlex Lorenz   YamlMBB.IsLandingPad = MBB.isLandingPad();
230eb5112bfSAlex Lorenz   for (const auto *SuccMBB : MBB.successors()) {
231f09df00dSAlex Lorenz     std::string Str;
232f09df00dSAlex Lorenz     raw_string_ostream StrOS(Str);
233900b5cb2SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds).printMBBReference(*SuccMBB);
234f09df00dSAlex Lorenz     YamlMBB.Successors.push_back(StrOS.str());
235f09df00dSAlex Lorenz   }
2368e0a1b48SAlex Lorenz 
2378e0a1b48SAlex Lorenz   // Print the machine instructions.
2388e0a1b48SAlex Lorenz   YamlMBB.Instructions.reserve(MBB.size());
2398e0a1b48SAlex Lorenz   std::string Str;
2408e0a1b48SAlex Lorenz   for (const auto &MI : MBB) {
2418e0a1b48SAlex Lorenz     raw_string_ostream StrOS(Str);
242900b5cb2SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds).print(MI);
2438e0a1b48SAlex Lorenz     YamlMBB.Instructions.push_back(StrOS.str());
2448e0a1b48SAlex Lorenz     Str.clear();
2458e0a1b48SAlex Lorenz   }
2468e0a1b48SAlex Lorenz }
2478e0a1b48SAlex Lorenz 
2488f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
2498f6f4285SAlex Lorenz   const auto *TRI = MF.getSubtarget().getRegisterInfo();
2508f6f4285SAlex Lorenz   unsigned I = 0;
2518f6f4285SAlex Lorenz   for (const uint32_t *Mask : TRI->getRegMasks())
2528f6f4285SAlex Lorenz     RegisterMaskIds.insert(std::make_pair(Mask, I++));
2538f6f4285SAlex Lorenz }
2548f6f4285SAlex Lorenz 
2558e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) {
2568e0a1b48SAlex Lorenz   const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
257f3db51deSAlex Lorenz   const auto *TRI = SubTarget.getRegisterInfo();
258f3db51deSAlex Lorenz   assert(TRI && "Expected target register info");
2598e0a1b48SAlex Lorenz   const auto *TII = SubTarget.getInstrInfo();
2608e0a1b48SAlex Lorenz   assert(TII && "Expected target instruction info");
2618e0a1b48SAlex Lorenz 
262f3db51deSAlex Lorenz   unsigned I = 0, E = MI.getNumOperands();
263f3db51deSAlex Lorenz   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
264f3db51deSAlex Lorenz          !MI.getOperand(I).isImplicit();
265f3db51deSAlex Lorenz        ++I) {
266f3db51deSAlex Lorenz     if (I)
267f3db51deSAlex Lorenz       OS << ", ";
268f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
269f3db51deSAlex Lorenz   }
270f3db51deSAlex Lorenz 
271f3db51deSAlex Lorenz   if (I)
272f3db51deSAlex Lorenz     OS << " = ";
2738e0a1b48SAlex Lorenz   OS << TII->getName(MI.getOpcode());
274f3db51deSAlex Lorenz   // TODO: Print the instruction flags, machine mem operands.
275f3db51deSAlex Lorenz   if (I < E)
276f3db51deSAlex Lorenz     OS << ' ';
277f3db51deSAlex Lorenz 
278f3db51deSAlex Lorenz   bool NeedComma = false;
279f3db51deSAlex Lorenz   for (; I < E; ++I) {
280f3db51deSAlex Lorenz     if (NeedComma)
281f3db51deSAlex Lorenz       OS << ", ";
282f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
283f3db51deSAlex Lorenz     NeedComma = true;
284f3db51deSAlex Lorenz   }
285f3db51deSAlex Lorenz }
286f3db51deSAlex Lorenz 
2875d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
2885d26fa83SAlex Lorenz   OS << "%bb." << MBB.getNumber();
2895d26fa83SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
2905d26fa83SAlex Lorenz     if (BB->hasName())
2915d26fa83SAlex Lorenz       OS << '.' << BB->getName();
2925d26fa83SAlex Lorenz   }
2935d26fa83SAlex Lorenz }
2945d26fa83SAlex Lorenz 
295f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
296f3db51deSAlex Lorenz   switch (Op.getType()) {
297f3db51deSAlex Lorenz   case MachineOperand::MO_Register:
298cb268d46SAlex Lorenz     // TODO: Print the other register flags.
299cb268d46SAlex Lorenz     if (Op.isImplicit())
300cb268d46SAlex Lorenz       OS << (Op.isDef() ? "implicit-def " : "implicit ");
301cbbfd0b1SAlex Lorenz     if (Op.isDead())
302cbbfd0b1SAlex Lorenz       OS << "dead ";
303495ad879SAlex Lorenz     if (Op.isKill())
304495ad879SAlex Lorenz       OS << "killed ";
3054d026b89SAlex Lorenz     if (Op.isUndef())
3064d026b89SAlex Lorenz       OS << "undef ";
307f3db51deSAlex Lorenz     printReg(Op.getReg(), OS, TRI);
3082eacca86SAlex Lorenz     // Print the sub register.
3092eacca86SAlex Lorenz     if (Op.getSubReg() != 0)
3102eacca86SAlex Lorenz       OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
311f3db51deSAlex Lorenz     break;
312240fc1e0SAlex Lorenz   case MachineOperand::MO_Immediate:
313240fc1e0SAlex Lorenz     OS << Op.getImm();
314240fc1e0SAlex Lorenz     break;
31533f0aef3SAlex Lorenz   case MachineOperand::MO_MachineBasicBlock:
3165d26fa83SAlex Lorenz     printMBBReference(*Op.getMBB());
31733f0aef3SAlex Lorenz     break;
3185d6108e4SAlex Lorenz   case MachineOperand::MO_GlobalAddress:
319900b5cb2SAlex Lorenz     Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
3205d6108e4SAlex Lorenz     // TODO: Print offset and target flags.
3215d6108e4SAlex Lorenz     break;
3228f6f4285SAlex Lorenz   case MachineOperand::MO_RegisterMask: {
3238f6f4285SAlex Lorenz     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
3248f6f4285SAlex Lorenz     if (RegMaskInfo != RegisterMaskIds.end())
3258f6f4285SAlex Lorenz       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
3268f6f4285SAlex Lorenz     else
3278f6f4285SAlex Lorenz       llvm_unreachable("Can't print this machine register mask yet.");
3288f6f4285SAlex Lorenz     break;
3298f6f4285SAlex Lorenz   }
330f3db51deSAlex Lorenz   default:
331f3db51deSAlex Lorenz     // TODO: Print the other machine operands.
332f3db51deSAlex Lorenz     llvm_unreachable("Can't print this machine operand at the moment");
333f3db51deSAlex Lorenz   }
3344f093bf1SAlex Lorenz }
3354f093bf1SAlex Lorenz 
336345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) {
337345c1449SAlex Lorenz   yaml::Output Out(OS);
338345c1449SAlex Lorenz   Out << const_cast<Module &>(M);
339345c1449SAlex Lorenz }
340345c1449SAlex Lorenz 
341345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
342345c1449SAlex Lorenz   MIRPrinter Printer(OS);
343345c1449SAlex Lorenz   Printer.print(MF);
344345c1449SAlex Lorenz }
345