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"
17ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h"
18345c1449SAlex Lorenz #include "llvm/CodeGen/MachineFunction.h"
1960541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h"
204af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h"
21f4baeb51SAlex Lorenz #include "llvm/CodeGen/MachineModuleInfo.h"
2254565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h"
23345c1449SAlex Lorenz #include "llvm/CodeGen/MIRYamlMapping.h"
244f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h"
25deb53490SAlex Lorenz #include "llvm/IR/Constants.h"
2637643a04SAlex Lorenz #include "llvm/IR/Instructions.h"
276ede3744SAlex Lorenz #include "llvm/IR/IRPrintingPasses.h"
28345c1449SAlex Lorenz #include "llvm/IR/Module.h"
29900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h"
30345c1449SAlex Lorenz #include "llvm/Support/MemoryBuffer.h"
31345c1449SAlex Lorenz #include "llvm/Support/raw_ostream.h"
32345c1449SAlex Lorenz #include "llvm/Support/YAMLTraits.h"
338e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h"
348e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h"
35345c1449SAlex Lorenz 
36345c1449SAlex Lorenz using namespace llvm;
37345c1449SAlex Lorenz 
38345c1449SAlex Lorenz namespace {
39345c1449SAlex Lorenz 
407feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references.
417feaf7c6SAlex Lorenz struct FrameIndexOperand {
427feaf7c6SAlex Lorenz   std::string Name;
437feaf7c6SAlex Lorenz   unsigned ID;
447feaf7c6SAlex Lorenz   bool IsFixed;
457feaf7c6SAlex Lorenz 
467feaf7c6SAlex Lorenz   FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
477feaf7c6SAlex Lorenz       : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
487feaf7c6SAlex Lorenz 
497feaf7c6SAlex Lorenz   /// Return an ordinary stack object reference.
507feaf7c6SAlex Lorenz   static FrameIndexOperand create(StringRef Name, unsigned ID) {
517feaf7c6SAlex Lorenz     return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
527feaf7c6SAlex Lorenz   }
537feaf7c6SAlex Lorenz 
547feaf7c6SAlex Lorenz   /// Return a fixed stack object reference.
557feaf7c6SAlex Lorenz   static FrameIndexOperand createFixed(unsigned ID) {
567feaf7c6SAlex Lorenz     return FrameIndexOperand("", ID, /*IsFixed=*/true);
577feaf7c6SAlex Lorenz   }
587feaf7c6SAlex Lorenz };
597feaf7c6SAlex Lorenz 
60618b283cSAlex Lorenz } // end anonymous namespace
61618b283cSAlex Lorenz 
62618b283cSAlex Lorenz namespace llvm {
63618b283cSAlex Lorenz 
64345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization
65345c1449SAlex Lorenz /// format.
66345c1449SAlex Lorenz class MIRPrinter {
67345c1449SAlex Lorenz   raw_ostream &OS;
688f6f4285SAlex Lorenz   DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
697feaf7c6SAlex Lorenz   /// Maps from stack object indices to operand indices which will be used when
707feaf7c6SAlex Lorenz   /// printing frame index machine operands.
717feaf7c6SAlex Lorenz   DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
72345c1449SAlex Lorenz 
73345c1449SAlex Lorenz public:
74345c1449SAlex Lorenz   MIRPrinter(raw_ostream &OS) : OS(OS) {}
75345c1449SAlex Lorenz 
76345c1449SAlex Lorenz   void print(const MachineFunction &MF);
774f093bf1SAlex Lorenz 
7828148ba8SAlex Lorenz   void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
7928148ba8SAlex Lorenz                const TargetRegisterInfo *TRI);
80a6f9a37dSAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
81a6f9a37dSAlex Lorenz                const MachineFrameInfo &MFI);
82ab980499SAlex Lorenz   void convert(yaml::MachineFunction &MF,
83ab980499SAlex Lorenz                const MachineConstantPool &ConstantPool);
846799e9b3SAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
856799e9b3SAlex Lorenz                const MachineJumpTableInfo &JTI);
86f6bc8667SAlex Lorenz   void convertStackObjects(yaml::MachineFunction &MF,
871bb48de1SAlex Lorenz                            const MachineFrameInfo &MFI,
881bb48de1SAlex Lorenz                            const TargetRegisterInfo *TRI);
898f6f4285SAlex Lorenz 
908f6f4285SAlex Lorenz private:
918f6f4285SAlex Lorenz   void initRegisterMaskIds(const MachineFunction &MF);
92345c1449SAlex Lorenz };
93345c1449SAlex Lorenz 
948e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization
958e0a1b48SAlex Lorenz /// format.
968e0a1b48SAlex Lorenz class MIPrinter {
978e0a1b48SAlex Lorenz   raw_ostream &OS;
98900b5cb2SAlex Lorenz   ModuleSlotTracker &MST;
998f6f4285SAlex Lorenz   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
1007feaf7c6SAlex Lorenz   const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
1018e0a1b48SAlex Lorenz 
1028e0a1b48SAlex Lorenz public:
103900b5cb2SAlex Lorenz   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
1047feaf7c6SAlex Lorenz             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
1057feaf7c6SAlex Lorenz             const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
1067feaf7c6SAlex Lorenz       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
1077feaf7c6SAlex Lorenz         StackObjectOperandMapping(StackObjectOperandMapping) {}
1088e0a1b48SAlex Lorenz 
1095022f6bbSAlex Lorenz   void print(const MachineBasicBlock &MBB);
1105022f6bbSAlex Lorenz 
1118e0a1b48SAlex Lorenz   void print(const MachineInstr &MI);
1125d26fa83SAlex Lorenz   void printMBBReference(const MachineBasicBlock &MBB);
113deb53490SAlex Lorenz   void printIRBlockReference(const BasicBlock &BB);
1144af7e610SAlex Lorenz   void printIRValueReference(const Value &V);
1157feaf7c6SAlex Lorenz   void printStackObjectReference(int FrameIndex);
1165672a893SAlex Lorenz   void printOffset(int64_t Offset);
11749873a83SAlex Lorenz   void printTargetFlags(const MachineOperand &Op);
118f3db51deSAlex Lorenz   void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
1194af7e610SAlex Lorenz   void print(const MachineMemOperand &Op);
120f4baeb51SAlex Lorenz 
1218cfc6867SAlex Lorenz   void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
1228e0a1b48SAlex Lorenz };
1238e0a1b48SAlex Lorenz 
1245022f6bbSAlex Lorenz } // end namespace llvm
125345c1449SAlex Lorenz 
126345c1449SAlex Lorenz namespace llvm {
127345c1449SAlex Lorenz namespace yaml {
128345c1449SAlex Lorenz 
129345c1449SAlex Lorenz /// This struct serializes the LLVM IR module.
130345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> {
131345c1449SAlex Lorenz   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
132345c1449SAlex Lorenz     Mod.print(OS, nullptr);
133345c1449SAlex Lorenz   }
134345c1449SAlex Lorenz   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
135345c1449SAlex Lorenz     llvm_unreachable("LLVM Module is supposed to be parsed separately");
136345c1449SAlex Lorenz     return "";
137345c1449SAlex Lorenz   }
138345c1449SAlex Lorenz };
139345c1449SAlex Lorenz 
140345c1449SAlex Lorenz } // end namespace yaml
141345c1449SAlex Lorenz } // end namespace llvm
142345c1449SAlex Lorenz 
14315a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS,
14415a00a85SAlex Lorenz                      const TargetRegisterInfo *TRI) {
14515a00a85SAlex Lorenz   // TODO: Print Stack Slots.
14615a00a85SAlex Lorenz   if (!Reg)
14715a00a85SAlex Lorenz     OS << '_';
14815a00a85SAlex Lorenz   else if (TargetRegisterInfo::isVirtualRegister(Reg))
14915a00a85SAlex Lorenz     OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
15015a00a85SAlex Lorenz   else if (Reg < TRI->getNumRegs())
15115a00a85SAlex Lorenz     OS << '%' << StringRef(TRI->getName(Reg)).lower();
15215a00a85SAlex Lorenz   else
15315a00a85SAlex Lorenz     llvm_unreachable("Can't print this kind of register yet");
15415a00a85SAlex Lorenz }
15515a00a85SAlex Lorenz 
156ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest,
157ab4cbcfdSAlex Lorenz                      const TargetRegisterInfo *TRI) {
158ab4cbcfdSAlex Lorenz   raw_string_ostream OS(Dest.Value);
159ab4cbcfdSAlex Lorenz   printReg(Reg, OS, TRI);
160ab4cbcfdSAlex Lorenz }
161ab4cbcfdSAlex Lorenz 
162345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) {
1638f6f4285SAlex Lorenz   initRegisterMaskIds(MF);
1648f6f4285SAlex Lorenz 
165345c1449SAlex Lorenz   yaml::MachineFunction YamlMF;
166345c1449SAlex Lorenz   YamlMF.Name = MF.getName();
1675b5f9753SAlex Lorenz   YamlMF.Alignment = MF.getAlignment();
1685b5f9753SAlex Lorenz   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
1695b5f9753SAlex Lorenz   YamlMF.HasInlineAsm = MF.hasInlineAsm();
17028148ba8SAlex Lorenz   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
171a6f9a37dSAlex Lorenz   ModuleSlotTracker MST(MF.getFunction()->getParent());
172a6f9a37dSAlex Lorenz   MST.incorporateFunction(*MF.getFunction());
173a6f9a37dSAlex Lorenz   convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
1741bb48de1SAlex Lorenz   convertStackObjects(YamlMF, *MF.getFrameInfo(),
1751bb48de1SAlex Lorenz                       MF.getSubtarget().getRegisterInfo());
176ab980499SAlex Lorenz   if (const auto *ConstantPool = MF.getConstantPool())
177ab980499SAlex Lorenz     convert(YamlMF, *ConstantPool);
1786799e9b3SAlex Lorenz   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
1796799e9b3SAlex Lorenz     convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
1805022f6bbSAlex Lorenz   raw_string_ostream StrOS(YamlMF.Body.Value.Value);
1815022f6bbSAlex Lorenz   bool IsNewlineNeeded = false;
1824f093bf1SAlex Lorenz   for (const auto &MBB : MF) {
1835022f6bbSAlex Lorenz     if (IsNewlineNeeded)
1845022f6bbSAlex Lorenz       StrOS << "\n";
1855022f6bbSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
1865022f6bbSAlex Lorenz         .print(MBB);
1875022f6bbSAlex Lorenz     IsNewlineNeeded = true;
1884f093bf1SAlex Lorenz   }
1895022f6bbSAlex Lorenz   StrOS.flush();
190345c1449SAlex Lorenz   yaml::Output Out(OS);
191345c1449SAlex Lorenz   Out << YamlMF;
192345c1449SAlex Lorenz }
193345c1449SAlex Lorenz 
19454565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
19528148ba8SAlex Lorenz                          const MachineRegisterInfo &RegInfo,
19628148ba8SAlex Lorenz                          const TargetRegisterInfo *TRI) {
19754565cf0SAlex Lorenz   MF.IsSSA = RegInfo.isSSA();
19854565cf0SAlex Lorenz   MF.TracksRegLiveness = RegInfo.tracksLiveness();
19954565cf0SAlex Lorenz   MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
20028148ba8SAlex Lorenz 
20128148ba8SAlex Lorenz   // Print the virtual register definitions.
20228148ba8SAlex Lorenz   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
20328148ba8SAlex Lorenz     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
20428148ba8SAlex Lorenz     yaml::VirtualRegisterDefinition VReg;
20528148ba8SAlex Lorenz     VReg.ID = I;
20628148ba8SAlex Lorenz     VReg.Class =
20728148ba8SAlex Lorenz         StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
208ab4cbcfdSAlex Lorenz     unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
209ab4cbcfdSAlex Lorenz     if (PreferredReg)
210ab4cbcfdSAlex Lorenz       printReg(PreferredReg, VReg.PreferredRegister, TRI);
21128148ba8SAlex Lorenz     MF.VirtualRegisters.push_back(VReg);
21228148ba8SAlex Lorenz   }
21312045a4bSAlex Lorenz 
21412045a4bSAlex Lorenz   // Print the live ins.
21512045a4bSAlex Lorenz   for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
21612045a4bSAlex Lorenz     yaml::MachineFunctionLiveIn LiveIn;
21712045a4bSAlex Lorenz     printReg(I->first, LiveIn.Register, TRI);
21812045a4bSAlex Lorenz     if (I->second)
21912045a4bSAlex Lorenz       printReg(I->second, LiveIn.VirtualRegister, TRI);
22012045a4bSAlex Lorenz     MF.LiveIns.push_back(LiveIn);
22112045a4bSAlex Lorenz   }
222c4838087SAlex Lorenz   // The used physical register mask is printed as an inverted callee saved
223c4838087SAlex Lorenz   // register mask.
224c4838087SAlex Lorenz   const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask();
225c4838087SAlex Lorenz   if (UsedPhysRegMask.none())
226c4838087SAlex Lorenz     return;
227c4838087SAlex Lorenz   std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
228c4838087SAlex Lorenz   for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) {
229c4838087SAlex Lorenz     if (!UsedPhysRegMask[I]) {
230c4838087SAlex Lorenz       yaml::FlowStringValue Reg;
231c4838087SAlex Lorenz       printReg(I, Reg, TRI);
232c4838087SAlex Lorenz       CalleeSavedRegisters.push_back(Reg);
233c4838087SAlex Lorenz     }
234c4838087SAlex Lorenz   }
235c4838087SAlex Lorenz   MF.CalleeSavedRegisters = CalleeSavedRegisters;
23654565cf0SAlex Lorenz }
23754565cf0SAlex Lorenz 
238a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
239a6f9a37dSAlex Lorenz                          yaml::MachineFrameInfo &YamlMFI,
24060541c1dSAlex Lorenz                          const MachineFrameInfo &MFI) {
24160541c1dSAlex Lorenz   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
24260541c1dSAlex Lorenz   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
24360541c1dSAlex Lorenz   YamlMFI.HasStackMap = MFI.hasStackMap();
24460541c1dSAlex Lorenz   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
24560541c1dSAlex Lorenz   YamlMFI.StackSize = MFI.getStackSize();
24660541c1dSAlex Lorenz   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
24760541c1dSAlex Lorenz   YamlMFI.MaxAlignment = MFI.getMaxAlignment();
24860541c1dSAlex Lorenz   YamlMFI.AdjustsStack = MFI.adjustsStack();
24960541c1dSAlex Lorenz   YamlMFI.HasCalls = MFI.hasCalls();
25060541c1dSAlex Lorenz   YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
25160541c1dSAlex Lorenz   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
25260541c1dSAlex Lorenz   YamlMFI.HasVAStart = MFI.hasVAStart();
25360541c1dSAlex Lorenz   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
254a6f9a37dSAlex Lorenz   if (MFI.getSavePoint()) {
255a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
256a6f9a37dSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
257a6f9a37dSAlex Lorenz         .printMBBReference(*MFI.getSavePoint());
258a6f9a37dSAlex Lorenz   }
259a6f9a37dSAlex Lorenz   if (MFI.getRestorePoint()) {
260a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
261a6f9a37dSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
262a6f9a37dSAlex Lorenz         .printMBBReference(*MFI.getRestorePoint());
263a6f9a37dSAlex Lorenz   }
26460541c1dSAlex Lorenz }
26560541c1dSAlex Lorenz 
266f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
2671bb48de1SAlex Lorenz                                      const MachineFrameInfo &MFI,
2681bb48de1SAlex Lorenz                                      const TargetRegisterInfo *TRI) {
269de491f05SAlex Lorenz   // Process fixed stack objects.
270f6bc8667SAlex Lorenz   unsigned ID = 0;
271de491f05SAlex Lorenz   for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
272de491f05SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
273de491f05SAlex Lorenz       continue;
274de491f05SAlex Lorenz 
275de491f05SAlex Lorenz     yaml::FixedMachineStackObject YamlObject;
2767feaf7c6SAlex Lorenz     YamlObject.ID = ID;
277de491f05SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
278de491f05SAlex Lorenz                           ? yaml::FixedMachineStackObject::SpillSlot
279de491f05SAlex Lorenz                           : yaml::FixedMachineStackObject::DefaultType;
280de491f05SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
281de491f05SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
282de491f05SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
283de491f05SAlex Lorenz     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
284de491f05SAlex Lorenz     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
285de491f05SAlex Lorenz     MF.FixedStackObjects.push_back(YamlObject);
2867feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(
2877feaf7c6SAlex Lorenz         std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
288de491f05SAlex Lorenz   }
289de491f05SAlex Lorenz 
290de491f05SAlex Lorenz   // Process ordinary stack objects.
291de491f05SAlex Lorenz   ID = 0;
292f6bc8667SAlex Lorenz   for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
293f6bc8667SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
294f6bc8667SAlex Lorenz       continue;
295f6bc8667SAlex Lorenz 
296f6bc8667SAlex Lorenz     yaml::MachineStackObject YamlObject;
2977feaf7c6SAlex Lorenz     YamlObject.ID = ID;
29837643a04SAlex Lorenz     if (const auto *Alloca = MFI.getObjectAllocation(I))
29937643a04SAlex Lorenz       YamlObject.Name.Value =
30037643a04SAlex Lorenz           Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
301f6bc8667SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
302f6bc8667SAlex Lorenz                           ? yaml::MachineStackObject::SpillSlot
303418f3ec1SAlex Lorenz                           : MFI.isVariableSizedObjectIndex(I)
304418f3ec1SAlex Lorenz                                 ? yaml::MachineStackObject::VariableSized
305f6bc8667SAlex Lorenz                                 : yaml::MachineStackObject::DefaultType;
306f6bc8667SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
307f6bc8667SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
308f6bc8667SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
309f6bc8667SAlex Lorenz 
310f6bc8667SAlex Lorenz     MF.StackObjects.push_back(YamlObject);
3117feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(std::make_pair(
3127feaf7c6SAlex Lorenz         I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
313f6bc8667SAlex Lorenz   }
3141bb48de1SAlex Lorenz 
3151bb48de1SAlex Lorenz   for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
3161bb48de1SAlex Lorenz     yaml::StringValue Reg;
3171bb48de1SAlex Lorenz     printReg(CSInfo.getReg(), Reg, TRI);
3181bb48de1SAlex Lorenz     auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
3191bb48de1SAlex Lorenz     assert(StackObjectInfo != StackObjectOperandMapping.end() &&
3201bb48de1SAlex Lorenz            "Invalid stack object index");
3211bb48de1SAlex Lorenz     const FrameIndexOperand &StackObject = StackObjectInfo->second;
3221bb48de1SAlex Lorenz     if (StackObject.IsFixed)
3231bb48de1SAlex Lorenz       MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
3241bb48de1SAlex Lorenz     else
3251bb48de1SAlex Lorenz       MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
3261bb48de1SAlex Lorenz   }
327f6bc8667SAlex Lorenz }
328f6bc8667SAlex Lorenz 
329ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
330ab980499SAlex Lorenz                          const MachineConstantPool &ConstantPool) {
331ab980499SAlex Lorenz   unsigned ID = 0;
332ab980499SAlex Lorenz   for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
333ab980499SAlex Lorenz     // TODO: Serialize target specific constant pool entries.
334ab980499SAlex Lorenz     if (Constant.isMachineConstantPoolEntry())
335ab980499SAlex Lorenz       llvm_unreachable("Can't print target specific constant pool entries yet");
336ab980499SAlex Lorenz 
337ab980499SAlex Lorenz     yaml::MachineConstantPoolValue YamlConstant;
338ab980499SAlex Lorenz     std::string Str;
339ab980499SAlex Lorenz     raw_string_ostream StrOS(Str);
340ab980499SAlex Lorenz     Constant.Val.ConstVal->printAsOperand(StrOS);
341ab980499SAlex Lorenz     YamlConstant.ID = ID++;
342ab980499SAlex Lorenz     YamlConstant.Value = StrOS.str();
343ab980499SAlex Lorenz     YamlConstant.Alignment = Constant.getAlignment();
344ab980499SAlex Lorenz     MF.Constants.push_back(YamlConstant);
345ab980499SAlex Lorenz   }
346ab980499SAlex Lorenz }
347ab980499SAlex Lorenz 
348900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
3496799e9b3SAlex Lorenz                          yaml::MachineJumpTable &YamlJTI,
3506799e9b3SAlex Lorenz                          const MachineJumpTableInfo &JTI) {
3516799e9b3SAlex Lorenz   YamlJTI.Kind = JTI.getEntryKind();
3526799e9b3SAlex Lorenz   unsigned ID = 0;
3536799e9b3SAlex Lorenz   for (const auto &Table : JTI.getJumpTables()) {
3546799e9b3SAlex Lorenz     std::string Str;
3556799e9b3SAlex Lorenz     yaml::MachineJumpTable::Entry Entry;
3566799e9b3SAlex Lorenz     Entry.ID = ID++;
3576799e9b3SAlex Lorenz     for (const auto *MBB : Table.MBBs) {
3586799e9b3SAlex Lorenz       raw_string_ostream StrOS(Str);
3597feaf7c6SAlex Lorenz       MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
3607feaf7c6SAlex Lorenz           .printMBBReference(*MBB);
3616799e9b3SAlex Lorenz       Entry.Blocks.push_back(StrOS.str());
3626799e9b3SAlex Lorenz       Str.clear();
3636799e9b3SAlex Lorenz     }
3646799e9b3SAlex Lorenz     YamlJTI.Entries.push_back(Entry);
3656799e9b3SAlex Lorenz   }
3666799e9b3SAlex Lorenz }
3676799e9b3SAlex Lorenz 
3688f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
3698f6f4285SAlex Lorenz   const auto *TRI = MF.getSubtarget().getRegisterInfo();
3708f6f4285SAlex Lorenz   unsigned I = 0;
3718f6f4285SAlex Lorenz   for (const uint32_t *Mask : TRI->getRegMasks())
3728f6f4285SAlex Lorenz     RegisterMaskIds.insert(std::make_pair(Mask, I++));
3738f6f4285SAlex Lorenz }
3748f6f4285SAlex Lorenz 
3755022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) {
3765022f6bbSAlex Lorenz   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
3775022f6bbSAlex Lorenz   OS << "bb." << MBB.getNumber();
3785022f6bbSAlex Lorenz   bool HasAttributes = false;
3795022f6bbSAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
3805022f6bbSAlex Lorenz     if (BB->hasName()) {
3815022f6bbSAlex Lorenz       OS << "." << BB->getName();
3825022f6bbSAlex Lorenz     } else {
3835022f6bbSAlex Lorenz       HasAttributes = true;
3845022f6bbSAlex Lorenz       OS << " (";
3855022f6bbSAlex Lorenz       int Slot = MST.getLocalSlot(BB);
3865022f6bbSAlex Lorenz       if (Slot == -1)
3875022f6bbSAlex Lorenz         OS << "<ir-block badref>";
3885022f6bbSAlex Lorenz       else
3895022f6bbSAlex Lorenz         OS << (Twine("%ir-block.") + Twine(Slot)).str();
3905022f6bbSAlex Lorenz     }
3915022f6bbSAlex Lorenz   }
3925022f6bbSAlex Lorenz   if (MBB.hasAddressTaken()) {
3935022f6bbSAlex Lorenz     OS << (HasAttributes ? ", " : " (");
3945022f6bbSAlex Lorenz     OS << "address-taken";
3955022f6bbSAlex Lorenz     HasAttributes = true;
3965022f6bbSAlex Lorenz   }
3975022f6bbSAlex Lorenz   if (MBB.isLandingPad()) {
3985022f6bbSAlex Lorenz     OS << (HasAttributes ? ", " : " (");
3995022f6bbSAlex Lorenz     OS << "landing-pad";
4005022f6bbSAlex Lorenz     HasAttributes = true;
4015022f6bbSAlex Lorenz   }
4025022f6bbSAlex Lorenz   if (MBB.getAlignment()) {
4035022f6bbSAlex Lorenz     OS << (HasAttributes ? ", " : " (");
4045022f6bbSAlex Lorenz     OS << "align " << MBB.getAlignment();
4055022f6bbSAlex Lorenz     HasAttributes = true;
4065022f6bbSAlex Lorenz   }
4075022f6bbSAlex Lorenz   if (HasAttributes)
4085022f6bbSAlex Lorenz     OS << ")";
4095022f6bbSAlex Lorenz   OS << ":\n";
4105022f6bbSAlex Lorenz 
4115022f6bbSAlex Lorenz   bool HasLineAttributes = false;
4125022f6bbSAlex Lorenz   // Print the successors
4135022f6bbSAlex Lorenz   if (!MBB.succ_empty()) {
4145022f6bbSAlex Lorenz     OS.indent(2) << "successors: ";
4155022f6bbSAlex Lorenz     for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
4165022f6bbSAlex Lorenz       if (I != MBB.succ_begin())
4175022f6bbSAlex Lorenz         OS << ", ";
4185022f6bbSAlex Lorenz       printMBBReference(**I);
4195022f6bbSAlex Lorenz       if (MBB.hasSuccessorWeights())
4205022f6bbSAlex Lorenz         OS << '(' << MBB.getSuccWeight(I) << ')';
4215022f6bbSAlex Lorenz     }
4225022f6bbSAlex Lorenz     OS << "\n";
4235022f6bbSAlex Lorenz     HasLineAttributes = true;
4245022f6bbSAlex Lorenz   }
4255022f6bbSAlex Lorenz 
4265022f6bbSAlex Lorenz   // Print the live in registers.
4275022f6bbSAlex Lorenz   const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
4285022f6bbSAlex Lorenz   assert(TRI && "Expected target register info");
4295022f6bbSAlex Lorenz   if (!MBB.livein_empty()) {
4305022f6bbSAlex Lorenz     OS.indent(2) << "liveins: ";
4315022f6bbSAlex Lorenz     for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) {
4325022f6bbSAlex Lorenz       if (I != MBB.livein_begin())
4335022f6bbSAlex Lorenz         OS << ", ";
4345022f6bbSAlex Lorenz       printReg(*I, OS, TRI);
4355022f6bbSAlex Lorenz     }
4365022f6bbSAlex Lorenz     OS << "\n";
4375022f6bbSAlex Lorenz     HasLineAttributes = true;
4385022f6bbSAlex Lorenz   }
4395022f6bbSAlex Lorenz 
4405022f6bbSAlex Lorenz   if (HasLineAttributes)
4415022f6bbSAlex Lorenz     OS << "\n";
442f9a2b123SAlex Lorenz   bool IsInBundle = false;
443f9a2b123SAlex Lorenz   for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) {
444f9a2b123SAlex Lorenz     const MachineInstr &MI = *I;
445f9a2b123SAlex Lorenz     if (IsInBundle && !MI.isInsideBundle()) {
446f9a2b123SAlex Lorenz       OS.indent(2) << "}\n";
447f9a2b123SAlex Lorenz       IsInBundle = false;
448f9a2b123SAlex Lorenz     }
449f9a2b123SAlex Lorenz     OS.indent(IsInBundle ? 4 : 2);
4505022f6bbSAlex Lorenz     print(MI);
451f9a2b123SAlex Lorenz     if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
452f9a2b123SAlex Lorenz       OS << " {";
453f9a2b123SAlex Lorenz       IsInBundle = true;
454f9a2b123SAlex Lorenz     }
4555022f6bbSAlex Lorenz     OS << "\n";
4565022f6bbSAlex Lorenz   }
457f9a2b123SAlex Lorenz   if (IsInBundle)
458f9a2b123SAlex Lorenz     OS.indent(2) << "}\n";
4595022f6bbSAlex Lorenz }
4605022f6bbSAlex Lorenz 
4618e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) {
4628e0a1b48SAlex Lorenz   const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
463f3db51deSAlex Lorenz   const auto *TRI = SubTarget.getRegisterInfo();
464f3db51deSAlex Lorenz   assert(TRI && "Expected target register info");
4658e0a1b48SAlex Lorenz   const auto *TII = SubTarget.getInstrInfo();
4668e0a1b48SAlex Lorenz   assert(TII && "Expected target instruction info");
467f4baeb51SAlex Lorenz   if (MI.isCFIInstruction())
468f4baeb51SAlex Lorenz     assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
4698e0a1b48SAlex Lorenz 
470f3db51deSAlex Lorenz   unsigned I = 0, E = MI.getNumOperands();
471f3db51deSAlex Lorenz   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
472f3db51deSAlex Lorenz          !MI.getOperand(I).isImplicit();
473f3db51deSAlex Lorenz        ++I) {
474f3db51deSAlex Lorenz     if (I)
475f3db51deSAlex Lorenz       OS << ", ";
476f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
477f3db51deSAlex Lorenz   }
478f3db51deSAlex Lorenz 
479f3db51deSAlex Lorenz   if (I)
480f3db51deSAlex Lorenz     OS << " = ";
481e5a44660SAlex Lorenz   if (MI.getFlag(MachineInstr::FrameSetup))
482e5a44660SAlex Lorenz     OS << "frame-setup ";
4838e0a1b48SAlex Lorenz   OS << TII->getName(MI.getOpcode());
484f3db51deSAlex Lorenz   if (I < E)
485f3db51deSAlex Lorenz     OS << ' ';
486f3db51deSAlex Lorenz 
487f3db51deSAlex Lorenz   bool NeedComma = false;
488f3db51deSAlex Lorenz   for (; I < E; ++I) {
489f3db51deSAlex Lorenz     if (NeedComma)
490f3db51deSAlex Lorenz       OS << ", ";
491f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
492f3db51deSAlex Lorenz     NeedComma = true;
493f3db51deSAlex Lorenz   }
49446d760d1SAlex Lorenz 
49546d760d1SAlex Lorenz   if (MI.getDebugLoc()) {
49646d760d1SAlex Lorenz     if (NeedComma)
49746d760d1SAlex Lorenz       OS << ',';
49846d760d1SAlex Lorenz     OS << " debug-location ";
49946d760d1SAlex Lorenz     MI.getDebugLoc()->printAsOperand(OS, MST);
50046d760d1SAlex Lorenz   }
5014af7e610SAlex Lorenz 
5024af7e610SAlex Lorenz   if (!MI.memoperands_empty()) {
5034af7e610SAlex Lorenz     OS << " :: ";
5044af7e610SAlex Lorenz     bool NeedComma = false;
5054af7e610SAlex Lorenz     for (const auto *Op : MI.memoperands()) {
5064af7e610SAlex Lorenz       if (NeedComma)
5074af7e610SAlex Lorenz         OS << ", ";
5084af7e610SAlex Lorenz       print(*Op);
5094af7e610SAlex Lorenz       NeedComma = true;
5104af7e610SAlex Lorenz     }
5114af7e610SAlex Lorenz   }
512f3db51deSAlex Lorenz }
513f3db51deSAlex Lorenz 
5145d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
5155d26fa83SAlex Lorenz   OS << "%bb." << MBB.getNumber();
5165d26fa83SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
5175d26fa83SAlex Lorenz     if (BB->hasName())
5185d26fa83SAlex Lorenz       OS << '.' << BB->getName();
5195d26fa83SAlex Lorenz   }
5205d26fa83SAlex Lorenz }
5215d26fa83SAlex Lorenz 
522deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
523deb53490SAlex Lorenz   OS << "%ir-block.";
524deb53490SAlex Lorenz   if (BB.hasName()) {
525deb53490SAlex Lorenz     printLLVMNameWithoutPrefix(OS, BB.getName());
526deb53490SAlex Lorenz     return;
527deb53490SAlex Lorenz   }
528cba8c5feSAlex Lorenz   const Function *F = BB.getParent();
529cba8c5feSAlex Lorenz   int Slot;
530cba8c5feSAlex Lorenz   if (F == MST.getCurrentFunction()) {
531cba8c5feSAlex Lorenz     Slot = MST.getLocalSlot(&BB);
532cba8c5feSAlex Lorenz   } else {
533cba8c5feSAlex Lorenz     ModuleSlotTracker CustomMST(F->getParent(),
534cba8c5feSAlex Lorenz                                 /*ShouldInitializeAllMetadata=*/false);
535cba8c5feSAlex Lorenz     CustomMST.incorporateFunction(*F);
536cba8c5feSAlex Lorenz     Slot = CustomMST.getLocalSlot(&BB);
537cba8c5feSAlex Lorenz   }
538deb53490SAlex Lorenz   if (Slot == -1)
539deb53490SAlex Lorenz     OS << "<badref>";
540deb53490SAlex Lorenz   else
541deb53490SAlex Lorenz     OS << Slot;
542deb53490SAlex Lorenz }
543deb53490SAlex Lorenz 
5444af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) {
5454af7e610SAlex Lorenz   OS << "%ir.";
5464af7e610SAlex Lorenz   if (V.hasName()) {
5474af7e610SAlex Lorenz     printLLVMNameWithoutPrefix(OS, V.getName());
5484af7e610SAlex Lorenz     return;
5494af7e610SAlex Lorenz   }
5504af7e610SAlex Lorenz   // TODO: Serialize the unnamed IR value references.
5514af7e610SAlex Lorenz   OS << "<unserializable ir value>";
5524af7e610SAlex Lorenz }
5534af7e610SAlex Lorenz 
5547feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) {
5557feaf7c6SAlex Lorenz   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
5567feaf7c6SAlex Lorenz   assert(ObjectInfo != StackObjectOperandMapping.end() &&
5577feaf7c6SAlex Lorenz          "Invalid frame index");
5587feaf7c6SAlex Lorenz   const FrameIndexOperand &Operand = ObjectInfo->second;
5597feaf7c6SAlex Lorenz   if (Operand.IsFixed) {
5607feaf7c6SAlex Lorenz     OS << "%fixed-stack." << Operand.ID;
5617feaf7c6SAlex Lorenz     return;
5627feaf7c6SAlex Lorenz   }
5637feaf7c6SAlex Lorenz   OS << "%stack." << Operand.ID;
5647feaf7c6SAlex Lorenz   if (!Operand.Name.empty())
5657feaf7c6SAlex Lorenz     OS << '.' << Operand.Name;
5667feaf7c6SAlex Lorenz }
5677feaf7c6SAlex Lorenz 
5685672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) {
5695672a893SAlex Lorenz   if (Offset == 0)
5705672a893SAlex Lorenz     return;
5715672a893SAlex Lorenz   if (Offset < 0) {
5725672a893SAlex Lorenz     OS << " - " << -Offset;
5735672a893SAlex Lorenz     return;
5745672a893SAlex Lorenz   }
5755672a893SAlex Lorenz   OS << " + " << Offset;
5765672a893SAlex Lorenz }
5775672a893SAlex Lorenz 
57849873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
57949873a83SAlex Lorenz   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
58049873a83SAlex Lorenz   for (const auto &I : Flags) {
58149873a83SAlex Lorenz     if (I.first == TF) {
58249873a83SAlex Lorenz       return I.second;
58349873a83SAlex Lorenz     }
58449873a83SAlex Lorenz   }
58549873a83SAlex Lorenz   return nullptr;
58649873a83SAlex Lorenz }
58749873a83SAlex Lorenz 
58849873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) {
58949873a83SAlex Lorenz   if (!Op.getTargetFlags())
59049873a83SAlex Lorenz     return;
59149873a83SAlex Lorenz   const auto *TII =
59249873a83SAlex Lorenz       Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo();
59349873a83SAlex Lorenz   assert(TII && "expected instruction info");
59449873a83SAlex Lorenz   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
59549873a83SAlex Lorenz   OS << "target-flags(";
59649873a83SAlex Lorenz   if (const auto *Name = getTargetFlagName(TII, Flags.first))
59749873a83SAlex Lorenz     OS << Name;
59849873a83SAlex Lorenz   else
59949873a83SAlex Lorenz     OS << "<unknown target flag>";
60049873a83SAlex Lorenz   // TODO: Print the target's bit flags.
60149873a83SAlex Lorenz   OS << ") ";
60249873a83SAlex Lorenz }
60349873a83SAlex Lorenz 
604ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
605ef5c196fSAlex Lorenz   const auto *TII = MF.getSubtarget().getInstrInfo();
606ef5c196fSAlex Lorenz   assert(TII && "expected instruction info");
607ef5c196fSAlex Lorenz   auto Indices = TII->getSerializableTargetIndices();
608ef5c196fSAlex Lorenz   for (const auto &I : Indices) {
609ef5c196fSAlex Lorenz     if (I.first == Index) {
610ef5c196fSAlex Lorenz       return I.second;
611ef5c196fSAlex Lorenz     }
612ef5c196fSAlex Lorenz   }
613ef5c196fSAlex Lorenz   return nullptr;
614ef5c196fSAlex Lorenz }
615ef5c196fSAlex Lorenz 
616f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
61749873a83SAlex Lorenz   printTargetFlags(Op);
618f3db51deSAlex Lorenz   switch (Op.getType()) {
619f3db51deSAlex Lorenz   case MachineOperand::MO_Register:
6201039fd1aSAlex Lorenz     // FIXME: Serialize the tied register.
621cb268d46SAlex Lorenz     if (Op.isImplicit())
622cb268d46SAlex Lorenz       OS << (Op.isDef() ? "implicit-def " : "implicit ");
6231039fd1aSAlex Lorenz     if (Op.isInternalRead())
6241039fd1aSAlex Lorenz       OS << "internal ";
625cbbfd0b1SAlex Lorenz     if (Op.isDead())
626cbbfd0b1SAlex Lorenz       OS << "dead ";
627495ad879SAlex Lorenz     if (Op.isKill())
628495ad879SAlex Lorenz       OS << "killed ";
6294d026b89SAlex Lorenz     if (Op.isUndef())
6304d026b89SAlex Lorenz       OS << "undef ";
63101c1a5eeSAlex Lorenz     if (Op.isEarlyClobber())
63201c1a5eeSAlex Lorenz       OS << "early-clobber ";
6339075258bSAlex Lorenz     if (Op.isDebug())
6349075258bSAlex Lorenz       OS << "debug-use ";
635f3db51deSAlex Lorenz     printReg(Op.getReg(), OS, TRI);
6362eacca86SAlex Lorenz     // Print the sub register.
6372eacca86SAlex Lorenz     if (Op.getSubReg() != 0)
6382eacca86SAlex Lorenz       OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
639f3db51deSAlex Lorenz     break;
640240fc1e0SAlex Lorenz   case MachineOperand::MO_Immediate:
641240fc1e0SAlex Lorenz     OS << Op.getImm();
642240fc1e0SAlex Lorenz     break;
64305e3882eSAlex Lorenz   case MachineOperand::MO_CImmediate:
64405e3882eSAlex Lorenz     Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
64505e3882eSAlex Lorenz     break;
646ad156fb6SAlex Lorenz   case MachineOperand::MO_FPImmediate:
647ad156fb6SAlex Lorenz     Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
648ad156fb6SAlex Lorenz     break;
64933f0aef3SAlex Lorenz   case MachineOperand::MO_MachineBasicBlock:
6505d26fa83SAlex Lorenz     printMBBReference(*Op.getMBB());
65133f0aef3SAlex Lorenz     break;
6527feaf7c6SAlex Lorenz   case MachineOperand::MO_FrameIndex:
6537feaf7c6SAlex Lorenz     printStackObjectReference(Op.getIndex());
6547feaf7c6SAlex Lorenz     break;
655ab980499SAlex Lorenz   case MachineOperand::MO_ConstantPoolIndex:
656ab980499SAlex Lorenz     OS << "%const." << Op.getIndex();
6575672a893SAlex Lorenz     printOffset(Op.getOffset());
658ab980499SAlex Lorenz     break;
659ef5c196fSAlex Lorenz   case MachineOperand::MO_TargetIndex: {
660ef5c196fSAlex Lorenz     OS << "target-index(";
661ef5c196fSAlex Lorenz     if (const auto *Name = getTargetIndexName(
662ef5c196fSAlex Lorenz             *Op.getParent()->getParent()->getParent(), Op.getIndex()))
663ef5c196fSAlex Lorenz       OS << Name;
664ef5c196fSAlex Lorenz     else
665ef5c196fSAlex Lorenz       OS << "<unknown>";
666ef5c196fSAlex Lorenz     OS << ')';
6675672a893SAlex Lorenz     printOffset(Op.getOffset());
668ef5c196fSAlex Lorenz     break;
669ef5c196fSAlex Lorenz   }
67031d70683SAlex Lorenz   case MachineOperand::MO_JumpTableIndex:
67131d70683SAlex Lorenz     OS << "%jump-table." << Op.getIndex();
67231d70683SAlex Lorenz     break;
6736ede3744SAlex Lorenz   case MachineOperand::MO_ExternalSymbol:
6746ede3744SAlex Lorenz     OS << '$';
6756ede3744SAlex Lorenz     printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
6765672a893SAlex Lorenz     printOffset(Op.getOffset());
6776ede3744SAlex Lorenz     break;
6785d6108e4SAlex Lorenz   case MachineOperand::MO_GlobalAddress:
679900b5cb2SAlex Lorenz     Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
6805672a893SAlex Lorenz     printOffset(Op.getOffset());
6815d6108e4SAlex Lorenz     break;
682deb53490SAlex Lorenz   case MachineOperand::MO_BlockAddress:
683deb53490SAlex Lorenz     OS << "blockaddress(";
684deb53490SAlex Lorenz     Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
685deb53490SAlex Lorenz                                                         MST);
686deb53490SAlex Lorenz     OS << ", ";
687deb53490SAlex Lorenz     printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
688deb53490SAlex Lorenz     OS << ')';
6895672a893SAlex Lorenz     printOffset(Op.getOffset());
690deb53490SAlex Lorenz     break;
6918f6f4285SAlex Lorenz   case MachineOperand::MO_RegisterMask: {
6928f6f4285SAlex Lorenz     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
6938f6f4285SAlex Lorenz     if (RegMaskInfo != RegisterMaskIds.end())
6948f6f4285SAlex Lorenz       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
6958f6f4285SAlex Lorenz     else
6968f6f4285SAlex Lorenz       llvm_unreachable("Can't print this machine register mask yet.");
6978f6f4285SAlex Lorenz     break;
6988f6f4285SAlex Lorenz   }
699b97c9ef4SAlex Lorenz   case MachineOperand::MO_RegisterLiveOut: {
700b97c9ef4SAlex Lorenz     const uint32_t *RegMask = Op.getRegLiveOut();
701b97c9ef4SAlex Lorenz     OS << "liveout(";
702b97c9ef4SAlex Lorenz     bool IsCommaNeeded = false;
703b97c9ef4SAlex Lorenz     for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
704b97c9ef4SAlex Lorenz       if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
705b97c9ef4SAlex Lorenz         if (IsCommaNeeded)
706b97c9ef4SAlex Lorenz           OS << ", ";
707b97c9ef4SAlex Lorenz         printReg(Reg, OS, TRI);
708b97c9ef4SAlex Lorenz         IsCommaNeeded = true;
709b97c9ef4SAlex Lorenz       }
710b97c9ef4SAlex Lorenz     }
711b97c9ef4SAlex Lorenz     OS << ")";
712b97c9ef4SAlex Lorenz     break;
713b97c9ef4SAlex Lorenz   }
71435e44469SAlex Lorenz   case MachineOperand::MO_Metadata:
71535e44469SAlex Lorenz     Op.getMetadata()->printAsOperand(OS, MST);
71635e44469SAlex Lorenz     break;
717f4baeb51SAlex Lorenz   case MachineOperand::MO_CFIIndex: {
718f4baeb51SAlex Lorenz     const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
7198cfc6867SAlex Lorenz     print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
720f4baeb51SAlex Lorenz     break;
721f4baeb51SAlex Lorenz   }
722f3db51deSAlex Lorenz   default:
723f3db51deSAlex Lorenz     // TODO: Print the other machine operands.
724f3db51deSAlex Lorenz     llvm_unreachable("Can't print this machine operand at the moment");
725f3db51deSAlex Lorenz   }
7264f093bf1SAlex Lorenz }
7274f093bf1SAlex Lorenz 
7284af7e610SAlex Lorenz void MIPrinter::print(const MachineMemOperand &Op) {
7294af7e610SAlex Lorenz   OS << '(';
730dc8de2a6SAlex Lorenz   // TODO: Print operand's target specific flags.
731a518b796SAlex Lorenz   if (Op.isVolatile())
732a518b796SAlex Lorenz     OS << "volatile ";
73310fd0385SAlex Lorenz   if (Op.isNonTemporal())
73410fd0385SAlex Lorenz     OS << "non-temporal ";
735dc8de2a6SAlex Lorenz   if (Op.isInvariant())
736dc8de2a6SAlex Lorenz     OS << "invariant ";
7374af7e610SAlex Lorenz   if (Op.isLoad())
7384af7e610SAlex Lorenz     OS << "load ";
7394af7e610SAlex Lorenz   else {
7404af7e610SAlex Lorenz     assert(Op.isStore() && "Non load machine operand must be a store");
7414af7e610SAlex Lorenz     OS << "store ";
7424af7e610SAlex Lorenz   }
7434af7e610SAlex Lorenz   OS << Op.getSize() << (Op.isLoad() ? " from " : " into ");
74491097a3fSAlex Lorenz   if (const Value *Val = Op.getValue()) {
7454af7e610SAlex Lorenz     printIRValueReference(*Val);
74691097a3fSAlex Lorenz   } else {
74791097a3fSAlex Lorenz     const PseudoSourceValue *PVal = Op.getPseudoValue();
74891097a3fSAlex Lorenz     assert(PVal && "Expected a pseudo source value");
74991097a3fSAlex Lorenz     switch (PVal->kind()) {
75046e9558aSAlex Lorenz     case PseudoSourceValue::Stack:
75146e9558aSAlex Lorenz       OS << "stack";
75246e9558aSAlex Lorenz       break;
753d858f874SAlex Lorenz     case PseudoSourceValue::GOT:
754d858f874SAlex Lorenz       OS << "got";
755d858f874SAlex Lorenz       break;
7564be56e93SAlex Lorenz     case PseudoSourceValue::JumpTable:
7574be56e93SAlex Lorenz       OS << "jump-table";
7584be56e93SAlex Lorenz       break;
75991097a3fSAlex Lorenz     case PseudoSourceValue::ConstantPool:
76091097a3fSAlex Lorenz       OS << "constant-pool";
76191097a3fSAlex Lorenz       break;
7620cc671bfSAlex Lorenz     case PseudoSourceValue::FixedStack:
7630cc671bfSAlex Lorenz       printStackObjectReference(
7640cc671bfSAlex Lorenz           cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex());
7650cc671bfSAlex Lorenz       break;
76650b826fbSAlex Lorenz     case PseudoSourceValue::GlobalValueCallEntry:
76750b826fbSAlex Lorenz       cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
76850b826fbSAlex Lorenz           OS, /*PrintType=*/false, MST);
76950b826fbSAlex Lorenz       break;
770c3ba7508SAlex Lorenz     case PseudoSourceValue::ExternalSymbolCallEntry:
771c3ba7508SAlex Lorenz       OS << '$';
772c3ba7508SAlex Lorenz       printLLVMNameWithoutPrefix(
773c3ba7508SAlex Lorenz           OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
77491097a3fSAlex Lorenz       break;
77591097a3fSAlex Lorenz     }
77691097a3fSAlex Lorenz   }
77783127739SAlex Lorenz   printOffset(Op.getOffset());
77861420f79SAlex Lorenz   if (Op.getBaseAlignment() != Op.getSize())
77961420f79SAlex Lorenz     OS << ", align " << Op.getBaseAlignment();
7804af7e610SAlex Lorenz   // TODO: Print the metadata attributes.
7814af7e610SAlex Lorenz   OS << ')';
7824af7e610SAlex Lorenz }
7834af7e610SAlex Lorenz 
7848cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
7858cfc6867SAlex Lorenz                              const TargetRegisterInfo *TRI) {
7868cfc6867SAlex Lorenz   int Reg = TRI->getLLVMRegNum(DwarfReg, true);
7878cfc6867SAlex Lorenz   if (Reg == -1) {
7888cfc6867SAlex Lorenz     OS << "<badreg>";
7898cfc6867SAlex Lorenz     return;
7908cfc6867SAlex Lorenz   }
7918cfc6867SAlex Lorenz   printReg(Reg, OS, TRI);
7928cfc6867SAlex Lorenz }
7938cfc6867SAlex Lorenz 
7948cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI,
7958cfc6867SAlex Lorenz                       const TargetRegisterInfo *TRI) {
796f4baeb51SAlex Lorenz   switch (CFI.getOperation()) {
797*577d271aSAlex Lorenz   case MCCFIInstruction::OpSameValue:
798*577d271aSAlex Lorenz     OS << ".cfi_same_value ";
799*577d271aSAlex Lorenz     if (CFI.getLabel())
800*577d271aSAlex Lorenz       OS << "<mcsymbol> ";
801*577d271aSAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
802*577d271aSAlex Lorenz     break;
8038cfc6867SAlex Lorenz   case MCCFIInstruction::OpOffset:
8048cfc6867SAlex Lorenz     OS << ".cfi_offset ";
8058cfc6867SAlex Lorenz     if (CFI.getLabel())
8068cfc6867SAlex Lorenz       OS << "<mcsymbol> ";
8078cfc6867SAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
8088cfc6867SAlex Lorenz     OS << ", " << CFI.getOffset();
8098cfc6867SAlex Lorenz     break;
8105b0d5f6fSAlex Lorenz   case MCCFIInstruction::OpDefCfaRegister:
8115b0d5f6fSAlex Lorenz     OS << ".cfi_def_cfa_register ";
8125b0d5f6fSAlex Lorenz     if (CFI.getLabel())
8135b0d5f6fSAlex Lorenz       OS << "<mcsymbol> ";
8145b0d5f6fSAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
8155b0d5f6fSAlex Lorenz     break;
816f4baeb51SAlex Lorenz   case MCCFIInstruction::OpDefCfaOffset:
817f4baeb51SAlex Lorenz     OS << ".cfi_def_cfa_offset ";
818f4baeb51SAlex Lorenz     if (CFI.getLabel())
819f4baeb51SAlex Lorenz       OS << "<mcsymbol> ";
820f4baeb51SAlex Lorenz     OS << CFI.getOffset();
821f4baeb51SAlex Lorenz     break;
822b139323fSAlex Lorenz   case MCCFIInstruction::OpDefCfa:
823b139323fSAlex Lorenz     OS << ".cfi_def_cfa ";
824b139323fSAlex Lorenz     if (CFI.getLabel())
825b139323fSAlex Lorenz       OS << "<mcsymbol> ";
826b139323fSAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
827b139323fSAlex Lorenz     OS << ", " << CFI.getOffset();
828b139323fSAlex Lorenz     break;
829f4baeb51SAlex Lorenz   default:
830f4baeb51SAlex Lorenz     // TODO: Print the other CFI Operations.
831f4baeb51SAlex Lorenz     OS << "<unserializable cfi operation>";
832f4baeb51SAlex Lorenz     break;
833f4baeb51SAlex Lorenz   }
834f4baeb51SAlex Lorenz }
835f4baeb51SAlex Lorenz 
836345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) {
837345c1449SAlex Lorenz   yaml::Output Out(OS);
838345c1449SAlex Lorenz   Out << const_cast<Module &>(M);
839345c1449SAlex Lorenz }
840345c1449SAlex Lorenz 
841345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
842345c1449SAlex Lorenz   MIRPrinter Printer(OS);
843345c1449SAlex Lorenz   Printer.print(MF);
844345c1449SAlex Lorenz }
845