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 
153f833edcSDavid Blaikie #include "llvm/CodeGen/MIRPrinter.h"
16fb69e66cSEugene Zelenko #include "llvm/ADT/DenseMap.h"
17fb69e66cSEugene Zelenko #include "llvm/ADT/None.h"
183f833edcSDavid Blaikie #include "llvm/ADT/STLExtras.h"
19d28d3cc0STim Northover #include "llvm/ADT/SmallBitVector.h"
20fb69e66cSEugene Zelenko #include "llvm/ADT/SmallPtrSet.h"
21fb69e66cSEugene Zelenko #include "llvm/ADT/SmallVector.h"
22bb80d3e1SKonstantin Zhuravlyov #include "llvm/ADT/StringExtras.h"
23fb69e66cSEugene Zelenko #include "llvm/ADT/StringRef.h"
24fb69e66cSEugene Zelenko #include "llvm/ADT/Twine.h"
25fab1cfe6SQuentin Colombet #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
263f833edcSDavid Blaikie #include "llvm/CodeGen/MIRYamlMapping.h"
27fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h"
28ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h"
2960541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h"
30fab1cfe6SQuentin Colombet #include "llvm/CodeGen/MachineFunction.h"
31fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineInstr.h"
32fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineJumpTableInfo.h"
334af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h"
34fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineOperand.h"
3554565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h"
36fb69e66cSEugene Zelenko #include "llvm/CodeGen/PseudoSourceValue.h"
373f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
38b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
39b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
404f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h"
41deb53490SAlex Lorenz #include "llvm/IR/Constants.h"
4228865809SReid Kleckner #include "llvm/IR/DebugInfo.h"
43fb69e66cSEugene Zelenko #include "llvm/IR/DebugLoc.h"
44fb69e66cSEugene Zelenko #include "llvm/IR/Function.h"
45fb69e66cSEugene Zelenko #include "llvm/IR/GlobalValue.h"
463f833edcSDavid Blaikie #include "llvm/IR/IRPrintingPasses.h"
47fb69e66cSEugene Zelenko #include "llvm/IR/InstrTypes.h"
48fab1cfe6SQuentin Colombet #include "llvm/IR/Instructions.h"
496b3bd612STim Northover #include "llvm/IR/Intrinsics.h"
50345c1449SAlex Lorenz #include "llvm/IR/Module.h"
51900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h"
52fb69e66cSEugene Zelenko #include "llvm/IR/Value.h"
53fb69e66cSEugene Zelenko #include "llvm/MC/LaneBitmask.h"
54fb69e66cSEugene Zelenko #include "llvm/MC/MCDwarf.h"
55f22ca8adSAlex Lorenz #include "llvm/MC/MCSymbol.h"
56fb69e66cSEugene Zelenko #include "llvm/Support/AtomicOrdering.h"
57fb69e66cSEugene Zelenko #include "llvm/Support/BranchProbability.h"
58fb69e66cSEugene Zelenko #include "llvm/Support/Casting.h"
59fb69e66cSEugene Zelenko #include "llvm/Support/CommandLine.h"
60fb69e66cSEugene Zelenko #include "llvm/Support/ErrorHandling.h"
61b51774acSGeoff Berry #include "llvm/Support/Format.h"
62fb69e66cSEugene Zelenko #include "llvm/Support/LowLevelTypeImpl.h"
63fb69e66cSEugene Zelenko #include "llvm/Support/YAMLTraits.h"
643f833edcSDavid Blaikie #include "llvm/Support/raw_ostream.h"
656b3bd612STim Northover #include "llvm/Target/TargetIntrinsicInfo.h"
66fb69e66cSEugene Zelenko #include "llvm/Target/TargetMachine.h"
67fb69e66cSEugene Zelenko #include <algorithm>
68fb69e66cSEugene Zelenko #include <cassert>
69fb69e66cSEugene Zelenko #include <cinttypes>
70fb69e66cSEugene Zelenko #include <cstdint>
71fb69e66cSEugene Zelenko #include <iterator>
72fb69e66cSEugene Zelenko #include <string>
73fb69e66cSEugene Zelenko #include <utility>
74fb69e66cSEugene Zelenko #include <vector>
75345c1449SAlex Lorenz 
76345c1449SAlex Lorenz using namespace llvm;
77345c1449SAlex Lorenz 
788065f0b9SZachary Turner static cl::opt<bool> SimplifyMIR(
798065f0b9SZachary Turner     "simplify-mir", cl::Hidden,
808940114fSMatthias Braun     cl::desc("Leave out unnecessary information when printing MIR"));
818940114fSMatthias Braun 
82345c1449SAlex Lorenz namespace {
83345c1449SAlex Lorenz 
847feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references.
857feaf7c6SAlex Lorenz struct FrameIndexOperand {
867feaf7c6SAlex Lorenz   std::string Name;
877feaf7c6SAlex Lorenz   unsigned ID;
887feaf7c6SAlex Lorenz   bool IsFixed;
897feaf7c6SAlex Lorenz 
907feaf7c6SAlex Lorenz   FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
917feaf7c6SAlex Lorenz       : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
927feaf7c6SAlex Lorenz 
937feaf7c6SAlex Lorenz   /// Return an ordinary stack object reference.
947feaf7c6SAlex Lorenz   static FrameIndexOperand create(StringRef Name, unsigned ID) {
957feaf7c6SAlex Lorenz     return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
967feaf7c6SAlex Lorenz   }
977feaf7c6SAlex Lorenz 
987feaf7c6SAlex Lorenz   /// Return a fixed stack object reference.
997feaf7c6SAlex Lorenz   static FrameIndexOperand createFixed(unsigned ID) {
1007feaf7c6SAlex Lorenz     return FrameIndexOperand("", ID, /*IsFixed=*/true);
1017feaf7c6SAlex Lorenz   }
1027feaf7c6SAlex Lorenz };
1037feaf7c6SAlex Lorenz 
104618b283cSAlex Lorenz } // end anonymous namespace
105618b283cSAlex Lorenz 
106618b283cSAlex Lorenz namespace llvm {
107618b283cSAlex Lorenz 
108345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization
109345c1449SAlex Lorenz /// format.
110345c1449SAlex Lorenz class MIRPrinter {
111345c1449SAlex Lorenz   raw_ostream &OS;
1128f6f4285SAlex Lorenz   DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
1137feaf7c6SAlex Lorenz   /// Maps from stack object indices to operand indices which will be used when
1147feaf7c6SAlex Lorenz   /// printing frame index machine operands.
1157feaf7c6SAlex Lorenz   DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
116345c1449SAlex Lorenz 
117345c1449SAlex Lorenz public:
118345c1449SAlex Lorenz   MIRPrinter(raw_ostream &OS) : OS(OS) {}
119345c1449SAlex Lorenz 
120345c1449SAlex Lorenz   void print(const MachineFunction &MF);
1214f093bf1SAlex Lorenz 
12228148ba8SAlex Lorenz   void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
12328148ba8SAlex Lorenz                const TargetRegisterInfo *TRI);
124a6f9a37dSAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
125a6f9a37dSAlex Lorenz                const MachineFrameInfo &MFI);
126ab980499SAlex Lorenz   void convert(yaml::MachineFunction &MF,
127ab980499SAlex Lorenz                const MachineConstantPool &ConstantPool);
1286799e9b3SAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
1296799e9b3SAlex Lorenz                const MachineJumpTableInfo &JTI);
130ef331effSMatthias Braun   void convertStackObjects(yaml::MachineFunction &YMF,
131ef331effSMatthias Braun                            const MachineFunction &MF, ModuleSlotTracker &MST);
1328f6f4285SAlex Lorenz 
1338f6f4285SAlex Lorenz private:
1348f6f4285SAlex Lorenz   void initRegisterMaskIds(const MachineFunction &MF);
135345c1449SAlex Lorenz };
136345c1449SAlex Lorenz 
1378e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization
1388e0a1b48SAlex Lorenz /// format.
1398e0a1b48SAlex Lorenz class MIPrinter {
1408e0a1b48SAlex Lorenz   raw_ostream &OS;
141900b5cb2SAlex Lorenz   ModuleSlotTracker &MST;
1428f6f4285SAlex Lorenz   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
1437feaf7c6SAlex Lorenz   const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
144bb80d3e1SKonstantin Zhuravlyov   /// Synchronization scope names registered with LLVMContext.
145bb80d3e1SKonstantin Zhuravlyov   SmallVector<StringRef, 8> SSNs;
1468e0a1b48SAlex Lorenz 
1478940114fSMatthias Braun   bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const;
1488940114fSMatthias Braun   bool canPredictSuccessors(const MachineBasicBlock &MBB) const;
1498940114fSMatthias Braun 
1508e0a1b48SAlex Lorenz public:
151900b5cb2SAlex Lorenz   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
1527feaf7c6SAlex Lorenz             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
1537feaf7c6SAlex Lorenz             const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
1547feaf7c6SAlex Lorenz       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
1557feaf7c6SAlex Lorenz         StackObjectOperandMapping(StackObjectOperandMapping) {}
1568e0a1b48SAlex Lorenz 
1575022f6bbSAlex Lorenz   void print(const MachineBasicBlock &MBB);
1585022f6bbSAlex Lorenz 
1598e0a1b48SAlex Lorenz   void print(const MachineInstr &MI);
160deb53490SAlex Lorenz   void printIRBlockReference(const BasicBlock &BB);
1614af7e610SAlex Lorenz   void printIRValueReference(const Value &V);
1627feaf7c6SAlex Lorenz   void printStackObjectReference(int FrameIndex);
163a42ed3e3SBjorn Pettersson   void print(const MachineInstr &MI, unsigned OpIdx,
164a42ed3e3SBjorn Pettersson              const TargetRegisterInfo *TRI, bool ShouldPrintRegisterTies,
165a8a83d15SFrancis Visoiu Mistrih              LLT TypeToPrint, bool PrintDef = true);
1666748abe2SGeoff Berry   void print(const LLVMContext &Context, const TargetInstrInfo &TII,
1676748abe2SGeoff Berry              const MachineMemOperand &Op);
168bb80d3e1SKonstantin Zhuravlyov   void printSyncScope(const LLVMContext &Context, SyncScope::ID SSID);
1698e0a1b48SAlex Lorenz };
1708e0a1b48SAlex Lorenz 
1715022f6bbSAlex Lorenz } // end namespace llvm
172345c1449SAlex Lorenz 
173345c1449SAlex Lorenz namespace llvm {
174345c1449SAlex Lorenz namespace yaml {
175345c1449SAlex Lorenz 
176345c1449SAlex Lorenz /// This struct serializes the LLVM IR module.
177345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> {
178345c1449SAlex Lorenz   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
179345c1449SAlex Lorenz     Mod.print(OS, nullptr);
180345c1449SAlex Lorenz   }
181fb69e66cSEugene Zelenko 
182345c1449SAlex Lorenz   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
183345c1449SAlex Lorenz     llvm_unreachable("LLVM Module is supposed to be parsed separately");
184345c1449SAlex Lorenz     return "";
185345c1449SAlex Lorenz   }
186345c1449SAlex Lorenz };
187345c1449SAlex Lorenz 
188345c1449SAlex Lorenz } // end namespace yaml
189345c1449SAlex Lorenz } // end namespace llvm
190345c1449SAlex Lorenz 
1919d419d3bSFrancis Visoiu Mistrih static void printRegMIR(unsigned Reg, yaml::StringValue &Dest,
192ab4cbcfdSAlex Lorenz                         const TargetRegisterInfo *TRI) {
193ab4cbcfdSAlex Lorenz   raw_string_ostream OS(Dest.Value);
194c71cced0SFrancis Visoiu Mistrih   OS << printReg(Reg, TRI);
195ab4cbcfdSAlex Lorenz }
196ab4cbcfdSAlex Lorenz 
197345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) {
1988f6f4285SAlex Lorenz   initRegisterMaskIds(MF);
1998f6f4285SAlex Lorenz 
200345c1449SAlex Lorenz   yaml::MachineFunction YamlMF;
201345c1449SAlex Lorenz   YamlMF.Name = MF.getName();
2025b5f9753SAlex Lorenz   YamlMF.Alignment = MF.getAlignment();
2035b5f9753SAlex Lorenz   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
204ad154c83SDerek Schuff 
2050d7b0cb8SAhmed Bougacha   YamlMF.Legalized = MF.getProperties().hasProperty(
2060d7b0cb8SAhmed Bougacha       MachineFunctionProperties::Property::Legalized);
20724712655SAhmed Bougacha   YamlMF.RegBankSelected = MF.getProperties().hasProperty(
20824712655SAhmed Bougacha       MachineFunctionProperties::Property::RegBankSelected);
209b109d518SAhmed Bougacha   YamlMF.Selected = MF.getProperties().hasProperty(
210b109d518SAhmed Bougacha       MachineFunctionProperties::Property::Selected);
2110d7b0cb8SAhmed Bougacha 
21228148ba8SAlex Lorenz   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
213f1caa283SMatthias Braun   ModuleSlotTracker MST(MF.getFunction().getParent());
214f1caa283SMatthias Braun   MST.incorporateFunction(MF.getFunction());
215941a705bSMatthias Braun   convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
216ef331effSMatthias Braun   convertStackObjects(YamlMF, MF, MST);
217ab980499SAlex Lorenz   if (const auto *ConstantPool = MF.getConstantPool())
218ab980499SAlex Lorenz     convert(YamlMF, *ConstantPool);
2196799e9b3SAlex Lorenz   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
2206799e9b3SAlex Lorenz     convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
2215022f6bbSAlex Lorenz   raw_string_ostream StrOS(YamlMF.Body.Value.Value);
2225022f6bbSAlex Lorenz   bool IsNewlineNeeded = false;
2234f093bf1SAlex Lorenz   for (const auto &MBB : MF) {
2245022f6bbSAlex Lorenz     if (IsNewlineNeeded)
2255022f6bbSAlex Lorenz       StrOS << "\n";
2265022f6bbSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
2275022f6bbSAlex Lorenz         .print(MBB);
2285022f6bbSAlex Lorenz     IsNewlineNeeded = true;
2294f093bf1SAlex Lorenz   }
2305022f6bbSAlex Lorenz   StrOS.flush();
231345c1449SAlex Lorenz   yaml::Output Out(OS);
23256d87ef5SVivek Pandya   if (!SimplifyMIR)
23356d87ef5SVivek Pandya       Out.setWriteDefaultValues(true);
234345c1449SAlex Lorenz   Out << YamlMF;
235345c1449SAlex Lorenz }
236345c1449SAlex Lorenz 
2370ef61ec3SOren Ben Simhon static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,
2380ef61ec3SOren Ben Simhon                                const TargetRegisterInfo *TRI) {
2390ef61ec3SOren Ben Simhon   assert(RegMask && "Can't print an empty register mask");
2400ef61ec3SOren Ben Simhon   OS << StringRef("CustomRegMask(");
2410ef61ec3SOren Ben Simhon 
2420ef61ec3SOren Ben Simhon   bool IsRegInRegMaskFound = false;
2430ef61ec3SOren Ben Simhon   for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {
2440ef61ec3SOren Ben Simhon     // Check whether the register is asserted in regmask.
2450ef61ec3SOren Ben Simhon     if (RegMask[I / 32] & (1u << (I % 32))) {
2460ef61ec3SOren Ben Simhon       if (IsRegInRegMaskFound)
2470ef61ec3SOren Ben Simhon         OS << ',';
248c71cced0SFrancis Visoiu Mistrih       OS << printReg(I, TRI);
2490ef61ec3SOren Ben Simhon       IsRegInRegMaskFound = true;
2500ef61ec3SOren Ben Simhon     }
2510ef61ec3SOren Ben Simhon   }
2520ef61ec3SOren Ben Simhon 
2530ef61ec3SOren Ben Simhon   OS << ')';
2540ef61ec3SOren Ben Simhon }
2550ef61ec3SOren Ben Simhon 
2566c452834SJustin Bogner static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest,
2576c452834SJustin Bogner                                 const MachineRegisterInfo &RegInfo,
2586c452834SJustin Bogner                                 const TargetRegisterInfo *TRI) {
2596c452834SJustin Bogner   raw_string_ostream OS(Dest.Value);
260a8a83d15SFrancis Visoiu Mistrih   OS << printRegClassOrBank(Reg, RegInfo, TRI);
2616c452834SJustin Bogner }
2626c452834SJustin Bogner 
2636c452834SJustin Bogner 
26454565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
26528148ba8SAlex Lorenz                          const MachineRegisterInfo &RegInfo,
26628148ba8SAlex Lorenz                          const TargetRegisterInfo *TRI) {
26754565cf0SAlex Lorenz   MF.TracksRegLiveness = RegInfo.tracksLiveness();
26828148ba8SAlex Lorenz 
26928148ba8SAlex Lorenz   // Print the virtual register definitions.
27028148ba8SAlex Lorenz   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
27128148ba8SAlex Lorenz     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
27228148ba8SAlex Lorenz     yaml::VirtualRegisterDefinition VReg;
27328148ba8SAlex Lorenz     VReg.ID = I;
274a8a83d15SFrancis Visoiu Mistrih     ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);
275ab4cbcfdSAlex Lorenz     unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
276ab4cbcfdSAlex Lorenz     if (PreferredReg)
2779d419d3bSFrancis Visoiu Mistrih       printRegMIR(PreferredReg, VReg.PreferredRegister, TRI);
27828148ba8SAlex Lorenz     MF.VirtualRegisters.push_back(VReg);
27928148ba8SAlex Lorenz   }
28012045a4bSAlex Lorenz 
28112045a4bSAlex Lorenz   // Print the live ins.
28272518eaaSKrzysztof Parzyszek   for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) {
28312045a4bSAlex Lorenz     yaml::MachineFunctionLiveIn LiveIn;
2849d419d3bSFrancis Visoiu Mistrih     printRegMIR(LI.first, LiveIn.Register, TRI);
28572518eaaSKrzysztof Parzyszek     if (LI.second)
2869d419d3bSFrancis Visoiu Mistrih       printRegMIR(LI.second, LiveIn.VirtualRegister, TRI);
28712045a4bSAlex Lorenz     MF.LiveIns.push_back(LiveIn);
28812045a4bSAlex Lorenz   }
2890ef61ec3SOren Ben Simhon 
2900ef61ec3SOren Ben Simhon   // Prints the callee saved registers.
2910ef61ec3SOren Ben Simhon   if (RegInfo.isUpdatedCSRsInitialized()) {
2920ef61ec3SOren Ben Simhon     const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
293c4838087SAlex Lorenz     std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
2940ef61ec3SOren Ben Simhon     for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
295c4838087SAlex Lorenz       yaml::FlowStringValue Reg;
2969d419d3bSFrancis Visoiu Mistrih       printRegMIR(*I, Reg, TRI);
297c4838087SAlex Lorenz       CalleeSavedRegisters.push_back(Reg);
298c4838087SAlex Lorenz     }
299c4838087SAlex Lorenz     MF.CalleeSavedRegisters = CalleeSavedRegisters;
30054565cf0SAlex Lorenz   }
3010ef61ec3SOren Ben Simhon }
30254565cf0SAlex Lorenz 
303a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
304a6f9a37dSAlex Lorenz                          yaml::MachineFrameInfo &YamlMFI,
30560541c1dSAlex Lorenz                          const MachineFrameInfo &MFI) {
30660541c1dSAlex Lorenz   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
30760541c1dSAlex Lorenz   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
30860541c1dSAlex Lorenz   YamlMFI.HasStackMap = MFI.hasStackMap();
30960541c1dSAlex Lorenz   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
31060541c1dSAlex Lorenz   YamlMFI.StackSize = MFI.getStackSize();
31160541c1dSAlex Lorenz   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
31260541c1dSAlex Lorenz   YamlMFI.MaxAlignment = MFI.getMaxAlignment();
31360541c1dSAlex Lorenz   YamlMFI.AdjustsStack = MFI.adjustsStack();
31460541c1dSAlex Lorenz   YamlMFI.HasCalls = MFI.hasCalls();
315ab9438cbSMatthias Braun   YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()
316ab9438cbSMatthias Braun     ? MFI.getMaxCallFrameSize() : ~0u;
31760541c1dSAlex Lorenz   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
31860541c1dSAlex Lorenz   YamlMFI.HasVAStart = MFI.hasVAStart();
31960541c1dSAlex Lorenz   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
320a6f9a37dSAlex Lorenz   if (MFI.getSavePoint()) {
321a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
32225528d6dSFrancis Visoiu Mistrih     StrOS << printMBBReference(*MFI.getSavePoint());
323a6f9a37dSAlex Lorenz   }
324a6f9a37dSAlex Lorenz   if (MFI.getRestorePoint()) {
325a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
32625528d6dSFrancis Visoiu Mistrih     StrOS << printMBBReference(*MFI.getRestorePoint());
327a6f9a37dSAlex Lorenz   }
32860541c1dSAlex Lorenz }
32960541c1dSAlex Lorenz 
330ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
331ef331effSMatthias Braun                                      const MachineFunction &MF,
332ef331effSMatthias Braun                                      ModuleSlotTracker &MST) {
333ef331effSMatthias Braun   const MachineFrameInfo &MFI = MF.getFrameInfo();
334ef331effSMatthias Braun   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
335de491f05SAlex Lorenz   // Process fixed stack objects.
336f6bc8667SAlex Lorenz   unsigned ID = 0;
337de491f05SAlex Lorenz   for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
338de491f05SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
339de491f05SAlex Lorenz       continue;
340de491f05SAlex Lorenz 
341de491f05SAlex Lorenz     yaml::FixedMachineStackObject YamlObject;
3427feaf7c6SAlex Lorenz     YamlObject.ID = ID;
343de491f05SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
344de491f05SAlex Lorenz                           ? yaml::FixedMachineStackObject::SpillSlot
345de491f05SAlex Lorenz                           : yaml::FixedMachineStackObject::DefaultType;
346de491f05SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
347de491f05SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
348de491f05SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
349db78273bSMatt Arsenault     YamlObject.StackID = MFI.getStackID(I);
350de491f05SAlex Lorenz     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
351de491f05SAlex Lorenz     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
352ef331effSMatthias Braun     YMF.FixedStackObjects.push_back(YamlObject);
3537feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(
3547feaf7c6SAlex Lorenz         std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
355de491f05SAlex Lorenz   }
356de491f05SAlex Lorenz 
357de491f05SAlex Lorenz   // Process ordinary stack objects.
358de491f05SAlex Lorenz   ID = 0;
359f6bc8667SAlex Lorenz   for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
360f6bc8667SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
361f6bc8667SAlex Lorenz       continue;
362f6bc8667SAlex Lorenz 
363f6bc8667SAlex Lorenz     yaml::MachineStackObject YamlObject;
3647feaf7c6SAlex Lorenz     YamlObject.ID = ID;
36537643a04SAlex Lorenz     if (const auto *Alloca = MFI.getObjectAllocation(I))
36637643a04SAlex Lorenz       YamlObject.Name.Value =
36737643a04SAlex Lorenz           Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
368f6bc8667SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
369f6bc8667SAlex Lorenz                           ? yaml::MachineStackObject::SpillSlot
370418f3ec1SAlex Lorenz                           : MFI.isVariableSizedObjectIndex(I)
371418f3ec1SAlex Lorenz                                 ? yaml::MachineStackObject::VariableSized
372f6bc8667SAlex Lorenz                                 : yaml::MachineStackObject::DefaultType;
373f6bc8667SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
374f6bc8667SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
375f6bc8667SAlex Lorenz     YamlObject.Alignment = MFI.getObjectAlignment(I);
376db78273bSMatt Arsenault     YamlObject.StackID = MFI.getStackID(I);
377f6bc8667SAlex Lorenz 
378ef331effSMatthias Braun     YMF.StackObjects.push_back(YamlObject);
3797feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(std::make_pair(
3807feaf7c6SAlex Lorenz         I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
381f6bc8667SAlex Lorenz   }
3821bb48de1SAlex Lorenz 
3831bb48de1SAlex Lorenz   for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
3841bb48de1SAlex Lorenz     yaml::StringValue Reg;
3859d419d3bSFrancis Visoiu Mistrih     printRegMIR(CSInfo.getReg(), Reg, TRI);
3861bb48de1SAlex Lorenz     auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
3871bb48de1SAlex Lorenz     assert(StackObjectInfo != StackObjectOperandMapping.end() &&
3881bb48de1SAlex Lorenz            "Invalid stack object index");
3891bb48de1SAlex Lorenz     const FrameIndexOperand &StackObject = StackObjectInfo->second;
3905c3e8a45SMatthias Braun     if (StackObject.IsFixed) {
391ef331effSMatthias Braun       YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
3925c3e8a45SMatthias Braun       YMF.FixedStackObjects[StackObject.ID].CalleeSavedRestored =
3935c3e8a45SMatthias Braun         CSInfo.isRestored();
3945c3e8a45SMatthias Braun     } else {
395ef331effSMatthias Braun       YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
3965c3e8a45SMatthias Braun       YMF.StackObjects[StackObject.ID].CalleeSavedRestored =
3975c3e8a45SMatthias Braun         CSInfo.isRestored();
3985c3e8a45SMatthias Braun     }
3991bb48de1SAlex Lorenz   }
400a56ba6a6SAlex Lorenz   for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
401a56ba6a6SAlex Lorenz     auto LocalObject = MFI.getLocalFrameObjectMap(I);
402a56ba6a6SAlex Lorenz     auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first);
403a56ba6a6SAlex Lorenz     assert(StackObjectInfo != StackObjectOperandMapping.end() &&
404a56ba6a6SAlex Lorenz            "Invalid stack object index");
405a56ba6a6SAlex Lorenz     const FrameIndexOperand &StackObject = StackObjectInfo->second;
406a56ba6a6SAlex Lorenz     assert(!StackObject.IsFixed && "Expected a locally mapped stack object");
407ef331effSMatthias Braun     YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second;
408a56ba6a6SAlex Lorenz   }
409a314d813SAlex Lorenz 
410a314d813SAlex Lorenz   // Print the stack object references in the frame information class after
411a314d813SAlex Lorenz   // converting the stack objects.
412a314d813SAlex Lorenz   if (MFI.hasStackProtectorIndex()) {
413ef331effSMatthias Braun     raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);
414a314d813SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
415a314d813SAlex Lorenz         .printStackObjectReference(MFI.getStackProtectorIndex());
416a314d813SAlex Lorenz   }
417df9e3c6fSAlex Lorenz 
418df9e3c6fSAlex Lorenz   // Print the debug variable information.
419ef331effSMatthias Braun   for (const MachineFunction::VariableDbgInfo &DebugVar :
420ef331effSMatthias Braun        MF.getVariableDbgInfo()) {
421df9e3c6fSAlex Lorenz     auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot);
422df9e3c6fSAlex Lorenz     assert(StackObjectInfo != StackObjectOperandMapping.end() &&
423df9e3c6fSAlex Lorenz            "Invalid stack object index");
424df9e3c6fSAlex Lorenz     const FrameIndexOperand &StackObject = StackObjectInfo->second;
425df9e3c6fSAlex Lorenz     assert(!StackObject.IsFixed && "Expected a non-fixed stack object");
426ef331effSMatthias Braun     auto &Object = YMF.StackObjects[StackObject.ID];
427df9e3c6fSAlex Lorenz     {
428df9e3c6fSAlex Lorenz       raw_string_ostream StrOS(Object.DebugVar.Value);
429df9e3c6fSAlex Lorenz       DebugVar.Var->printAsOperand(StrOS, MST);
430df9e3c6fSAlex Lorenz     }
431df9e3c6fSAlex Lorenz     {
432df9e3c6fSAlex Lorenz       raw_string_ostream StrOS(Object.DebugExpr.Value);
433df9e3c6fSAlex Lorenz       DebugVar.Expr->printAsOperand(StrOS, MST);
434df9e3c6fSAlex Lorenz     }
435df9e3c6fSAlex Lorenz     {
436df9e3c6fSAlex Lorenz       raw_string_ostream StrOS(Object.DebugLoc.Value);
437df9e3c6fSAlex Lorenz       DebugVar.Loc->printAsOperand(StrOS, MST);
438df9e3c6fSAlex Lorenz     }
439df9e3c6fSAlex Lorenz   }
440f6bc8667SAlex Lorenz }
441f6bc8667SAlex Lorenz 
442ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
443ab980499SAlex Lorenz                          const MachineConstantPool &ConstantPool) {
444ab980499SAlex Lorenz   unsigned ID = 0;
445ab980499SAlex Lorenz   for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
446ab980499SAlex Lorenz     std::string Str;
447ab980499SAlex Lorenz     raw_string_ostream StrOS(Str);
448d5a00b0fSDiana Picus     if (Constant.isMachineConstantPoolEntry()) {
449d5a00b0fSDiana Picus       Constant.Val.MachineCPVal->print(StrOS);
450d5a00b0fSDiana Picus     } else {
451ab980499SAlex Lorenz       Constant.Val.ConstVal->printAsOperand(StrOS);
452d5a00b0fSDiana Picus     }
453d5a00b0fSDiana Picus 
454d5a00b0fSDiana Picus     yaml::MachineConstantPoolValue YamlConstant;
455ab980499SAlex Lorenz     YamlConstant.ID = ID++;
456ab980499SAlex Lorenz     YamlConstant.Value = StrOS.str();
457ab980499SAlex Lorenz     YamlConstant.Alignment = Constant.getAlignment();
458d5a00b0fSDiana Picus     YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();
459d5a00b0fSDiana Picus 
460ab980499SAlex Lorenz     MF.Constants.push_back(YamlConstant);
461ab980499SAlex Lorenz   }
462ab980499SAlex Lorenz }
463ab980499SAlex Lorenz 
464900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
4656799e9b3SAlex Lorenz                          yaml::MachineJumpTable &YamlJTI,
4666799e9b3SAlex Lorenz                          const MachineJumpTableInfo &JTI) {
4676799e9b3SAlex Lorenz   YamlJTI.Kind = JTI.getEntryKind();
4686799e9b3SAlex Lorenz   unsigned ID = 0;
4696799e9b3SAlex Lorenz   for (const auto &Table : JTI.getJumpTables()) {
4706799e9b3SAlex Lorenz     std::string Str;
4716799e9b3SAlex Lorenz     yaml::MachineJumpTable::Entry Entry;
4726799e9b3SAlex Lorenz     Entry.ID = ID++;
4736799e9b3SAlex Lorenz     for (const auto *MBB : Table.MBBs) {
4746799e9b3SAlex Lorenz       raw_string_ostream StrOS(Str);
47525528d6dSFrancis Visoiu Mistrih       StrOS << printMBBReference(*MBB);
4766799e9b3SAlex Lorenz       Entry.Blocks.push_back(StrOS.str());
4776799e9b3SAlex Lorenz       Str.clear();
4786799e9b3SAlex Lorenz     }
4796799e9b3SAlex Lorenz     YamlJTI.Entries.push_back(Entry);
4806799e9b3SAlex Lorenz   }
4816799e9b3SAlex Lorenz }
4826799e9b3SAlex Lorenz 
4838f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
4848f6f4285SAlex Lorenz   const auto *TRI = MF.getSubtarget().getRegisterInfo();
4858f6f4285SAlex Lorenz   unsigned I = 0;
4868f6f4285SAlex Lorenz   for (const uint32_t *Mask : TRI->getRegMasks())
4878f6f4285SAlex Lorenz     RegisterMaskIds.insert(std::make_pair(Mask, I++));
4888f6f4285SAlex Lorenz }
4898f6f4285SAlex Lorenz 
4908940114fSMatthias Braun void llvm::guessSuccessors(const MachineBasicBlock &MBB,
4918940114fSMatthias Braun                            SmallVectorImpl<MachineBasicBlock*> &Result,
4928940114fSMatthias Braun                            bool &IsFallthrough) {
4938940114fSMatthias Braun   SmallPtrSet<MachineBasicBlock*,8> Seen;
4948940114fSMatthias Braun 
4958940114fSMatthias Braun   for (const MachineInstr &MI : MBB) {
4968940114fSMatthias Braun     if (MI.isPHI())
4978940114fSMatthias Braun       continue;
4988940114fSMatthias Braun     for (const MachineOperand &MO : MI.operands()) {
4998940114fSMatthias Braun       if (!MO.isMBB())
5008940114fSMatthias Braun         continue;
5018940114fSMatthias Braun       MachineBasicBlock *Succ = MO.getMBB();
5028940114fSMatthias Braun       auto RP = Seen.insert(Succ);
5038940114fSMatthias Braun       if (RP.second)
5048940114fSMatthias Braun         Result.push_back(Succ);
5058940114fSMatthias Braun     }
5068940114fSMatthias Braun   }
5078940114fSMatthias Braun   MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
5088940114fSMatthias Braun   IsFallthrough = I == MBB.end() || !I->isBarrier();
5098940114fSMatthias Braun }
5108940114fSMatthias Braun 
5118940114fSMatthias Braun bool
5128940114fSMatthias Braun MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const {
5138940114fSMatthias Braun   if (MBB.succ_size() <= 1)
5148940114fSMatthias Braun     return true;
5158940114fSMatthias Braun   if (!MBB.hasSuccessorProbabilities())
5168940114fSMatthias Braun     return true;
5178940114fSMatthias Braun 
5188940114fSMatthias Braun   SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(),
5198940114fSMatthias Braun                                               MBB.Probs.end());
5208940114fSMatthias Braun   BranchProbability::normalizeProbabilities(Normalized.begin(),
5218940114fSMatthias Braun                                             Normalized.end());
5228940114fSMatthias Braun   SmallVector<BranchProbability,8> Equal(Normalized.size());
5238940114fSMatthias Braun   BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end());
5248940114fSMatthias Braun 
5258940114fSMatthias Braun   return std::equal(Normalized.begin(), Normalized.end(), Equal.begin());
5268940114fSMatthias Braun }
5278940114fSMatthias Braun 
5288940114fSMatthias Braun bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const {
5298940114fSMatthias Braun   SmallVector<MachineBasicBlock*,8> GuessedSuccs;
5308940114fSMatthias Braun   bool GuessedFallthrough;
5318940114fSMatthias Braun   guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough);
5328940114fSMatthias Braun   if (GuessedFallthrough) {
5338940114fSMatthias Braun     const MachineFunction &MF = *MBB.getParent();
5348940114fSMatthias Braun     MachineFunction::const_iterator NextI = std::next(MBB.getIterator());
5358940114fSMatthias Braun     if (NextI != MF.end()) {
5368940114fSMatthias Braun       MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);
5378940114fSMatthias Braun       if (!is_contained(GuessedSuccs, Next))
5388940114fSMatthias Braun         GuessedSuccs.push_back(Next);
5398940114fSMatthias Braun     }
5408940114fSMatthias Braun   }
5418940114fSMatthias Braun   if (GuessedSuccs.size() != MBB.succ_size())
5428940114fSMatthias Braun     return false;
5438940114fSMatthias Braun   return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin());
5448940114fSMatthias Braun }
5458940114fSMatthias Braun 
5465022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) {
5475022f6bbSAlex Lorenz   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
5485022f6bbSAlex Lorenz   OS << "bb." << MBB.getNumber();
5495022f6bbSAlex Lorenz   bool HasAttributes = false;
5505022f6bbSAlex Lorenz   if (const auto *BB = MBB.getBasicBlock()) {
5515022f6bbSAlex Lorenz     if (BB->hasName()) {
5525022f6bbSAlex Lorenz       OS << "." << BB->getName();
5535022f6bbSAlex Lorenz     } else {
5545022f6bbSAlex Lorenz       HasAttributes = true;
5555022f6bbSAlex Lorenz       OS << " (";
5565022f6bbSAlex Lorenz       int Slot = MST.getLocalSlot(BB);
5575022f6bbSAlex Lorenz       if (Slot == -1)
5585022f6bbSAlex Lorenz         OS << "<ir-block badref>";
5595022f6bbSAlex Lorenz       else
5605022f6bbSAlex Lorenz         OS << (Twine("%ir-block.") + Twine(Slot)).str();
5615022f6bbSAlex Lorenz     }
5625022f6bbSAlex Lorenz   }
5635022f6bbSAlex Lorenz   if (MBB.hasAddressTaken()) {
5645022f6bbSAlex Lorenz     OS << (HasAttributes ? ", " : " (");
5655022f6bbSAlex Lorenz     OS << "address-taken";
5665022f6bbSAlex Lorenz     HasAttributes = true;
5675022f6bbSAlex Lorenz   }
5680e288234SReid Kleckner   if (MBB.isEHPad()) {
5695022f6bbSAlex Lorenz     OS << (HasAttributes ? ", " : " (");
5705022f6bbSAlex Lorenz     OS << "landing-pad";
5715022f6bbSAlex Lorenz     HasAttributes = true;
5725022f6bbSAlex Lorenz   }
5735022f6bbSAlex Lorenz   if (MBB.getAlignment()) {
5745022f6bbSAlex Lorenz     OS << (HasAttributes ? ", " : " (");
5755022f6bbSAlex Lorenz     OS << "align " << MBB.getAlignment();
5765022f6bbSAlex Lorenz     HasAttributes = true;
5775022f6bbSAlex Lorenz   }
5785022f6bbSAlex Lorenz   if (HasAttributes)
5795022f6bbSAlex Lorenz     OS << ")";
5805022f6bbSAlex Lorenz   OS << ":\n";
5815022f6bbSAlex Lorenz 
5825022f6bbSAlex Lorenz   bool HasLineAttributes = false;
5835022f6bbSAlex Lorenz   // Print the successors
5848940114fSMatthias Braun   bool canPredictProbs = canPredictBranchProbabilities(MBB);
585d652aeb1SQuentin Colombet   // Even if the list of successors is empty, if we cannot guess it,
586d652aeb1SQuentin Colombet   // we need to print it to tell the parser that the list is empty.
587d652aeb1SQuentin Colombet   // This is needed, because MI model unreachable as empty blocks
588d652aeb1SQuentin Colombet   // with an empty successor list. If the parser would see that
589d652aeb1SQuentin Colombet   // without the successor list, it would guess the code would
590d652aeb1SQuentin Colombet   // fallthrough.
591d652aeb1SQuentin Colombet   if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||
592d652aeb1SQuentin Colombet       !canPredictSuccessors(MBB)) {
5935022f6bbSAlex Lorenz     OS.indent(2) << "successors: ";
5945022f6bbSAlex Lorenz     for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
5955022f6bbSAlex Lorenz       if (I != MBB.succ_begin())
5965022f6bbSAlex Lorenz         OS << ", ";
59725528d6dSFrancis Visoiu Mistrih       OS << printMBBReference(**I);
5988940114fSMatthias Braun       if (!SimplifyMIR || !canPredictProbs)
599b51774acSGeoff Berry         OS << '('
600b51774acSGeoff Berry            << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator())
601b51774acSGeoff Berry            << ')';
6025022f6bbSAlex Lorenz     }
6035022f6bbSAlex Lorenz     OS << "\n";
6045022f6bbSAlex Lorenz     HasLineAttributes = true;
6055022f6bbSAlex Lorenz   }
6065022f6bbSAlex Lorenz 
6075022f6bbSAlex Lorenz   // Print the live in registers.
60811723322SMatthias Braun   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
60911723322SMatthias Braun   if (MRI.tracksLiveness() && !MBB.livein_empty()) {
61011723322SMatthias Braun     const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
6115022f6bbSAlex Lorenz     OS.indent(2) << "liveins: ";
612b2b7ef1dSMatthias Braun     bool First = true;
613d9da1627SMatthias Braun     for (const auto &LI : MBB.liveins()) {
614b2b7ef1dSMatthias Braun       if (!First)
6155022f6bbSAlex Lorenz         OS << ", ";
616b2b7ef1dSMatthias Braun       First = false;
617c71cced0SFrancis Visoiu Mistrih       OS << printReg(LI.PhysReg, &TRI);
61891b5cf84SKrzysztof Parzyszek       if (!LI.LaneMask.all())
619d62669d7SKrzysztof Parzyszek         OS << ":0x" << PrintLaneMask(LI.LaneMask);
6205022f6bbSAlex Lorenz     }
6215022f6bbSAlex Lorenz     OS << "\n";
6225022f6bbSAlex Lorenz     HasLineAttributes = true;
6235022f6bbSAlex Lorenz   }
6245022f6bbSAlex Lorenz 
6255022f6bbSAlex Lorenz   if (HasLineAttributes)
6265022f6bbSAlex Lorenz     OS << "\n";
627f9a2b123SAlex Lorenz   bool IsInBundle = false;
628f9a2b123SAlex Lorenz   for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) {
629f9a2b123SAlex Lorenz     const MachineInstr &MI = *I;
630f9a2b123SAlex Lorenz     if (IsInBundle && !MI.isInsideBundle()) {
631f9a2b123SAlex Lorenz       OS.indent(2) << "}\n";
632f9a2b123SAlex Lorenz       IsInBundle = false;
633f9a2b123SAlex Lorenz     }
634f9a2b123SAlex Lorenz     OS.indent(IsInBundle ? 4 : 2);
6355022f6bbSAlex Lorenz     print(MI);
636f9a2b123SAlex Lorenz     if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
637f9a2b123SAlex Lorenz       OS << " {";
638f9a2b123SAlex Lorenz       IsInBundle = true;
639f9a2b123SAlex Lorenz     }
6405022f6bbSAlex Lorenz     OS << "\n";
6415022f6bbSAlex Lorenz   }
642f9a2b123SAlex Lorenz   if (IsInBundle)
643f9a2b123SAlex Lorenz     OS.indent(2) << "}\n";
6445022f6bbSAlex Lorenz }
6455022f6bbSAlex Lorenz 
6468e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) {
647fdf9bf4fSJustin Bogner   const auto *MF = MI.getMF();
6484e14a497SQuentin Colombet   const auto &MRI = MF->getRegInfo();
6494e14a497SQuentin Colombet   const auto &SubTarget = MF->getSubtarget();
650f3db51deSAlex Lorenz   const auto *TRI = SubTarget.getRegisterInfo();
651f3db51deSAlex Lorenz   assert(TRI && "Expected target register info");
6528e0a1b48SAlex Lorenz   const auto *TII = SubTarget.getInstrInfo();
6538e0a1b48SAlex Lorenz   assert(TII && "Expected target instruction info");
654f4baeb51SAlex Lorenz   if (MI.isCFIInstruction())
655f4baeb51SAlex Lorenz     assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
6568e0a1b48SAlex Lorenz 
657d28d3cc0STim Northover   SmallBitVector PrintedTypes(8);
658a8a83d15SFrancis Visoiu Mistrih   bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();
659f3db51deSAlex Lorenz   unsigned I = 0, E = MI.getNumOperands();
660f3db51deSAlex Lorenz   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
661f3db51deSAlex Lorenz          !MI.getOperand(I).isImplicit();
662f3db51deSAlex Lorenz        ++I) {
663f3db51deSAlex Lorenz     if (I)
664f3db51deSAlex Lorenz       OS << ", ";
665a42ed3e3SBjorn Pettersson     print(MI, I, TRI, ShouldPrintRegisterTies,
666a8a83d15SFrancis Visoiu Mistrih           MI.getTypeToPrint(I, PrintedTypes, MRI),
667a8a83d15SFrancis Visoiu Mistrih           /*PrintDef=*/false);
668f3db51deSAlex Lorenz   }
669f3db51deSAlex Lorenz 
670f3db51deSAlex Lorenz   if (I)
671f3db51deSAlex Lorenz     OS << " = ";
672e5a44660SAlex Lorenz   if (MI.getFlag(MachineInstr::FrameSetup))
673e5a44660SAlex Lorenz     OS << "frame-setup ";
6748e0a1b48SAlex Lorenz   OS << TII->getName(MI.getOpcode());
675f3db51deSAlex Lorenz   if (I < E)
676f3db51deSAlex Lorenz     OS << ' ';
677f3db51deSAlex Lorenz 
678f3db51deSAlex Lorenz   bool NeedComma = false;
679f3db51deSAlex Lorenz   for (; I < E; ++I) {
680f3db51deSAlex Lorenz     if (NeedComma)
681f3db51deSAlex Lorenz       OS << ", ";
682a42ed3e3SBjorn Pettersson     print(MI, I, TRI, ShouldPrintRegisterTies,
683a8a83d15SFrancis Visoiu Mistrih           MI.getTypeToPrint(I, PrintedTypes, MRI));
684f3db51deSAlex Lorenz     NeedComma = true;
685f3db51deSAlex Lorenz   }
68646d760d1SAlex Lorenz 
68746d760d1SAlex Lorenz   if (MI.getDebugLoc()) {
68846d760d1SAlex Lorenz     if (NeedComma)
68946d760d1SAlex Lorenz       OS << ',';
69046d760d1SAlex Lorenz     OS << " debug-location ";
69146d760d1SAlex Lorenz     MI.getDebugLoc()->printAsOperand(OS, MST);
69246d760d1SAlex Lorenz   }
6934af7e610SAlex Lorenz 
6944af7e610SAlex Lorenz   if (!MI.memoperands_empty()) {
6954af7e610SAlex Lorenz     OS << " :: ";
696f1caa283SMatthias Braun     const LLVMContext &Context = MF->getFunction().getContext();
6974af7e610SAlex Lorenz     bool NeedComma = false;
6984af7e610SAlex Lorenz     for (const auto *Op : MI.memoperands()) {
6994af7e610SAlex Lorenz       if (NeedComma)
7004af7e610SAlex Lorenz         OS << ", ";
7016748abe2SGeoff Berry       print(Context, *TII, *Op);
7024af7e610SAlex Lorenz       NeedComma = true;
7034af7e610SAlex Lorenz     }
7044af7e610SAlex Lorenz   }
705f3db51deSAlex Lorenz }
706f3db51deSAlex Lorenz 
70755dc6f81SAlex Lorenz static void printIRSlotNumber(raw_ostream &OS, int Slot) {
70855dc6f81SAlex Lorenz   if (Slot == -1)
70955dc6f81SAlex Lorenz     OS << "<badref>";
71055dc6f81SAlex Lorenz   else
71155dc6f81SAlex Lorenz     OS << Slot;
71255dc6f81SAlex Lorenz }
71355dc6f81SAlex Lorenz 
714deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
715deb53490SAlex Lorenz   OS << "%ir-block.";
716deb53490SAlex Lorenz   if (BB.hasName()) {
717deb53490SAlex Lorenz     printLLVMNameWithoutPrefix(OS, BB.getName());
718deb53490SAlex Lorenz     return;
719deb53490SAlex Lorenz   }
720cba8c5feSAlex Lorenz   const Function *F = BB.getParent();
721cba8c5feSAlex Lorenz   int Slot;
722cba8c5feSAlex Lorenz   if (F == MST.getCurrentFunction()) {
723cba8c5feSAlex Lorenz     Slot = MST.getLocalSlot(&BB);
724cba8c5feSAlex Lorenz   } else {
725cba8c5feSAlex Lorenz     ModuleSlotTracker CustomMST(F->getParent(),
726cba8c5feSAlex Lorenz                                 /*ShouldInitializeAllMetadata=*/false);
727cba8c5feSAlex Lorenz     CustomMST.incorporateFunction(*F);
728cba8c5feSAlex Lorenz     Slot = CustomMST.getLocalSlot(&BB);
729cba8c5feSAlex Lorenz   }
73055dc6f81SAlex Lorenz   printIRSlotNumber(OS, Slot);
731deb53490SAlex Lorenz }
732deb53490SAlex Lorenz 
7334af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) {
73436efd388SAlex Lorenz   if (isa<GlobalValue>(V)) {
73536efd388SAlex Lorenz     V.printAsOperand(OS, /*PrintType=*/false, MST);
73636efd388SAlex Lorenz     return;
73736efd388SAlex Lorenz   }
738c1136ef3SAlex Lorenz   if (isa<Constant>(V)) {
739c1136ef3SAlex Lorenz     // Machine memory operands can load/store to/from constant value pointers.
740c1136ef3SAlex Lorenz     OS << '`';
741c1136ef3SAlex Lorenz     V.printAsOperand(OS, /*PrintType=*/true, MST);
742c1136ef3SAlex Lorenz     OS << '`';
743c1136ef3SAlex Lorenz     return;
744c1136ef3SAlex Lorenz   }
7454af7e610SAlex Lorenz   OS << "%ir.";
7464af7e610SAlex Lorenz   if (V.hasName()) {
7474af7e610SAlex Lorenz     printLLVMNameWithoutPrefix(OS, V.getName());
7484af7e610SAlex Lorenz     return;
7494af7e610SAlex Lorenz   }
750dd13be0bSAlex Lorenz   printIRSlotNumber(OS, MST.getLocalSlot(&V));
7514af7e610SAlex Lorenz }
7524af7e610SAlex Lorenz 
7537feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) {
7547feaf7c6SAlex Lorenz   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
7557feaf7c6SAlex Lorenz   assert(ObjectInfo != StackObjectOperandMapping.end() &&
7567feaf7c6SAlex Lorenz          "Invalid frame index");
7577feaf7c6SAlex Lorenz   const FrameIndexOperand &Operand = ObjectInfo->second;
7580b5bdceaSFrancis Visoiu Mistrih   MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed,
7590b5bdceaSFrancis Visoiu Mistrih                                             Operand.Name);
7607feaf7c6SAlex Lorenz }
7617feaf7c6SAlex Lorenz 
762a42ed3e3SBjorn Pettersson void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
763a42ed3e3SBjorn Pettersson                       const TargetRegisterInfo *TRI,
764a42ed3e3SBjorn Pettersson                       bool ShouldPrintRegisterTies, LLT TypeToPrint,
765a8a83d15SFrancis Visoiu Mistrih                       bool PrintDef) {
766a42ed3e3SBjorn Pettersson   const MachineOperand &Op = MI.getOperand(OpIdx);
767f3db51deSAlex Lorenz   switch (Op.getType()) {
768440f69c9SFrancis Visoiu Mistrih   case MachineOperand::MO_Immediate:
769440f69c9SFrancis Visoiu Mistrih     if (MI.isOperandSubregIdx(OpIdx)) {
7705df3bbf3SFrancis Visoiu Mistrih       MachineOperand::printTargetFlags(OS, Op);
771440f69c9SFrancis Visoiu Mistrih       MachineOperand::printSubregIdx(OS, Op.getImm(), TRI);
772440f69c9SFrancis Visoiu Mistrih       break;
773440f69c9SFrancis Visoiu Mistrih     }
774440f69c9SFrancis Visoiu Mistrih     LLVM_FALLTHROUGH;
7756c4ca713SFrancis Visoiu Mistrih   case MachineOperand::MO_Register:
776f4bd2955SFrancis Visoiu Mistrih   case MachineOperand::MO_CImmediate:
7773b265c8fSFrancis Visoiu Mistrih   case MachineOperand::MO_FPImmediate:
77826ae8a65SFrancis Visoiu Mistrih   case MachineOperand::MO_MachineBasicBlock:
779b3a0d513SFrancis Visoiu Mistrih   case MachineOperand::MO_ConstantPoolIndex:
780b41dbbe3SFrancis Visoiu Mistrih   case MachineOperand::MO_TargetIndex:
781e76c5fcdSFrancis Visoiu Mistrih   case MachineOperand::MO_JumpTableIndex:
7825df3bbf3SFrancis Visoiu Mistrih   case MachineOperand::MO_ExternalSymbol:
783bdaf8bfaSFrancis Visoiu Mistrih   case MachineOperand::MO_GlobalAddress:
7842db59382SFrancis Visoiu Mistrih   case MachineOperand::MO_RegisterLiveOut:
7853c99371cSFrancis Visoiu Mistrih   case MachineOperand::MO_Metadata:
786874ae6faSFrancis Visoiu Mistrih   case MachineOperand::MO_MCSymbol:
787*bbd610aeSFrancis Visoiu Mistrih   case MachineOperand::MO_CFIIndex:
788*bbd610aeSFrancis Visoiu Mistrih   case MachineOperand::MO_IntrinsicID: {
789a8a83d15SFrancis Visoiu Mistrih     unsigned TiedOperandIdx = 0;
790440f69c9SFrancis Visoiu Mistrih     if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
791a8a83d15SFrancis Visoiu Mistrih       TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
792a8a83d15SFrancis Visoiu Mistrih     const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo();
793a8a83d15SFrancis Visoiu Mistrih     Op.print(OS, MST, TypeToPrint, PrintDef, ShouldPrintRegisterTies,
794a8a83d15SFrancis Visoiu Mistrih              TiedOperandIdx, TRI, TII);
795f3db51deSAlex Lorenz     break;
7966c452834SJustin Bogner   }
7977feaf7c6SAlex Lorenz   case MachineOperand::MO_FrameIndex:
7987feaf7c6SAlex Lorenz     printStackObjectReference(Op.getIndex());
7997feaf7c6SAlex Lorenz     break;
800deb53490SAlex Lorenz   case MachineOperand::MO_BlockAddress:
801deb53490SAlex Lorenz     OS << "blockaddress(";
802deb53490SAlex Lorenz     Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
803deb53490SAlex Lorenz                                                         MST);
804deb53490SAlex Lorenz     OS << ", ";
805deb53490SAlex Lorenz     printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
806deb53490SAlex Lorenz     OS << ')';
80781226602SFrancis Visoiu Mistrih     MachineOperand::printOperandOffset(Op.getOffset());
808deb53490SAlex Lorenz     break;
8098f6f4285SAlex Lorenz   case MachineOperand::MO_RegisterMask: {
8108f6f4285SAlex Lorenz     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
8118f6f4285SAlex Lorenz     if (RegMaskInfo != RegisterMaskIds.end())
8128f6f4285SAlex Lorenz       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
8138f6f4285SAlex Lorenz     else
8140ef61ec3SOren Ben Simhon       printCustomRegMask(Op.getRegMask(), OS, TRI);
8158f6f4285SAlex Lorenz     break;
8168f6f4285SAlex Lorenz   }
817de3aea04STim Northover   case MachineOperand::MO_Predicate: {
818de3aea04STim Northover     auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate());
819de3aea04STim Northover     OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
820de3aea04STim Northover        << CmpInst::getPredicateName(Pred) << ')';
821de3aea04STim Northover     break;
822de3aea04STim Northover   }
823f3db51deSAlex Lorenz   }
8244f093bf1SAlex Lorenz }
8254f093bf1SAlex Lorenz 
8266748abe2SGeoff Berry static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
8276748abe2SGeoff Berry                                         unsigned TMMOFlag) {
8286748abe2SGeoff Berry   auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
8296748abe2SGeoff Berry   for (const auto &I : Flags) {
8306748abe2SGeoff Berry     if (I.first == TMMOFlag) {
8316748abe2SGeoff Berry       return I.second;
8326748abe2SGeoff Berry     }
8336748abe2SGeoff Berry   }
8346748abe2SGeoff Berry   return nullptr;
8356748abe2SGeoff Berry }
8366748abe2SGeoff Berry 
8376748abe2SGeoff Berry void MIPrinter::print(const LLVMContext &Context, const TargetInstrInfo &TII,
8386748abe2SGeoff Berry                       const MachineMemOperand &Op) {
8394af7e610SAlex Lorenz   OS << '(';
840a518b796SAlex Lorenz   if (Op.isVolatile())
841a518b796SAlex Lorenz     OS << "volatile ";
84210fd0385SAlex Lorenz   if (Op.isNonTemporal())
84310fd0385SAlex Lorenz     OS << "non-temporal ";
844adbf09e8SJustin Lebar   if (Op.isDereferenceable())
845adbf09e8SJustin Lebar     OS << "dereferenceable ";
846dc8de2a6SAlex Lorenz   if (Op.isInvariant())
847dc8de2a6SAlex Lorenz     OS << "invariant ";
8486748abe2SGeoff Berry   if (Op.getFlags() & MachineMemOperand::MOTargetFlag1)
8496748abe2SGeoff Berry     OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag1)
8506748abe2SGeoff Berry        << "\" ";
8516748abe2SGeoff Berry   if (Op.getFlags() & MachineMemOperand::MOTargetFlag2)
8526748abe2SGeoff Berry     OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag2)
8536748abe2SGeoff Berry        << "\" ";
8546748abe2SGeoff Berry   if (Op.getFlags() & MachineMemOperand::MOTargetFlag3)
8556748abe2SGeoff Berry     OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag3)
8566748abe2SGeoff Berry        << "\" ";
85717d277b7SDaniel Sanders 
85817d277b7SDaniel Sanders   assert((Op.isLoad() || Op.isStore()) && "machine memory operand must be a load or store (or both)");
8594af7e610SAlex Lorenz   if (Op.isLoad())
8604af7e610SAlex Lorenz     OS << "load ";
86117d277b7SDaniel Sanders   if (Op.isStore())
8624af7e610SAlex Lorenz     OS << "store ";
863b73e3090STim Northover 
864bb80d3e1SKonstantin Zhuravlyov   printSyncScope(Context, Op.getSyncScopeID());
865b73e3090STim Northover 
866b73e3090STim Northover   if (Op.getOrdering() != AtomicOrdering::NotAtomic)
867b73e3090STim Northover     OS << toIRString(Op.getOrdering()) << ' ';
868b73e3090STim Northover   if (Op.getFailureOrdering() != AtomicOrdering::NotAtomic)
869b73e3090STim Northover     OS << toIRString(Op.getFailureOrdering()) << ' ';
870b73e3090STim Northover 
871c25c9ccbSMatthias Braun   OS << Op.getSize();
87291097a3fSAlex Lorenz   if (const Value *Val = Op.getValue()) {
87317d277b7SDaniel Sanders     OS << ((Op.isLoad() && Op.isStore()) ? " on "
87417d277b7SDaniel Sanders                                          : Op.isLoad() ? " from " : " into ");
8754af7e610SAlex Lorenz     printIRValueReference(*Val);
876c25c9ccbSMatthias Braun   } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) {
87717d277b7SDaniel Sanders     OS << ((Op.isLoad() && Op.isStore()) ? " on "
87817d277b7SDaniel Sanders                                          : Op.isLoad() ? " from " : " into ");
87991097a3fSAlex Lorenz     assert(PVal && "Expected a pseudo source value");
88091097a3fSAlex Lorenz     switch (PVal->kind()) {
88146e9558aSAlex Lorenz     case PseudoSourceValue::Stack:
88246e9558aSAlex Lorenz       OS << "stack";
88346e9558aSAlex Lorenz       break;
884d858f874SAlex Lorenz     case PseudoSourceValue::GOT:
885d858f874SAlex Lorenz       OS << "got";
886d858f874SAlex Lorenz       break;
8874be56e93SAlex Lorenz     case PseudoSourceValue::JumpTable:
8884be56e93SAlex Lorenz       OS << "jump-table";
8894be56e93SAlex Lorenz       break;
89091097a3fSAlex Lorenz     case PseudoSourceValue::ConstantPool:
89191097a3fSAlex Lorenz       OS << "constant-pool";
89291097a3fSAlex Lorenz       break;
8930cc671bfSAlex Lorenz     case PseudoSourceValue::FixedStack:
8940cc671bfSAlex Lorenz       printStackObjectReference(
8950cc671bfSAlex Lorenz           cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex());
8960cc671bfSAlex Lorenz       break;
89750b826fbSAlex Lorenz     case PseudoSourceValue::GlobalValueCallEntry:
8980d009645SAlex Lorenz       OS << "call-entry ";
89950b826fbSAlex Lorenz       cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
90050b826fbSAlex Lorenz           OS, /*PrintType=*/false, MST);
90150b826fbSAlex Lorenz       break;
902c3ba7508SAlex Lorenz     case PseudoSourceValue::ExternalSymbolCallEntry:
9030d009645SAlex Lorenz       OS << "call-entry $";
904c3ba7508SAlex Lorenz       printLLVMNameWithoutPrefix(
905c3ba7508SAlex Lorenz           OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
90691097a3fSAlex Lorenz       break;
9077761abb6STom Stellard     case PseudoSourceValue::TargetCustom:
9087761abb6STom Stellard       llvm_unreachable("TargetCustom pseudo source values are not supported");
9097761abb6STom Stellard       break;
91091097a3fSAlex Lorenz     }
91191097a3fSAlex Lorenz   }
91281226602SFrancis Visoiu Mistrih   MachineOperand::printOperandOffset(OS, Op.getOffset());
91361420f79SAlex Lorenz   if (Op.getBaseAlignment() != Op.getSize())
91461420f79SAlex Lorenz     OS << ", align " << Op.getBaseAlignment();
915a617c916SAlex Lorenz   auto AAInfo = Op.getAAInfo();
916a617c916SAlex Lorenz   if (AAInfo.TBAA) {
917a617c916SAlex Lorenz     OS << ", !tbaa ";
918a617c916SAlex Lorenz     AAInfo.TBAA->printAsOperand(OS, MST);
919a617c916SAlex Lorenz   }
920a16f624dSAlex Lorenz   if (AAInfo.Scope) {
921a16f624dSAlex Lorenz     OS << ", !alias.scope ";
922a16f624dSAlex Lorenz     AAInfo.Scope->printAsOperand(OS, MST);
923a16f624dSAlex Lorenz   }
92403e940d1SAlex Lorenz   if (AAInfo.NoAlias) {
92503e940d1SAlex Lorenz     OS << ", !noalias ";
92603e940d1SAlex Lorenz     AAInfo.NoAlias->printAsOperand(OS, MST);
92703e940d1SAlex Lorenz   }
928eb625686SAlex Lorenz   if (Op.getRanges()) {
929eb625686SAlex Lorenz     OS << ", !range ";
930eb625686SAlex Lorenz     Op.getRanges()->printAsOperand(OS, MST);
931eb625686SAlex Lorenz   }
9324af7e610SAlex Lorenz   OS << ')';
9334af7e610SAlex Lorenz }
9344af7e610SAlex Lorenz 
935bb80d3e1SKonstantin Zhuravlyov void MIPrinter::printSyncScope(const LLVMContext &Context, SyncScope::ID SSID) {
936bb80d3e1SKonstantin Zhuravlyov   switch (SSID) {
937bb80d3e1SKonstantin Zhuravlyov   case SyncScope::System: {
938bb80d3e1SKonstantin Zhuravlyov     break;
939bb80d3e1SKonstantin Zhuravlyov   }
940bb80d3e1SKonstantin Zhuravlyov   default: {
941bb80d3e1SKonstantin Zhuravlyov     if (SSNs.empty())
942bb80d3e1SKonstantin Zhuravlyov       Context.getSyncScopeNames(SSNs);
943bb80d3e1SKonstantin Zhuravlyov 
944bb80d3e1SKonstantin Zhuravlyov     OS << "syncscope(\"";
945bb80d3e1SKonstantin Zhuravlyov     PrintEscapedString(SSNs[SSID], OS);
946bb80d3e1SKonstantin Zhuravlyov     OS << "\") ";
947bb80d3e1SKonstantin Zhuravlyov     break;
948bb80d3e1SKonstantin Zhuravlyov   }
949bb80d3e1SKonstantin Zhuravlyov   }
950bb80d3e1SKonstantin Zhuravlyov }
951bb80d3e1SKonstantin Zhuravlyov 
952345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) {
953345c1449SAlex Lorenz   yaml::Output Out(OS);
954345c1449SAlex Lorenz   Out << const_cast<Module &>(M);
955345c1449SAlex Lorenz }
956345c1449SAlex Lorenz 
957345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
958345c1449SAlex Lorenz   MIRPrinter Printer(OS);
959345c1449SAlex Lorenz   Printer.print(MF);
960345c1449SAlex Lorenz }
961