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);
86900b5cb2SAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
875d6108e4SAlex Lorenz                const MachineBasicBlock &MBB);
88f6bc8667SAlex Lorenz   void convertStackObjects(yaml::MachineFunction &MF,
891bb48de1SAlex Lorenz                            const MachineFrameInfo &MFI,
901bb48de1SAlex Lorenz                            const TargetRegisterInfo *TRI);
918f6f4285SAlex Lorenz 
928f6f4285SAlex Lorenz private:
938f6f4285SAlex Lorenz   void initRegisterMaskIds(const MachineFunction &MF);
94345c1449SAlex Lorenz };
95345c1449SAlex Lorenz 
96618b283cSAlex Lorenz } // end namespace llvm
97618b283cSAlex Lorenz 
98618b283cSAlex Lorenz namespace {
99618b283cSAlex Lorenz 
1008e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization
1018e0a1b48SAlex Lorenz /// format.
1028e0a1b48SAlex Lorenz class MIPrinter {
1038e0a1b48SAlex Lorenz   raw_ostream &OS;
104900b5cb2SAlex Lorenz   ModuleSlotTracker &MST;
1058f6f4285SAlex Lorenz   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
1067feaf7c6SAlex Lorenz   const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
1078e0a1b48SAlex Lorenz 
1088e0a1b48SAlex Lorenz public:
109900b5cb2SAlex Lorenz   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
1107feaf7c6SAlex Lorenz             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
1117feaf7c6SAlex Lorenz             const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
1127feaf7c6SAlex Lorenz       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
1137feaf7c6SAlex Lorenz         StackObjectOperandMapping(StackObjectOperandMapping) {}
1148e0a1b48SAlex Lorenz 
1158e0a1b48SAlex Lorenz   void print(const MachineInstr &MI);
1165d26fa83SAlex Lorenz   void printMBBReference(const MachineBasicBlock &MBB);
117deb53490SAlex Lorenz   void printIRBlockReference(const BasicBlock &BB);
1184af7e610SAlex Lorenz   void printIRValueReference(const Value &V);
1197feaf7c6SAlex Lorenz   void printStackObjectReference(int FrameIndex);
1205672a893SAlex Lorenz   void printOffset(int64_t Offset);
12149873a83SAlex Lorenz   void printTargetFlags(const MachineOperand &Op);
122f3db51deSAlex Lorenz   void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
1234af7e610SAlex Lorenz   void print(const MachineMemOperand &Op);
124f4baeb51SAlex Lorenz 
1258cfc6867SAlex Lorenz   void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
1268e0a1b48SAlex Lorenz };
1278e0a1b48SAlex Lorenz 
128345c1449SAlex Lorenz } // end anonymous namespace
129345c1449SAlex Lorenz 
130345c1449SAlex Lorenz namespace llvm {
131345c1449SAlex Lorenz namespace yaml {
132345c1449SAlex Lorenz 
133345c1449SAlex Lorenz /// This struct serializes the LLVM IR module.
134345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> {
135345c1449SAlex Lorenz   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
136345c1449SAlex Lorenz     Mod.print(OS, nullptr);
137345c1449SAlex Lorenz   }
138345c1449SAlex Lorenz   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
139345c1449SAlex Lorenz     llvm_unreachable("LLVM Module is supposed to be parsed separately");
140345c1449SAlex Lorenz     return "";
141345c1449SAlex Lorenz   }
142345c1449SAlex Lorenz };
143345c1449SAlex Lorenz 
144345c1449SAlex Lorenz } // end namespace yaml
145345c1449SAlex Lorenz } // end namespace llvm
146345c1449SAlex Lorenz 
14715a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS,
14815a00a85SAlex Lorenz                      const TargetRegisterInfo *TRI) {
14915a00a85SAlex Lorenz   // TODO: Print Stack Slots.
15015a00a85SAlex Lorenz   if (!Reg)
15115a00a85SAlex Lorenz     OS << '_';
15215a00a85SAlex Lorenz   else if (TargetRegisterInfo::isVirtualRegister(Reg))
15315a00a85SAlex Lorenz     OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
15415a00a85SAlex Lorenz   else if (Reg < TRI->getNumRegs())
15515a00a85SAlex Lorenz     OS << '%' << StringRef(TRI->getName(Reg)).lower();
15615a00a85SAlex Lorenz   else
15715a00a85SAlex Lorenz     llvm_unreachable("Can't print this kind of register yet");
15815a00a85SAlex Lorenz }
15915a00a85SAlex Lorenz 
160ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest,
161ab4cbcfdSAlex Lorenz                      const TargetRegisterInfo *TRI) {
162ab4cbcfdSAlex Lorenz   raw_string_ostream OS(Dest.Value);
163ab4cbcfdSAlex Lorenz   printReg(Reg, OS, TRI);
164ab4cbcfdSAlex Lorenz }
165ab4cbcfdSAlex Lorenz 
166345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) {
1678f6f4285SAlex Lorenz   initRegisterMaskIds(MF);
1688f6f4285SAlex Lorenz 
169345c1449SAlex Lorenz   yaml::MachineFunction YamlMF;
170345c1449SAlex Lorenz   YamlMF.Name = MF.getName();
1715b5f9753SAlex Lorenz   YamlMF.Alignment = MF.getAlignment();
1725b5f9753SAlex Lorenz   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
1735b5f9753SAlex Lorenz   YamlMF.HasInlineAsm = MF.hasInlineAsm();
17428148ba8SAlex Lorenz   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
175a6f9a37dSAlex Lorenz   ModuleSlotTracker MST(MF.getFunction()->getParent());
176a6f9a37dSAlex Lorenz   MST.incorporateFunction(*MF.getFunction());
177a6f9a37dSAlex Lorenz   convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
1781bb48de1SAlex Lorenz   convertStackObjects(YamlMF, *MF.getFrameInfo(),
1791bb48de1SAlex Lorenz                       MF.getSubtarget().getRegisterInfo());
180ab980499SAlex Lorenz   if (const auto *ConstantPool = MF.getConstantPool())
181ab980499SAlex Lorenz     convert(YamlMF, *ConstantPool);
1826799e9b3SAlex Lorenz   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
1836799e9b3SAlex Lorenz     convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
1844f093bf1SAlex Lorenz   for (const auto &MBB : MF) {
1854f093bf1SAlex Lorenz     yaml::MachineBasicBlock YamlMBB;
186900b5cb2SAlex Lorenz     convert(MST, YamlMBB, MBB);
1874f093bf1SAlex Lorenz     YamlMF.BasicBlocks.push_back(YamlMBB);
1884f093bf1SAlex Lorenz   }
189345c1449SAlex Lorenz   yaml::Output Out(OS);
190345c1449SAlex Lorenz   Out << YamlMF;
191345c1449SAlex Lorenz }
192345c1449SAlex Lorenz 
19354565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
19428148ba8SAlex Lorenz                          const MachineRegisterInfo &RegInfo,
19528148ba8SAlex Lorenz                          const TargetRegisterInfo *TRI) {
19654565cf0SAlex Lorenz   MF.IsSSA = RegInfo.isSSA();
19754565cf0SAlex Lorenz   MF.TracksRegLiveness = RegInfo.tracksLiveness();
19854565cf0SAlex Lorenz   MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
19928148ba8SAlex Lorenz 
20028148ba8SAlex Lorenz   // Print the virtual register definitions.
20128148ba8SAlex Lorenz   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
20228148ba8SAlex Lorenz     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
20328148ba8SAlex Lorenz     yaml::VirtualRegisterDefinition VReg;
20428148ba8SAlex Lorenz     VReg.ID = I;
20528148ba8SAlex Lorenz     VReg.Class =
20628148ba8SAlex Lorenz         StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
207ab4cbcfdSAlex Lorenz     unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
208ab4cbcfdSAlex Lorenz     if (PreferredReg)
209ab4cbcfdSAlex Lorenz       printReg(PreferredReg, VReg.PreferredRegister, TRI);
21028148ba8SAlex Lorenz     MF.VirtualRegisters.push_back(VReg);
21128148ba8SAlex Lorenz   }
21212045a4bSAlex Lorenz 
21312045a4bSAlex Lorenz   // Print the live ins.
21412045a4bSAlex Lorenz   for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
21512045a4bSAlex Lorenz     yaml::MachineFunctionLiveIn LiveIn;
21612045a4bSAlex Lorenz     printReg(I->first, LiveIn.Register, TRI);
21712045a4bSAlex Lorenz     if (I->second)
21812045a4bSAlex Lorenz       printReg(I->second, LiveIn.VirtualRegister, TRI);
21912045a4bSAlex Lorenz     MF.LiveIns.push_back(LiveIn);
22012045a4bSAlex Lorenz   }
221c4838087SAlex Lorenz   // The used physical register mask is printed as an inverted callee saved
222c4838087SAlex Lorenz   // register mask.
223c4838087SAlex Lorenz   const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask();
224c4838087SAlex Lorenz   if (UsedPhysRegMask.none())
225c4838087SAlex Lorenz     return;
226c4838087SAlex Lorenz   std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
227c4838087SAlex Lorenz   for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) {
228c4838087SAlex Lorenz     if (!UsedPhysRegMask[I]) {
229c4838087SAlex Lorenz       yaml::FlowStringValue Reg;
230c4838087SAlex Lorenz       printReg(I, Reg, TRI);
231c4838087SAlex Lorenz       CalleeSavedRegisters.push_back(Reg);
232c4838087SAlex Lorenz     }
233c4838087SAlex Lorenz   }
234c4838087SAlex Lorenz   MF.CalleeSavedRegisters = CalleeSavedRegisters;
23554565cf0SAlex Lorenz }
23654565cf0SAlex Lorenz 
237a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
238a6f9a37dSAlex Lorenz                          yaml::MachineFrameInfo &YamlMFI,
23960541c1dSAlex Lorenz                          const MachineFrameInfo &MFI) {
24060541c1dSAlex Lorenz   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
24160541c1dSAlex Lorenz   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
24260541c1dSAlex Lorenz   YamlMFI.HasStackMap = MFI.hasStackMap();
24360541c1dSAlex Lorenz   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
24460541c1dSAlex Lorenz   YamlMFI.StackSize = MFI.getStackSize();
24560541c1dSAlex Lorenz   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
24660541c1dSAlex Lorenz   YamlMFI.MaxAlignment = MFI.getMaxAlignment();
24760541c1dSAlex Lorenz   YamlMFI.AdjustsStack = MFI.adjustsStack();
24860541c1dSAlex Lorenz   YamlMFI.HasCalls = MFI.hasCalls();
24960541c1dSAlex Lorenz   YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
25060541c1dSAlex Lorenz   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
25160541c1dSAlex Lorenz   YamlMFI.HasVAStart = MFI.hasVAStart();
25260541c1dSAlex Lorenz   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
253a6f9a37dSAlex Lorenz   if (MFI.getSavePoint()) {
254a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
255a6f9a37dSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
256a6f9a37dSAlex Lorenz         .printMBBReference(*MFI.getSavePoint());
257a6f9a37dSAlex Lorenz   }
258a6f9a37dSAlex Lorenz   if (MFI.getRestorePoint()) {
259a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
260a6f9a37dSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
261a6f9a37dSAlex Lorenz         .printMBBReference(*MFI.getRestorePoint());
262a6f9a37dSAlex Lorenz   }
26360541c1dSAlex Lorenz }
26460541c1dSAlex Lorenz 
265f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
2661bb48de1SAlex Lorenz                                      const MachineFrameInfo &MFI,
2671bb48de1SAlex Lorenz                                      const TargetRegisterInfo *TRI) {
268de491f05SAlex Lorenz   // Process fixed stack objects.
269f6bc8667SAlex Lorenz   unsigned ID = 0;
270de491f05SAlex Lorenz   for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
271de491f05SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
272de491f05SAlex Lorenz       continue;
273de491f05SAlex Lorenz 
274de491f05SAlex Lorenz     yaml::FixedMachineStackObject YamlObject;
2757feaf7c6SAlex Lorenz     YamlObject.ID = ID;
276de491f05SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
277de491f05SAlex Lorenz                           ? yaml::FixedMachineStackObject::SpillSlot
278de491f05SAlex Lorenz                           : yaml::FixedMachineStackObject::DefaultType;
279de491f05SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
280de491f05SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
281de491f05SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
282de491f05SAlex Lorenz     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
283de491f05SAlex Lorenz     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
284de491f05SAlex Lorenz     MF.FixedStackObjects.push_back(YamlObject);
2857feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(
2867feaf7c6SAlex Lorenz         std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
287de491f05SAlex Lorenz   }
288de491f05SAlex Lorenz 
289de491f05SAlex Lorenz   // Process ordinary stack objects.
290de491f05SAlex Lorenz   ID = 0;
291f6bc8667SAlex Lorenz   for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
292f6bc8667SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
293f6bc8667SAlex Lorenz       continue;
294f6bc8667SAlex Lorenz 
295f6bc8667SAlex Lorenz     yaml::MachineStackObject YamlObject;
2967feaf7c6SAlex Lorenz     YamlObject.ID = ID;
29737643a04SAlex Lorenz     if (const auto *Alloca = MFI.getObjectAllocation(I))
29837643a04SAlex Lorenz       YamlObject.Name.Value =
29937643a04SAlex Lorenz           Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
300f6bc8667SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
301f6bc8667SAlex Lorenz                           ? yaml::MachineStackObject::SpillSlot
302418f3ec1SAlex Lorenz                           : MFI.isVariableSizedObjectIndex(I)
303418f3ec1SAlex Lorenz                                 ? yaml::MachineStackObject::VariableSized
304f6bc8667SAlex Lorenz                                 : yaml::MachineStackObject::DefaultType;
305f6bc8667SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
306f6bc8667SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
307f6bc8667SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
308f6bc8667SAlex Lorenz 
309f6bc8667SAlex Lorenz     MF.StackObjects.push_back(YamlObject);
3107feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(std::make_pair(
3117feaf7c6SAlex Lorenz         I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
312f6bc8667SAlex Lorenz   }
3131bb48de1SAlex Lorenz 
3141bb48de1SAlex Lorenz   for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
3151bb48de1SAlex Lorenz     yaml::StringValue Reg;
3161bb48de1SAlex Lorenz     printReg(CSInfo.getReg(), Reg, TRI);
3171bb48de1SAlex Lorenz     auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
3181bb48de1SAlex Lorenz     assert(StackObjectInfo != StackObjectOperandMapping.end() &&
3191bb48de1SAlex Lorenz            "Invalid stack object index");
3201bb48de1SAlex Lorenz     const FrameIndexOperand &StackObject = StackObjectInfo->second;
3211bb48de1SAlex Lorenz     if (StackObject.IsFixed)
3221bb48de1SAlex Lorenz       MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
3231bb48de1SAlex Lorenz     else
3241bb48de1SAlex Lorenz       MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
3251bb48de1SAlex Lorenz   }
326f6bc8667SAlex Lorenz }
327f6bc8667SAlex Lorenz 
328ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
329ab980499SAlex Lorenz                          const MachineConstantPool &ConstantPool) {
330ab980499SAlex Lorenz   unsigned ID = 0;
331ab980499SAlex Lorenz   for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
332ab980499SAlex Lorenz     // TODO: Serialize target specific constant pool entries.
333ab980499SAlex Lorenz     if (Constant.isMachineConstantPoolEntry())
334ab980499SAlex Lorenz       llvm_unreachable("Can't print target specific constant pool entries yet");
335ab980499SAlex Lorenz 
336ab980499SAlex Lorenz     yaml::MachineConstantPoolValue YamlConstant;
337ab980499SAlex Lorenz     std::string Str;
338ab980499SAlex Lorenz     raw_string_ostream StrOS(Str);
339ab980499SAlex Lorenz     Constant.Val.ConstVal->printAsOperand(StrOS);
340ab980499SAlex Lorenz     YamlConstant.ID = ID++;
341ab980499SAlex Lorenz     YamlConstant.Value = StrOS.str();
342ab980499SAlex Lorenz     YamlConstant.Alignment = Constant.getAlignment();
343ab980499SAlex Lorenz     MF.Constants.push_back(YamlConstant);
344ab980499SAlex Lorenz   }
345ab980499SAlex Lorenz }
346ab980499SAlex Lorenz 
347900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
3486799e9b3SAlex Lorenz                          yaml::MachineJumpTable &YamlJTI,
3496799e9b3SAlex Lorenz                          const MachineJumpTableInfo &JTI) {
3506799e9b3SAlex Lorenz   YamlJTI.Kind = JTI.getEntryKind();
3516799e9b3SAlex Lorenz   unsigned ID = 0;
3526799e9b3SAlex Lorenz   for (const auto &Table : JTI.getJumpTables()) {
3536799e9b3SAlex Lorenz     std::string Str;
3546799e9b3SAlex Lorenz     yaml::MachineJumpTable::Entry Entry;
3556799e9b3SAlex Lorenz     Entry.ID = ID++;
3566799e9b3SAlex Lorenz     for (const auto *MBB : Table.MBBs) {
3576799e9b3SAlex Lorenz       raw_string_ostream StrOS(Str);
3587feaf7c6SAlex Lorenz       MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
3597feaf7c6SAlex Lorenz           .printMBBReference(*MBB);
3606799e9b3SAlex Lorenz       Entry.Blocks.push_back(StrOS.str());
3616799e9b3SAlex Lorenz       Str.clear();
3626799e9b3SAlex Lorenz     }
3636799e9b3SAlex Lorenz     YamlJTI.Entries.push_back(Entry);
3646799e9b3SAlex Lorenz   }
3656799e9b3SAlex Lorenz }
3666799e9b3SAlex Lorenz 
3676799e9b3SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
368900b5cb2SAlex Lorenz                          yaml::MachineBasicBlock &YamlMBB,
3694f093bf1SAlex Lorenz                          const MachineBasicBlock &MBB) {
37033f0aef3SAlex Lorenz   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
37133f0aef3SAlex Lorenz   YamlMBB.ID = (unsigned)MBB.getNumber();
3728a1915b0SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
3738a1915b0SAlex Lorenz     if (BB->hasName()) {
3748a1915b0SAlex Lorenz       YamlMBB.Name.Value = BB->getName();
3758a1915b0SAlex Lorenz     } else {
3768a1915b0SAlex Lorenz       int Slot = MST.getLocalSlot(BB);
3778a1915b0SAlex Lorenz       if (Slot == -1)
3788a1915b0SAlex Lorenz         YamlMBB.IRBlock.Value = "<badref>";
3794f093bf1SAlex Lorenz       else
3808a1915b0SAlex Lorenz         YamlMBB.IRBlock.Value = (Twine("%ir-block.") + Twine(Slot)).str();
3818a1915b0SAlex Lorenz     }
3828a1915b0SAlex Lorenz   }
3834f093bf1SAlex Lorenz   YamlMBB.Alignment = MBB.getAlignment();
3844f093bf1SAlex Lorenz   YamlMBB.AddressTaken = MBB.hasAddressTaken();
3854f093bf1SAlex Lorenz   YamlMBB.IsLandingPad = MBB.isLandingPad();
386eb5112bfSAlex Lorenz   for (const auto *SuccMBB : MBB.successors()) {
387f09df00dSAlex Lorenz     std::string Str;
388f09df00dSAlex Lorenz     raw_string_ostream StrOS(Str);
3897feaf7c6SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
3907feaf7c6SAlex Lorenz         .printMBBReference(*SuccMBB);
391f09df00dSAlex Lorenz     YamlMBB.Successors.push_back(StrOS.str());
392f09df00dSAlex Lorenz   }
393618b283cSAlex Lorenz   if (MBB.hasSuccessorWeights()) {
394618b283cSAlex Lorenz     for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I)
395618b283cSAlex Lorenz       YamlMBB.SuccessorWeights.push_back(
396618b283cSAlex Lorenz           yaml::UnsignedValue(MBB.getSuccWeight(I)));
397618b283cSAlex Lorenz   }
3989fab370dSAlex Lorenz   // Print the live in registers.
3999fab370dSAlex Lorenz   const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
4009fab370dSAlex Lorenz   assert(TRI && "Expected target register info");
4019fab370dSAlex Lorenz   for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) {
4029fab370dSAlex Lorenz     std::string Str;
4039fab370dSAlex Lorenz     raw_string_ostream StrOS(Str);
4049fab370dSAlex Lorenz     printReg(*I, StrOS, TRI);
4059fab370dSAlex Lorenz     YamlMBB.LiveIns.push_back(StrOS.str());
4069fab370dSAlex Lorenz   }
4078e0a1b48SAlex Lorenz   // Print the machine instructions.
4088e0a1b48SAlex Lorenz   YamlMBB.Instructions.reserve(MBB.size());
4098e0a1b48SAlex Lorenz   std::string Str;
4108e0a1b48SAlex Lorenz   for (const auto &MI : MBB) {
4118e0a1b48SAlex Lorenz     raw_string_ostream StrOS(Str);
4127feaf7c6SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI);
4138e0a1b48SAlex Lorenz     YamlMBB.Instructions.push_back(StrOS.str());
4148e0a1b48SAlex Lorenz     Str.clear();
4158e0a1b48SAlex Lorenz   }
4168e0a1b48SAlex Lorenz }
4178e0a1b48SAlex Lorenz 
4188f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
4198f6f4285SAlex Lorenz   const auto *TRI = MF.getSubtarget().getRegisterInfo();
4208f6f4285SAlex Lorenz   unsigned I = 0;
4218f6f4285SAlex Lorenz   for (const uint32_t *Mask : TRI->getRegMasks())
4228f6f4285SAlex Lorenz     RegisterMaskIds.insert(std::make_pair(Mask, I++));
4238f6f4285SAlex Lorenz }
4248f6f4285SAlex Lorenz 
4258e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) {
4268e0a1b48SAlex Lorenz   const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
427f3db51deSAlex Lorenz   const auto *TRI = SubTarget.getRegisterInfo();
428f3db51deSAlex Lorenz   assert(TRI && "Expected target register info");
4298e0a1b48SAlex Lorenz   const auto *TII = SubTarget.getInstrInfo();
4308e0a1b48SAlex Lorenz   assert(TII && "Expected target instruction info");
431f4baeb51SAlex Lorenz   if (MI.isCFIInstruction())
432f4baeb51SAlex Lorenz     assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
4338e0a1b48SAlex Lorenz 
434f3db51deSAlex Lorenz   unsigned I = 0, E = MI.getNumOperands();
435f3db51deSAlex Lorenz   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
436f3db51deSAlex Lorenz          !MI.getOperand(I).isImplicit();
437f3db51deSAlex Lorenz        ++I) {
438f3db51deSAlex Lorenz     if (I)
439f3db51deSAlex Lorenz       OS << ", ";
440f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
441f3db51deSAlex Lorenz   }
442f3db51deSAlex Lorenz 
443f3db51deSAlex Lorenz   if (I)
444f3db51deSAlex Lorenz     OS << " = ";
445e5a44660SAlex Lorenz   if (MI.getFlag(MachineInstr::FrameSetup))
446e5a44660SAlex Lorenz     OS << "frame-setup ";
4478e0a1b48SAlex Lorenz   OS << TII->getName(MI.getOpcode());
4484af7e610SAlex Lorenz   // TODO: Print the bundling instruction flags.
449f3db51deSAlex Lorenz   if (I < E)
450f3db51deSAlex Lorenz     OS << ' ';
451f3db51deSAlex Lorenz 
452f3db51deSAlex Lorenz   bool NeedComma = false;
453f3db51deSAlex Lorenz   for (; I < E; ++I) {
454f3db51deSAlex Lorenz     if (NeedComma)
455f3db51deSAlex Lorenz       OS << ", ";
456f3db51deSAlex Lorenz     print(MI.getOperand(I), TRI);
457f3db51deSAlex Lorenz     NeedComma = true;
458f3db51deSAlex Lorenz   }
45946d760d1SAlex Lorenz 
46046d760d1SAlex Lorenz   if (MI.getDebugLoc()) {
46146d760d1SAlex Lorenz     if (NeedComma)
46246d760d1SAlex Lorenz       OS << ',';
46346d760d1SAlex Lorenz     OS << " debug-location ";
46446d760d1SAlex Lorenz     MI.getDebugLoc()->printAsOperand(OS, MST);
46546d760d1SAlex Lorenz   }
4664af7e610SAlex Lorenz 
4674af7e610SAlex Lorenz   if (!MI.memoperands_empty()) {
4684af7e610SAlex Lorenz     OS << " :: ";
4694af7e610SAlex Lorenz     bool NeedComma = false;
4704af7e610SAlex Lorenz     for (const auto *Op : MI.memoperands()) {
4714af7e610SAlex Lorenz       if (NeedComma)
4724af7e610SAlex Lorenz         OS << ", ";
4734af7e610SAlex Lorenz       print(*Op);
4744af7e610SAlex Lorenz       NeedComma = true;
4754af7e610SAlex Lorenz     }
4764af7e610SAlex Lorenz   }
477f3db51deSAlex Lorenz }
478f3db51deSAlex Lorenz 
4795d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
4805d26fa83SAlex Lorenz   OS << "%bb." << MBB.getNumber();
4815d26fa83SAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
4825d26fa83SAlex Lorenz     if (BB->hasName())
4835d26fa83SAlex Lorenz       OS << '.' << BB->getName();
4845d26fa83SAlex Lorenz   }
4855d26fa83SAlex Lorenz }
4865d26fa83SAlex Lorenz 
487deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
488deb53490SAlex Lorenz   OS << "%ir-block.";
489deb53490SAlex Lorenz   if (BB.hasName()) {
490deb53490SAlex Lorenz     printLLVMNameWithoutPrefix(OS, BB.getName());
491deb53490SAlex Lorenz     return;
492deb53490SAlex Lorenz   }
493cba8c5feSAlex Lorenz   const Function *F = BB.getParent();
494cba8c5feSAlex Lorenz   int Slot;
495cba8c5feSAlex Lorenz   if (F == MST.getCurrentFunction()) {
496cba8c5feSAlex Lorenz     Slot = MST.getLocalSlot(&BB);
497cba8c5feSAlex Lorenz   } else {
498cba8c5feSAlex Lorenz     ModuleSlotTracker CustomMST(F->getParent(),
499cba8c5feSAlex Lorenz                                 /*ShouldInitializeAllMetadata=*/false);
500cba8c5feSAlex Lorenz     CustomMST.incorporateFunction(*F);
501cba8c5feSAlex Lorenz     Slot = CustomMST.getLocalSlot(&BB);
502cba8c5feSAlex Lorenz   }
503deb53490SAlex Lorenz   if (Slot == -1)
504deb53490SAlex Lorenz     OS << "<badref>";
505deb53490SAlex Lorenz   else
506deb53490SAlex Lorenz     OS << Slot;
507deb53490SAlex Lorenz }
508deb53490SAlex Lorenz 
5094af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) {
5104af7e610SAlex Lorenz   OS << "%ir.";
5114af7e610SAlex Lorenz   if (V.hasName()) {
5124af7e610SAlex Lorenz     printLLVMNameWithoutPrefix(OS, V.getName());
5134af7e610SAlex Lorenz     return;
5144af7e610SAlex Lorenz   }
5154af7e610SAlex Lorenz   // TODO: Serialize the unnamed IR value references.
5164af7e610SAlex Lorenz   OS << "<unserializable ir value>";
5174af7e610SAlex Lorenz }
5184af7e610SAlex Lorenz 
5197feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) {
5207feaf7c6SAlex Lorenz   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
5217feaf7c6SAlex Lorenz   assert(ObjectInfo != StackObjectOperandMapping.end() &&
5227feaf7c6SAlex Lorenz          "Invalid frame index");
5237feaf7c6SAlex Lorenz   const FrameIndexOperand &Operand = ObjectInfo->second;
5247feaf7c6SAlex Lorenz   if (Operand.IsFixed) {
5257feaf7c6SAlex Lorenz     OS << "%fixed-stack." << Operand.ID;
5267feaf7c6SAlex Lorenz     return;
5277feaf7c6SAlex Lorenz   }
5287feaf7c6SAlex Lorenz   OS << "%stack." << Operand.ID;
5297feaf7c6SAlex Lorenz   if (!Operand.Name.empty())
5307feaf7c6SAlex Lorenz     OS << '.' << Operand.Name;
5317feaf7c6SAlex Lorenz }
5327feaf7c6SAlex Lorenz 
5335672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) {
5345672a893SAlex Lorenz   if (Offset == 0)
5355672a893SAlex Lorenz     return;
5365672a893SAlex Lorenz   if (Offset < 0) {
5375672a893SAlex Lorenz     OS << " - " << -Offset;
5385672a893SAlex Lorenz     return;
5395672a893SAlex Lorenz   }
5405672a893SAlex Lorenz   OS << " + " << Offset;
5415672a893SAlex Lorenz }
5425672a893SAlex Lorenz 
54349873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
54449873a83SAlex Lorenz   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
54549873a83SAlex Lorenz   for (const auto &I : Flags) {
54649873a83SAlex Lorenz     if (I.first == TF) {
54749873a83SAlex Lorenz       return I.second;
54849873a83SAlex Lorenz     }
54949873a83SAlex Lorenz   }
55049873a83SAlex Lorenz   return nullptr;
55149873a83SAlex Lorenz }
55249873a83SAlex Lorenz 
55349873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) {
55449873a83SAlex Lorenz   if (!Op.getTargetFlags())
55549873a83SAlex Lorenz     return;
55649873a83SAlex Lorenz   const auto *TII =
55749873a83SAlex Lorenz       Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo();
55849873a83SAlex Lorenz   assert(TII && "expected instruction info");
55949873a83SAlex Lorenz   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
56049873a83SAlex Lorenz   OS << "target-flags(";
56149873a83SAlex Lorenz   if (const auto *Name = getTargetFlagName(TII, Flags.first))
56249873a83SAlex Lorenz     OS << Name;
56349873a83SAlex Lorenz   else
56449873a83SAlex Lorenz     OS << "<unknown target flag>";
56549873a83SAlex Lorenz   // TODO: Print the target's bit flags.
56649873a83SAlex Lorenz   OS << ") ";
56749873a83SAlex Lorenz }
56849873a83SAlex Lorenz 
569ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
570ef5c196fSAlex Lorenz   const auto *TII = MF.getSubtarget().getInstrInfo();
571ef5c196fSAlex Lorenz   assert(TII && "expected instruction info");
572ef5c196fSAlex Lorenz   auto Indices = TII->getSerializableTargetIndices();
573ef5c196fSAlex Lorenz   for (const auto &I : Indices) {
574ef5c196fSAlex Lorenz     if (I.first == Index) {
575ef5c196fSAlex Lorenz       return I.second;
576ef5c196fSAlex Lorenz     }
577ef5c196fSAlex Lorenz   }
578ef5c196fSAlex Lorenz   return nullptr;
579ef5c196fSAlex Lorenz }
580ef5c196fSAlex Lorenz 
581f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
58249873a83SAlex Lorenz   printTargetFlags(Op);
583f3db51deSAlex Lorenz   switch (Op.getType()) {
584f3db51deSAlex Lorenz   case MachineOperand::MO_Register:
585cb268d46SAlex Lorenz     // TODO: Print the other register flags.
586cb268d46SAlex Lorenz     if (Op.isImplicit())
587cb268d46SAlex Lorenz       OS << (Op.isDef() ? "implicit-def " : "implicit ");
588cbbfd0b1SAlex Lorenz     if (Op.isDead())
589cbbfd0b1SAlex Lorenz       OS << "dead ";
590495ad879SAlex Lorenz     if (Op.isKill())
591495ad879SAlex Lorenz       OS << "killed ";
5924d026b89SAlex Lorenz     if (Op.isUndef())
5934d026b89SAlex Lorenz       OS << "undef ";
59401c1a5eeSAlex Lorenz     if (Op.isEarlyClobber())
59501c1a5eeSAlex Lorenz       OS << "early-clobber ";
5969075258bSAlex Lorenz     if (Op.isDebug())
5979075258bSAlex Lorenz       OS << "debug-use ";
598f3db51deSAlex Lorenz     printReg(Op.getReg(), OS, TRI);
5992eacca86SAlex Lorenz     // Print the sub register.
6002eacca86SAlex Lorenz     if (Op.getSubReg() != 0)
6012eacca86SAlex Lorenz       OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
602f3db51deSAlex Lorenz     break;
603240fc1e0SAlex Lorenz   case MachineOperand::MO_Immediate:
604240fc1e0SAlex Lorenz     OS << Op.getImm();
605240fc1e0SAlex Lorenz     break;
60605e3882eSAlex Lorenz   case MachineOperand::MO_CImmediate:
60705e3882eSAlex Lorenz     Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
60805e3882eSAlex Lorenz     break;
609ad156fb6SAlex Lorenz   case MachineOperand::MO_FPImmediate:
610ad156fb6SAlex Lorenz     Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
611ad156fb6SAlex Lorenz     break;
61233f0aef3SAlex Lorenz   case MachineOperand::MO_MachineBasicBlock:
6135d26fa83SAlex Lorenz     printMBBReference(*Op.getMBB());
61433f0aef3SAlex Lorenz     break;
6157feaf7c6SAlex Lorenz   case MachineOperand::MO_FrameIndex:
6167feaf7c6SAlex Lorenz     printStackObjectReference(Op.getIndex());
6177feaf7c6SAlex Lorenz     break;
618ab980499SAlex Lorenz   case MachineOperand::MO_ConstantPoolIndex:
619ab980499SAlex Lorenz     OS << "%const." << Op.getIndex();
6205672a893SAlex Lorenz     printOffset(Op.getOffset());
621ab980499SAlex Lorenz     break;
622ef5c196fSAlex Lorenz   case MachineOperand::MO_TargetIndex: {
623ef5c196fSAlex Lorenz     OS << "target-index(";
624ef5c196fSAlex Lorenz     if (const auto *Name = getTargetIndexName(
625ef5c196fSAlex Lorenz             *Op.getParent()->getParent()->getParent(), Op.getIndex()))
626ef5c196fSAlex Lorenz       OS << Name;
627ef5c196fSAlex Lorenz     else
628ef5c196fSAlex Lorenz       OS << "<unknown>";
629ef5c196fSAlex Lorenz     OS << ')';
6305672a893SAlex Lorenz     printOffset(Op.getOffset());
631ef5c196fSAlex Lorenz     break;
632ef5c196fSAlex Lorenz   }
63331d70683SAlex Lorenz   case MachineOperand::MO_JumpTableIndex:
63431d70683SAlex Lorenz     OS << "%jump-table." << Op.getIndex();
63531d70683SAlex Lorenz     break;
6366ede3744SAlex Lorenz   case MachineOperand::MO_ExternalSymbol:
6376ede3744SAlex Lorenz     OS << '$';
6386ede3744SAlex Lorenz     printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
6395672a893SAlex Lorenz     printOffset(Op.getOffset());
6406ede3744SAlex Lorenz     break;
6415d6108e4SAlex Lorenz   case MachineOperand::MO_GlobalAddress:
642900b5cb2SAlex Lorenz     Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
6435672a893SAlex Lorenz     printOffset(Op.getOffset());
6445d6108e4SAlex Lorenz     break;
645deb53490SAlex Lorenz   case MachineOperand::MO_BlockAddress:
646deb53490SAlex Lorenz     OS << "blockaddress(";
647deb53490SAlex Lorenz     Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
648deb53490SAlex Lorenz                                                         MST);
649deb53490SAlex Lorenz     OS << ", ";
650deb53490SAlex Lorenz     printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
651deb53490SAlex Lorenz     OS << ')';
6525672a893SAlex Lorenz     printOffset(Op.getOffset());
653deb53490SAlex Lorenz     break;
6548f6f4285SAlex Lorenz   case MachineOperand::MO_RegisterMask: {
6558f6f4285SAlex Lorenz     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
6568f6f4285SAlex Lorenz     if (RegMaskInfo != RegisterMaskIds.end())
6578f6f4285SAlex Lorenz       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
6588f6f4285SAlex Lorenz     else
6598f6f4285SAlex Lorenz       llvm_unreachable("Can't print this machine register mask yet.");
6608f6f4285SAlex Lorenz     break;
6618f6f4285SAlex Lorenz   }
662b97c9ef4SAlex Lorenz   case MachineOperand::MO_RegisterLiveOut: {
663b97c9ef4SAlex Lorenz     const uint32_t *RegMask = Op.getRegLiveOut();
664b97c9ef4SAlex Lorenz     OS << "liveout(";
665b97c9ef4SAlex Lorenz     bool IsCommaNeeded = false;
666b97c9ef4SAlex Lorenz     for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
667b97c9ef4SAlex Lorenz       if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
668b97c9ef4SAlex Lorenz         if (IsCommaNeeded)
669b97c9ef4SAlex Lorenz           OS << ", ";
670b97c9ef4SAlex Lorenz         printReg(Reg, OS, TRI);
671b97c9ef4SAlex Lorenz         IsCommaNeeded = true;
672b97c9ef4SAlex Lorenz       }
673b97c9ef4SAlex Lorenz     }
674b97c9ef4SAlex Lorenz     OS << ")";
675b97c9ef4SAlex Lorenz     break;
676b97c9ef4SAlex Lorenz   }
67735e44469SAlex Lorenz   case MachineOperand::MO_Metadata:
67835e44469SAlex Lorenz     Op.getMetadata()->printAsOperand(OS, MST);
67935e44469SAlex Lorenz     break;
680f4baeb51SAlex Lorenz   case MachineOperand::MO_CFIIndex: {
681f4baeb51SAlex Lorenz     const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
6828cfc6867SAlex Lorenz     print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
683f4baeb51SAlex Lorenz     break;
684f4baeb51SAlex Lorenz   }
685f3db51deSAlex Lorenz   default:
686f3db51deSAlex Lorenz     // TODO: Print the other machine operands.
687f3db51deSAlex Lorenz     llvm_unreachable("Can't print this machine operand at the moment");
688f3db51deSAlex Lorenz   }
6894f093bf1SAlex Lorenz }
6904f093bf1SAlex Lorenz 
6914af7e610SAlex Lorenz void MIPrinter::print(const MachineMemOperand &Op) {
6924af7e610SAlex Lorenz   OS << '(';
693dc8de2a6SAlex Lorenz   // TODO: Print operand's target specific flags.
694a518b796SAlex Lorenz   if (Op.isVolatile())
695a518b796SAlex Lorenz     OS << "volatile ";
69610fd0385SAlex Lorenz   if (Op.isNonTemporal())
69710fd0385SAlex Lorenz     OS << "non-temporal ";
698dc8de2a6SAlex Lorenz   if (Op.isInvariant())
699dc8de2a6SAlex Lorenz     OS << "invariant ";
7004af7e610SAlex Lorenz   if (Op.isLoad())
7014af7e610SAlex Lorenz     OS << "load ";
7024af7e610SAlex Lorenz   else {
7034af7e610SAlex Lorenz     assert(Op.isStore() && "Non load machine operand must be a store");
7044af7e610SAlex Lorenz     OS << "store ";
7054af7e610SAlex Lorenz   }
7064af7e610SAlex Lorenz   OS << Op.getSize() << (Op.isLoad() ? " from " : " into ");
70791097a3fSAlex Lorenz   if (const Value *Val = Op.getValue()) {
7084af7e610SAlex Lorenz     printIRValueReference(*Val);
70991097a3fSAlex Lorenz   } else {
71091097a3fSAlex Lorenz     const PseudoSourceValue *PVal = Op.getPseudoValue();
71191097a3fSAlex Lorenz     assert(PVal && "Expected a pseudo source value");
71291097a3fSAlex Lorenz     switch (PVal->kind()) {
71346e9558aSAlex Lorenz     case PseudoSourceValue::Stack:
71446e9558aSAlex Lorenz       OS << "stack";
71546e9558aSAlex Lorenz       break;
716d858f874SAlex Lorenz     case PseudoSourceValue::GOT:
717d858f874SAlex Lorenz       OS << "got";
718d858f874SAlex Lorenz       break;
7194be56e93SAlex Lorenz     case PseudoSourceValue::JumpTable:
7204be56e93SAlex Lorenz       OS << "jump-table";
7214be56e93SAlex Lorenz       break;
72291097a3fSAlex Lorenz     case PseudoSourceValue::ConstantPool:
72391097a3fSAlex Lorenz       OS << "constant-pool";
72491097a3fSAlex Lorenz       break;
725*0cc671bfSAlex Lorenz     case PseudoSourceValue::FixedStack:
726*0cc671bfSAlex Lorenz       printStackObjectReference(
727*0cc671bfSAlex Lorenz           cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex());
728*0cc671bfSAlex Lorenz       break;
72991097a3fSAlex Lorenz     default:
73091097a3fSAlex Lorenz       // TODO: Print the other pseudo source values.
73191097a3fSAlex Lorenz       OS << "<unserializable pseudo value>";
73291097a3fSAlex Lorenz       break;
73391097a3fSAlex Lorenz     }
73491097a3fSAlex Lorenz   }
73583127739SAlex Lorenz   printOffset(Op.getOffset());
73661420f79SAlex Lorenz   if (Op.getBaseAlignment() != Op.getSize())
73761420f79SAlex Lorenz     OS << ", align " << Op.getBaseAlignment();
7384af7e610SAlex Lorenz   // TODO: Print the metadata attributes.
7394af7e610SAlex Lorenz   OS << ')';
7404af7e610SAlex Lorenz }
7414af7e610SAlex Lorenz 
7428cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
7438cfc6867SAlex Lorenz                              const TargetRegisterInfo *TRI) {
7448cfc6867SAlex Lorenz   int Reg = TRI->getLLVMRegNum(DwarfReg, true);
7458cfc6867SAlex Lorenz   if (Reg == -1) {
7468cfc6867SAlex Lorenz     OS << "<badreg>";
7478cfc6867SAlex Lorenz     return;
7488cfc6867SAlex Lorenz   }
7498cfc6867SAlex Lorenz   printReg(Reg, OS, TRI);
7508cfc6867SAlex Lorenz }
7518cfc6867SAlex Lorenz 
7528cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI,
7538cfc6867SAlex Lorenz                       const TargetRegisterInfo *TRI) {
754f4baeb51SAlex Lorenz   switch (CFI.getOperation()) {
7558cfc6867SAlex Lorenz   case MCCFIInstruction::OpOffset:
7568cfc6867SAlex Lorenz     OS << ".cfi_offset ";
7578cfc6867SAlex Lorenz     if (CFI.getLabel())
7588cfc6867SAlex Lorenz       OS << "<mcsymbol> ";
7598cfc6867SAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
7608cfc6867SAlex Lorenz     OS << ", " << CFI.getOffset();
7618cfc6867SAlex Lorenz     break;
7625b0d5f6fSAlex Lorenz   case MCCFIInstruction::OpDefCfaRegister:
7635b0d5f6fSAlex Lorenz     OS << ".cfi_def_cfa_register ";
7645b0d5f6fSAlex Lorenz     if (CFI.getLabel())
7655b0d5f6fSAlex Lorenz       OS << "<mcsymbol> ";
7665b0d5f6fSAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
7675b0d5f6fSAlex Lorenz     break;
768f4baeb51SAlex Lorenz   case MCCFIInstruction::OpDefCfaOffset:
769f4baeb51SAlex Lorenz     OS << ".cfi_def_cfa_offset ";
770f4baeb51SAlex Lorenz     if (CFI.getLabel())
771f4baeb51SAlex Lorenz       OS << "<mcsymbol> ";
772f4baeb51SAlex Lorenz     OS << CFI.getOffset();
773f4baeb51SAlex Lorenz     break;
774b139323fSAlex Lorenz   case MCCFIInstruction::OpDefCfa:
775b139323fSAlex Lorenz     OS << ".cfi_def_cfa ";
776b139323fSAlex Lorenz     if (CFI.getLabel())
777b139323fSAlex Lorenz       OS << "<mcsymbol> ";
778b139323fSAlex Lorenz     printCFIRegister(CFI.getRegister(), OS, TRI);
779b139323fSAlex Lorenz     OS << ", " << CFI.getOffset();
780b139323fSAlex Lorenz     break;
781f4baeb51SAlex Lorenz   default:
782f4baeb51SAlex Lorenz     // TODO: Print the other CFI Operations.
783f4baeb51SAlex Lorenz     OS << "<unserializable cfi operation>";
784f4baeb51SAlex Lorenz     break;
785f4baeb51SAlex Lorenz   }
786f4baeb51SAlex Lorenz }
787f4baeb51SAlex Lorenz 
788345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) {
789345c1449SAlex Lorenz   yaml::Output Out(OS);
790345c1449SAlex Lorenz   Out << const_cast<Module &>(M);
791345c1449SAlex Lorenz }
792345c1449SAlex Lorenz 
793345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
794345c1449SAlex Lorenz   MIRPrinter Printer(OS);
795345c1449SAlex Lorenz   Printer.print(MF);
796345c1449SAlex Lorenz }
797