1345c1449SAlex Lorenz //===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
2345c1449SAlex Lorenz //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6345c1449SAlex Lorenz //
7345c1449SAlex Lorenz //===----------------------------------------------------------------------===//
8345c1449SAlex Lorenz //
9345c1449SAlex Lorenz // This file implements the class that prints out the LLVM IR and machine
10345c1449SAlex Lorenz // functions using the MIR serialization format.
11345c1449SAlex Lorenz //
12345c1449SAlex Lorenz //===----------------------------------------------------------------------===//
13345c1449SAlex Lorenz 
143f833edcSDavid Blaikie #include "llvm/CodeGen/MIRPrinter.h"
15fb69e66cSEugene Zelenko #include "llvm/ADT/DenseMap.h"
163f833edcSDavid Blaikie #include "llvm/ADT/STLExtras.h"
17d28d3cc0STim Northover #include "llvm/ADT/SmallBitVector.h"
18fb69e66cSEugene Zelenko #include "llvm/ADT/SmallPtrSet.h"
19fb69e66cSEugene Zelenko #include "llvm/ADT/SmallVector.h"
20fb69e66cSEugene Zelenko #include "llvm/ADT/StringRef.h"
213f833edcSDavid Blaikie #include "llvm/CodeGen/MIRYamlMapping.h"
22fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h"
23ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h"
2460541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h"
25fab1cfe6SQuentin Colombet #include "llvm/CodeGen/MachineFunction.h"
26fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineInstr.h"
27fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineJumpTableInfo.h"
284af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h"
29b9c05affSMichael Liao #include "llvm/CodeGen/MachineModuleSlotTracker.h"
30fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineOperand.h"
3154565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h"
32b9c05affSMichael Liao #include "llvm/CodeGen/TargetFrameLowering.h"
333f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
34b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
35b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
36989f1c72Sserge-sans-paille #include "llvm/IR/DebugInfoMetadata.h"
37fb69e66cSEugene Zelenko #include "llvm/IR/DebugLoc.h"
38fb69e66cSEugene Zelenko #include "llvm/IR/Function.h"
393f833edcSDavid Blaikie #include "llvm/IR/IRPrintingPasses.h"
40fab1cfe6SQuentin Colombet #include "llvm/IR/Instructions.h"
41345c1449SAlex Lorenz #include "llvm/IR/Module.h"
42900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h"
43fb69e66cSEugene Zelenko #include "llvm/IR/Value.h"
44fb69e66cSEugene Zelenko #include "llvm/MC/LaneBitmask.h"
45fb69e66cSEugene Zelenko #include "llvm/Support/BranchProbability.h"
46fb69e66cSEugene Zelenko #include "llvm/Support/Casting.h"
47fb69e66cSEugene Zelenko #include "llvm/Support/CommandLine.h"
48fb69e66cSEugene Zelenko #include "llvm/Support/ErrorHandling.h"
49b51774acSGeoff Berry #include "llvm/Support/Format.h"
50fb69e66cSEugene Zelenko #include "llvm/Support/LowLevelTypeImpl.h"
51fb69e66cSEugene Zelenko #include "llvm/Support/YAMLTraits.h"
523f833edcSDavid Blaikie #include "llvm/Support/raw_ostream.h"
53fb69e66cSEugene Zelenko #include "llvm/Target/TargetMachine.h"
54fb69e66cSEugene Zelenko #include <algorithm>
55fb69e66cSEugene Zelenko #include <cassert>
56fb69e66cSEugene Zelenko #include <cinttypes>
57fb69e66cSEugene Zelenko #include <cstdint>
58fb69e66cSEugene Zelenko #include <iterator>
59fb69e66cSEugene Zelenko #include <string>
60fb69e66cSEugene Zelenko #include <utility>
61fb69e66cSEugene Zelenko #include <vector>
62345c1449SAlex Lorenz 
63345c1449SAlex Lorenz using namespace llvm;
64345c1449SAlex Lorenz 
658065f0b9SZachary Turner static cl::opt<bool> SimplifyMIR(
668065f0b9SZachary Turner     "simplify-mir", cl::Hidden,
678940114fSMatthias Braun     cl::desc("Leave out unnecessary information when printing MIR"));
688940114fSMatthias Braun 
69f27cea72SDaniel Sanders static cl::opt<bool> PrintLocations("mir-debug-loc", cl::Hidden, cl::init(true),
70f27cea72SDaniel Sanders                                     cl::desc("Print MIR debug-locations"));
71f27cea72SDaniel Sanders 
72345c1449SAlex Lorenz namespace {
73345c1449SAlex Lorenz 
747feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references.
757feaf7c6SAlex Lorenz struct FrameIndexOperand {
767feaf7c6SAlex Lorenz   std::string Name;
777feaf7c6SAlex Lorenz   unsigned ID;
787feaf7c6SAlex Lorenz   bool IsFixed;
797feaf7c6SAlex Lorenz 
FrameIndexOperand__anonc22a66f00111::FrameIndexOperand807feaf7c6SAlex Lorenz   FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
817feaf7c6SAlex Lorenz       : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
827feaf7c6SAlex Lorenz 
837feaf7c6SAlex Lorenz   /// Return an ordinary stack object reference.
create__anonc22a66f00111::FrameIndexOperand847feaf7c6SAlex Lorenz   static FrameIndexOperand create(StringRef Name, unsigned ID) {
857feaf7c6SAlex Lorenz     return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
867feaf7c6SAlex Lorenz   }
877feaf7c6SAlex Lorenz 
887feaf7c6SAlex Lorenz   /// Return a fixed stack object reference.
createFixed__anonc22a66f00111::FrameIndexOperand897feaf7c6SAlex Lorenz   static FrameIndexOperand createFixed(unsigned ID) {
907feaf7c6SAlex Lorenz     return FrameIndexOperand("", ID, /*IsFixed=*/true);
917feaf7c6SAlex Lorenz   }
927feaf7c6SAlex Lorenz };
937feaf7c6SAlex Lorenz 
94618b283cSAlex Lorenz } // end anonymous namespace
95618b283cSAlex Lorenz 
96618b283cSAlex Lorenz namespace llvm {
97618b283cSAlex Lorenz 
98345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization
99345c1449SAlex Lorenz /// format.
100345c1449SAlex Lorenz class MIRPrinter {
101345c1449SAlex Lorenz   raw_ostream &OS;
1028f6f4285SAlex Lorenz   DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
1037feaf7c6SAlex Lorenz   /// Maps from stack object indices to operand indices which will be used when
1047feaf7c6SAlex Lorenz   /// printing frame index machine operands.
1057feaf7c6SAlex Lorenz   DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
106345c1449SAlex Lorenz 
107345c1449SAlex Lorenz public:
MIRPrinter(raw_ostream & OS)108345c1449SAlex Lorenz   MIRPrinter(raw_ostream &OS) : OS(OS) {}
109345c1449SAlex Lorenz 
110345c1449SAlex Lorenz   void print(const MachineFunction &MF);
1114f093bf1SAlex Lorenz 
11228148ba8SAlex Lorenz   void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
11328148ba8SAlex Lorenz                const TargetRegisterInfo *TRI);
114a6f9a37dSAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
115a6f9a37dSAlex Lorenz                const MachineFrameInfo &MFI);
116ab980499SAlex Lorenz   void convert(yaml::MachineFunction &MF,
117ab980499SAlex Lorenz                const MachineConstantPool &ConstantPool);
1186799e9b3SAlex Lorenz   void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
1196799e9b3SAlex Lorenz                const MachineJumpTableInfo &JTI);
120ef331effSMatthias Braun   void convertStackObjects(yaml::MachineFunction &YMF,
121ef331effSMatthias Braun                            const MachineFunction &MF, ModuleSlotTracker &MST);
122a7cde103SDjordje Todorovic   void convertCallSiteObjects(yaml::MachineFunction &YMF,
123a7cde103SDjordje Todorovic                               const MachineFunction &MF,
124a7cde103SDjordje Todorovic                               ModuleSlotTracker &MST);
125b9c05affSMichael Liao   void convertMachineMetadataNodes(yaml::MachineFunction &YMF,
126b9c05affSMichael Liao                                    const MachineFunction &MF,
127b9c05affSMichael Liao                                    MachineModuleSlotTracker &MST);
1288f6f4285SAlex Lorenz 
1298f6f4285SAlex Lorenz private:
1308f6f4285SAlex Lorenz   void initRegisterMaskIds(const MachineFunction &MF);
131345c1449SAlex Lorenz };
132345c1449SAlex Lorenz 
1338e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization
1348e0a1b48SAlex Lorenz /// format.
1358e0a1b48SAlex Lorenz class MIPrinter {
1368e0a1b48SAlex Lorenz   raw_ostream &OS;
137900b5cb2SAlex Lorenz   ModuleSlotTracker &MST;
1388f6f4285SAlex Lorenz   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
1397feaf7c6SAlex Lorenz   const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
140bb80d3e1SKonstantin Zhuravlyov   /// Synchronization scope names registered with LLVMContext.
141bb80d3e1SKonstantin Zhuravlyov   SmallVector<StringRef, 8> SSNs;
1428e0a1b48SAlex Lorenz 
1438940114fSMatthias Braun   bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const;
1448940114fSMatthias Braun   bool canPredictSuccessors(const MachineBasicBlock &MBB) const;
1458940114fSMatthias Braun 
1468e0a1b48SAlex Lorenz public:
MIPrinter(raw_ostream & OS,ModuleSlotTracker & MST,const DenseMap<const uint32_t *,unsigned> & RegisterMaskIds,const DenseMap<int,FrameIndexOperand> & StackObjectOperandMapping)147900b5cb2SAlex Lorenz   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
1487feaf7c6SAlex Lorenz             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
1497feaf7c6SAlex Lorenz             const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
1507feaf7c6SAlex Lorenz       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
1517feaf7c6SAlex Lorenz         StackObjectOperandMapping(StackObjectOperandMapping) {}
1528e0a1b48SAlex Lorenz 
1535022f6bbSAlex Lorenz   void print(const MachineBasicBlock &MBB);
1545022f6bbSAlex Lorenz 
1558e0a1b48SAlex Lorenz   void print(const MachineInstr &MI);
1567feaf7c6SAlex Lorenz   void printStackObjectReference(int FrameIndex);
157a42ed3e3SBjorn Pettersson   void print(const MachineInstr &MI, unsigned OpIdx,
1587efabe5cSSjoerd Meijer              const TargetRegisterInfo *TRI, const TargetInstrInfo *TII,
1597efabe5cSSjoerd Meijer              bool ShouldPrintRegisterTies, LLT TypeToPrint,
1607efabe5cSSjoerd Meijer              bool PrintDef = true);
1618e0a1b48SAlex Lorenz };
1628e0a1b48SAlex Lorenz 
1635022f6bbSAlex Lorenz } // end namespace llvm
164345c1449SAlex Lorenz 
165345c1449SAlex Lorenz namespace llvm {
166345c1449SAlex Lorenz namespace yaml {
167345c1449SAlex Lorenz 
168345c1449SAlex Lorenz /// This struct serializes the LLVM IR module.
169345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> {
outputllvm::yaml::BlockScalarTraits170345c1449SAlex Lorenz   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
171345c1449SAlex Lorenz     Mod.print(OS, nullptr);
172345c1449SAlex Lorenz   }
173fb69e66cSEugene Zelenko 
inputllvm::yaml::BlockScalarTraits174345c1449SAlex Lorenz   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
175345c1449SAlex Lorenz     llvm_unreachable("LLVM Module is supposed to be parsed separately");
176345c1449SAlex Lorenz     return "";
177345c1449SAlex Lorenz   }
178345c1449SAlex Lorenz };
179345c1449SAlex Lorenz 
180345c1449SAlex Lorenz } // end namespace yaml
181345c1449SAlex Lorenz } // end namespace llvm
182345c1449SAlex Lorenz 
printRegMIR(unsigned Reg,yaml::StringValue & Dest,const TargetRegisterInfo * TRI)1839d419d3bSFrancis Visoiu Mistrih static void printRegMIR(unsigned Reg, yaml::StringValue &Dest,
184ab4cbcfdSAlex Lorenz                         const TargetRegisterInfo *TRI) {
185ab4cbcfdSAlex Lorenz   raw_string_ostream OS(Dest.Value);
186c71cced0SFrancis Visoiu Mistrih   OS << printReg(Reg, TRI);
187ab4cbcfdSAlex Lorenz }
188ab4cbcfdSAlex Lorenz 
print(const MachineFunction & MF)189345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) {
1908f6f4285SAlex Lorenz   initRegisterMaskIds(MF);
1918f6f4285SAlex Lorenz 
192345c1449SAlex Lorenz   yaml::MachineFunction YamlMF;
193345c1449SAlex Lorenz   YamlMF.Name = MF.getName();
194bf573beaSGuillaume Chatelet   YamlMF.Alignment = MF.getAlignment();
1955b5f9753SAlex Lorenz   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
196625d08eeSSanjin Sijaric   YamlMF.HasWinCFI = MF.hasWinCFI();
197ad154c83SDerek Schuff 
198b8033de0SMatt Arsenault   YamlMF.CallsEHReturn = MF.callsEHReturn();
199b8033de0SMatt Arsenault   YamlMF.CallsUnwindInit = MF.callsUnwindInit();
200b8033de0SMatt Arsenault   YamlMF.HasEHCatchret = MF.hasEHCatchret();
201b8033de0SMatt Arsenault   YamlMF.HasEHScopes = MF.hasEHScopes();
202b8033de0SMatt Arsenault   YamlMF.HasEHFunclets = MF.hasEHFunclets();
203b8033de0SMatt Arsenault 
2040d7b0cb8SAhmed Bougacha   YamlMF.Legalized = MF.getProperties().hasProperty(
2050d7b0cb8SAhmed Bougacha       MachineFunctionProperties::Property::Legalized);
20624712655SAhmed Bougacha   YamlMF.RegBankSelected = MF.getProperties().hasProperty(
20724712655SAhmed Bougacha       MachineFunctionProperties::Property::RegBankSelected);
208b109d518SAhmed Bougacha   YamlMF.Selected = MF.getProperties().hasProperty(
209b109d518SAhmed Bougacha       MachineFunctionProperties::Property::Selected);
2103054eceaSRoman Tereshin   YamlMF.FailedISel = MF.getProperties().hasProperty(
2113054eceaSRoman Tereshin       MachineFunctionProperties::Property::FailedISel);
21236deb9a6SJay Foad   YamlMF.FailsVerification = MF.getProperties().hasProperty(
21336deb9a6SJay Foad       MachineFunctionProperties::Property::FailsVerification);
214f108c7f5SJack Andersen   YamlMF.TracksDebugUserValues = MF.getProperties().hasProperty(
215f108c7f5SJack Andersen       MachineFunctionProperties::Property::TracksDebugUserValues);
2160d7b0cb8SAhmed Bougacha 
21728148ba8SAlex Lorenz   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
218b9c05affSMichael Liao   MachineModuleSlotTracker MST(&MF);
219f1caa283SMatthias Braun   MST.incorporateFunction(MF.getFunction());
220941a705bSMatthias Braun   convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
221ef331effSMatthias Braun   convertStackObjects(YamlMF, MF, MST);
222a7cde103SDjordje Todorovic   convertCallSiteObjects(YamlMF, MF, MST);
22347c3fe2aSJeremy Morse   for (const auto &Sub : MF.DebugValueSubstitutions) {
224f551fb96SJeremy Morse     const auto &SubSrc = Sub.Src;
225f551fb96SJeremy Morse     const auto &SubDest = Sub.Dest;
22647c3fe2aSJeremy Morse     YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second,
227f551fb96SJeremy Morse                                               SubDest.first,
228f551fb96SJeremy Morse                                               SubDest.second,
229f551fb96SJeremy Morse                                               Sub.Subreg});
23047c3fe2aSJeremy Morse   }
231ab980499SAlex Lorenz   if (const auto *ConstantPool = MF.getConstantPool())
232ab980499SAlex Lorenz     convert(YamlMF, *ConstantPool);
2336799e9b3SAlex Lorenz   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
2346799e9b3SAlex Lorenz     convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
235bc6d07caSMatt Arsenault 
236bc6d07caSMatt Arsenault   const TargetMachine &TM = MF.getTarget();
237bc6d07caSMatt Arsenault   YamlMF.MachineFuncInfo =
238bc6d07caSMatt Arsenault       std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF));
239bc6d07caSMatt Arsenault 
2405022f6bbSAlex Lorenz   raw_string_ostream StrOS(YamlMF.Body.Value.Value);
2415022f6bbSAlex Lorenz   bool IsNewlineNeeded = false;
2424f093bf1SAlex Lorenz   for (const auto &MBB : MF) {
2435022f6bbSAlex Lorenz     if (IsNewlineNeeded)
2445022f6bbSAlex Lorenz       StrOS << "\n";
2455022f6bbSAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
2465022f6bbSAlex Lorenz         .print(MBB);
2475022f6bbSAlex Lorenz     IsNewlineNeeded = true;
2484f093bf1SAlex Lorenz   }
2495022f6bbSAlex Lorenz   StrOS.flush();
250b9c05affSMichael Liao   // Convert machine metadata collected during the print of the machine
251b9c05affSMichael Liao   // function.
252b9c05affSMichael Liao   convertMachineMetadataNodes(YamlMF, MF, MST);
253b9c05affSMichael Liao 
254345c1449SAlex Lorenz   yaml::Output Out(OS);
25556d87ef5SVivek Pandya   if (!SimplifyMIR)
25656d87ef5SVivek Pandya       Out.setWriteDefaultValues(true);
257345c1449SAlex Lorenz   Out << YamlMF;
258345c1449SAlex Lorenz }
259345c1449SAlex Lorenz 
printCustomRegMask(const uint32_t * RegMask,raw_ostream & OS,const TargetRegisterInfo * TRI)2600ef61ec3SOren Ben Simhon static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,
2610ef61ec3SOren Ben Simhon                                const TargetRegisterInfo *TRI) {
2620ef61ec3SOren Ben Simhon   assert(RegMask && "Can't print an empty register mask");
2630ef61ec3SOren Ben Simhon   OS << StringRef("CustomRegMask(");
2640ef61ec3SOren Ben Simhon 
2650ef61ec3SOren Ben Simhon   bool IsRegInRegMaskFound = false;
2660ef61ec3SOren Ben Simhon   for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {
2670ef61ec3SOren Ben Simhon     // Check whether the register is asserted in regmask.
2680ef61ec3SOren Ben Simhon     if (RegMask[I / 32] & (1u << (I % 32))) {
2690ef61ec3SOren Ben Simhon       if (IsRegInRegMaskFound)
2700ef61ec3SOren Ben Simhon         OS << ',';
271c71cced0SFrancis Visoiu Mistrih       OS << printReg(I, TRI);
2720ef61ec3SOren Ben Simhon       IsRegInRegMaskFound = true;
2730ef61ec3SOren Ben Simhon     }
2740ef61ec3SOren Ben Simhon   }
2750ef61ec3SOren Ben Simhon 
2760ef61ec3SOren Ben Simhon   OS << ')';
2770ef61ec3SOren Ben Simhon }
2780ef61ec3SOren Ben Simhon 
printRegClassOrBank(unsigned Reg,yaml::StringValue & Dest,const MachineRegisterInfo & RegInfo,const TargetRegisterInfo * TRI)2796c452834SJustin Bogner static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest,
2806c452834SJustin Bogner                                 const MachineRegisterInfo &RegInfo,
2816c452834SJustin Bogner                                 const TargetRegisterInfo *TRI) {
2826c452834SJustin Bogner   raw_string_ostream OS(Dest.Value);
283a8a83d15SFrancis Visoiu Mistrih   OS << printRegClassOrBank(Reg, RegInfo, TRI);
2846c452834SJustin Bogner }
2856c452834SJustin Bogner 
28657fcd345SFrancis Visoiu Mistrih template <typename T>
28757fcd345SFrancis Visoiu Mistrih static void
printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo & DebugVar,T & Object,ModuleSlotTracker & MST)28857fcd345SFrancis Visoiu Mistrih printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo &DebugVar,
28957fcd345SFrancis Visoiu Mistrih                         T &Object, ModuleSlotTracker &MST) {
29057fcd345SFrancis Visoiu Mistrih   std::array<std::string *, 3> Outputs{{&Object.DebugVar.Value,
29157fcd345SFrancis Visoiu Mistrih                                         &Object.DebugExpr.Value,
29257fcd345SFrancis Visoiu Mistrih                                         &Object.DebugLoc.Value}};
29357fcd345SFrancis Visoiu Mistrih   std::array<const Metadata *, 3> Metas{{DebugVar.Var,
29457fcd345SFrancis Visoiu Mistrih                                         DebugVar.Expr,
29557fcd345SFrancis Visoiu Mistrih                                         DebugVar.Loc}};
29657fcd345SFrancis Visoiu Mistrih   for (unsigned i = 0; i < 3; ++i) {
29757fcd345SFrancis Visoiu Mistrih     raw_string_ostream StrOS(*Outputs[i]);
29857fcd345SFrancis Visoiu Mistrih     Metas[i]->printAsOperand(StrOS, MST);
29957fcd345SFrancis Visoiu Mistrih   }
30057fcd345SFrancis Visoiu Mistrih }
3016c452834SJustin Bogner 
convert(yaml::MachineFunction & MF,const MachineRegisterInfo & RegInfo,const TargetRegisterInfo * TRI)30254565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
30328148ba8SAlex Lorenz                          const MachineRegisterInfo &RegInfo,
30428148ba8SAlex Lorenz                          const TargetRegisterInfo *TRI) {
30554565cf0SAlex Lorenz   MF.TracksRegLiveness = RegInfo.tracksLiveness();
30628148ba8SAlex Lorenz 
30728148ba8SAlex Lorenz   // Print the virtual register definitions.
30828148ba8SAlex Lorenz   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
3092bea69bfSDaniel Sanders     unsigned Reg = Register::index2VirtReg(I);
31028148ba8SAlex Lorenz     yaml::VirtualRegisterDefinition VReg;
31128148ba8SAlex Lorenz     VReg.ID = I;
312399b46c9SPuyan Lotfi     if (RegInfo.getVRegName(Reg) != "")
313399b46c9SPuyan Lotfi       continue;
314a8a83d15SFrancis Visoiu Mistrih     ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);
315ab4cbcfdSAlex Lorenz     unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
316ab4cbcfdSAlex Lorenz     if (PreferredReg)
3179d419d3bSFrancis Visoiu Mistrih       printRegMIR(PreferredReg, VReg.PreferredRegister, TRI);
31828148ba8SAlex Lorenz     MF.VirtualRegisters.push_back(VReg);
31928148ba8SAlex Lorenz   }
32012045a4bSAlex Lorenz 
32112045a4bSAlex Lorenz   // Print the live ins.
32272518eaaSKrzysztof Parzyszek   for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) {
32312045a4bSAlex Lorenz     yaml::MachineFunctionLiveIn LiveIn;
3249d419d3bSFrancis Visoiu Mistrih     printRegMIR(LI.first, LiveIn.Register, TRI);
32572518eaaSKrzysztof Parzyszek     if (LI.second)
3269d419d3bSFrancis Visoiu Mistrih       printRegMIR(LI.second, LiveIn.VirtualRegister, TRI);
32712045a4bSAlex Lorenz     MF.LiveIns.push_back(LiveIn);
32812045a4bSAlex Lorenz   }
3290ef61ec3SOren Ben Simhon 
3300ef61ec3SOren Ben Simhon   // Prints the callee saved registers.
3310ef61ec3SOren Ben Simhon   if (RegInfo.isUpdatedCSRsInitialized()) {
3320ef61ec3SOren Ben Simhon     const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
333c4838087SAlex Lorenz     std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
3340ef61ec3SOren Ben Simhon     for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
335c4838087SAlex Lorenz       yaml::FlowStringValue Reg;
3369d419d3bSFrancis Visoiu Mistrih       printRegMIR(*I, Reg, TRI);
337c4838087SAlex Lorenz       CalleeSavedRegisters.push_back(Reg);
338c4838087SAlex Lorenz     }
339c4838087SAlex Lorenz     MF.CalleeSavedRegisters = CalleeSavedRegisters;
34054565cf0SAlex Lorenz   }
3410ef61ec3SOren Ben Simhon }
34254565cf0SAlex Lorenz 
convert(ModuleSlotTracker & MST,yaml::MachineFrameInfo & YamlMFI,const MachineFrameInfo & MFI)343a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
344a6f9a37dSAlex Lorenz                          yaml::MachineFrameInfo &YamlMFI,
34560541c1dSAlex Lorenz                          const MachineFrameInfo &MFI) {
34660541c1dSAlex Lorenz   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
34760541c1dSAlex Lorenz   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
34860541c1dSAlex Lorenz   YamlMFI.HasStackMap = MFI.hasStackMap();
34960541c1dSAlex Lorenz   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
35060541c1dSAlex Lorenz   YamlMFI.StackSize = MFI.getStackSize();
35160541c1dSAlex Lorenz   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
352d000655aSGuillaume Chatelet   YamlMFI.MaxAlignment = MFI.getMaxAlign().value();
35360541c1dSAlex Lorenz   YamlMFI.AdjustsStack = MFI.adjustsStack();
35460541c1dSAlex Lorenz   YamlMFI.HasCalls = MFI.hasCalls();
355ab9438cbSMatthias Braun   YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()
356ab9438cbSMatthias Braun     ? MFI.getMaxCallFrameSize() : ~0u;
3579ea2c012SReid Kleckner   YamlMFI.CVBytesOfCalleeSavedRegisters =
3589ea2c012SReid Kleckner       MFI.getCVBytesOfCalleeSavedRegisters();
35960541c1dSAlex Lorenz   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
36060541c1dSAlex Lorenz   YamlMFI.HasVAStart = MFI.hasVAStart();
36160541c1dSAlex Lorenz   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
36220a24af0SMatt Arsenault   YamlMFI.HasTailCall = MFI.hasTailCall();
363537d7eeeSFrancis Visoiu Mistrih   YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();
364a6f9a37dSAlex Lorenz   if (MFI.getSavePoint()) {
365a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
36625528d6dSFrancis Visoiu Mistrih     StrOS << printMBBReference(*MFI.getSavePoint());
367a6f9a37dSAlex Lorenz   }
368a6f9a37dSAlex Lorenz   if (MFI.getRestorePoint()) {
369a6f9a37dSAlex Lorenz     raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
37025528d6dSFrancis Visoiu Mistrih     StrOS << printMBBReference(*MFI.getRestorePoint());
371a6f9a37dSAlex Lorenz   }
37260541c1dSAlex Lorenz }
37360541c1dSAlex Lorenz 
convertStackObjects(yaml::MachineFunction & YMF,const MachineFunction & MF,ModuleSlotTracker & MST)374ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
375ef331effSMatthias Braun                                      const MachineFunction &MF,
376ef331effSMatthias Braun                                      ModuleSlotTracker &MST) {
377ef331effSMatthias Braun   const MachineFrameInfo &MFI = MF.getFrameInfo();
378ef331effSMatthias Braun   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
379b3cdaef5Sdfukalov 
380de491f05SAlex Lorenz   // Process fixed stack objects.
381b3cdaef5Sdfukalov   assert(YMF.FixedStackObjects.empty());
382b3cdaef5Sdfukalov   SmallVector<int, 32> FixedStackObjectsIdx;
383b3cdaef5Sdfukalov   const int BeginIdx = MFI.getObjectIndexBegin();
384b3cdaef5Sdfukalov   if (BeginIdx < 0)
385b3cdaef5Sdfukalov     FixedStackObjectsIdx.reserve(-BeginIdx);
386b3cdaef5Sdfukalov 
387f6bc8667SAlex Lorenz   unsigned ID = 0;
388b3cdaef5Sdfukalov   for (int I = BeginIdx; I < 0; ++I, ++ID) {
389b3cdaef5Sdfukalov     FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.
390de491f05SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
391de491f05SAlex Lorenz       continue;
392de491f05SAlex Lorenz 
393de491f05SAlex Lorenz     yaml::FixedMachineStackObject YamlObject;
3947feaf7c6SAlex Lorenz     YamlObject.ID = ID;
395de491f05SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
396de491f05SAlex Lorenz                           ? yaml::FixedMachineStackObject::SpillSlot
397de491f05SAlex Lorenz                           : yaml::FixedMachineStackObject::DefaultType;
398de491f05SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
399de491f05SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
400bf573beaSGuillaume Chatelet     YamlObject.Alignment = MFI.getObjectAlign(I);
4015d6ee76cSSander de Smalen     YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
402de491f05SAlex Lorenz     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
403de491f05SAlex Lorenz     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
404b3cdaef5Sdfukalov     // Save the ID' position in FixedStackObjects storage vector.
405b3cdaef5Sdfukalov     FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
406ef331effSMatthias Braun     YMF.FixedStackObjects.push_back(YamlObject);
4077feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(
4087b55066aSMatt Arsenault         std::make_pair(I, FrameIndexOperand::createFixed(ID)));
409de491f05SAlex Lorenz   }
410de491f05SAlex Lorenz 
411de491f05SAlex Lorenz   // Process ordinary stack objects.
412b3cdaef5Sdfukalov   assert(YMF.StackObjects.empty());
413b3cdaef5Sdfukalov   SmallVector<unsigned, 32> StackObjectsIdx;
414b3cdaef5Sdfukalov   const int EndIdx = MFI.getObjectIndexEnd();
415b3cdaef5Sdfukalov   if (EndIdx > 0)
416b3cdaef5Sdfukalov     StackObjectsIdx.reserve(EndIdx);
417de491f05SAlex Lorenz   ID = 0;
418b3cdaef5Sdfukalov   for (int I = 0; I < EndIdx; ++I, ++ID) {
419b3cdaef5Sdfukalov     StackObjectsIdx.push_back(-1); // Fill index for possible dead.
420f6bc8667SAlex Lorenz     if (MFI.isDeadObjectIndex(I))
421f6bc8667SAlex Lorenz       continue;
422f6bc8667SAlex Lorenz 
423f6bc8667SAlex Lorenz     yaml::MachineStackObject YamlObject;
4247feaf7c6SAlex Lorenz     YamlObject.ID = ID;
42537643a04SAlex Lorenz     if (const auto *Alloca = MFI.getObjectAllocation(I))
426adcd0268SBenjamin Kramer       YamlObject.Name.Value = std::string(
427b9a7c89dSGabriel Hjort Åkerlund           Alloca->hasName() ? Alloca->getName() : "");
428f6bc8667SAlex Lorenz     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
429f6bc8667SAlex Lorenz                           ? yaml::MachineStackObject::SpillSlot
430418f3ec1SAlex Lorenz                           : MFI.isVariableSizedObjectIndex(I)
431418f3ec1SAlex Lorenz                                 ? yaml::MachineStackObject::VariableSized
432f6bc8667SAlex Lorenz                                 : yaml::MachineStackObject::DefaultType;
433f6bc8667SAlex Lorenz     YamlObject.Offset = MFI.getObjectOffset(I);
434f6bc8667SAlex Lorenz     YamlObject.Size = MFI.getObjectSize(I);
435bf573beaSGuillaume Chatelet     YamlObject.Alignment = MFI.getObjectAlign(I);
4365d6ee76cSSander de Smalen     YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
437f6bc8667SAlex Lorenz 
438b3cdaef5Sdfukalov     // Save the ID' position in StackObjects storage vector.
439b3cdaef5Sdfukalov     StackObjectsIdx[ID] = YMF.StackObjects.size();
440ef331effSMatthias Braun     YMF.StackObjects.push_back(YamlObject);
4417feaf7c6SAlex Lorenz     StackObjectOperandMapping.insert(std::make_pair(
4427b55066aSMatt Arsenault         I, FrameIndexOperand::create(YamlObject.Name.Value, ID)));
443f6bc8667SAlex Lorenz   }
4441bb48de1SAlex Lorenz 
4451bb48de1SAlex Lorenz   for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
446b3cdaef5Sdfukalov     const int FrameIdx = CSInfo.getFrameIdx();
447b3cdaef5Sdfukalov     if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))
448d3ed418aSMatt Arsenault       continue;
449d3ed418aSMatt Arsenault 
4501bb48de1SAlex Lorenz     yaml::StringValue Reg;
4519d419d3bSFrancis Visoiu Mistrih     printRegMIR(CSInfo.getReg(), Reg, TRI);
4525c179bf1SZaara Syeda     if (!CSInfo.isSpilledToReg()) {
453b3cdaef5Sdfukalov       assert(FrameIdx >= MFI.getObjectIndexBegin() &&
454b3cdaef5Sdfukalov              FrameIdx < MFI.getObjectIndexEnd() &&
4551bb48de1SAlex Lorenz              "Invalid stack object index");
456b3cdaef5Sdfukalov       if (FrameIdx < 0) { // Negative index means fixed objects.
457b3cdaef5Sdfukalov         auto &Object =
458b3cdaef5Sdfukalov             YMF.FixedStackObjects
459b3cdaef5Sdfukalov                 [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
460b3cdaef5Sdfukalov         Object.CalleeSavedRegister = Reg;
461b3cdaef5Sdfukalov         Object.CalleeSavedRestored = CSInfo.isRestored();
4625c3e8a45SMatthias Braun       } else {
463b3cdaef5Sdfukalov         auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
464b3cdaef5Sdfukalov         Object.CalleeSavedRegister = Reg;
465b3cdaef5Sdfukalov         Object.CalleeSavedRestored = CSInfo.isRestored();
4665c3e8a45SMatthias Braun       }
4671bb48de1SAlex Lorenz     }
4685c179bf1SZaara Syeda   }
469a56ba6a6SAlex Lorenz   for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
470a56ba6a6SAlex Lorenz     auto LocalObject = MFI.getLocalFrameObjectMap(I);
471b3cdaef5Sdfukalov     assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
472b3cdaef5Sdfukalov     YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
473b3cdaef5Sdfukalov         LocalObject.second;
474a56ba6a6SAlex Lorenz   }
475a314d813SAlex Lorenz 
476a314d813SAlex Lorenz   // Print the stack object references in the frame information class after
477a314d813SAlex Lorenz   // converting the stack objects.
478a314d813SAlex Lorenz   if (MFI.hasStackProtectorIndex()) {
479ef331effSMatthias Braun     raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);
480a314d813SAlex Lorenz     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
481a314d813SAlex Lorenz         .printStackObjectReference(MFI.getStackProtectorIndex());
482a314d813SAlex Lorenz   }
483df9e3c6fSAlex Lorenz 
4849c122537SMatt Arsenault   if (MFI.hasFunctionContextIndex()) {
4859c122537SMatt Arsenault     raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value);
4869c122537SMatt Arsenault     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
4879c122537SMatt Arsenault         .printStackObjectReference(MFI.getFunctionContextIndex());
4889c122537SMatt Arsenault   }
4899c122537SMatt Arsenault 
490df9e3c6fSAlex Lorenz   // Print the debug variable information.
491ef331effSMatthias Braun   for (const MachineFunction::VariableDbgInfo &DebugVar :
492ef331effSMatthias Braun        MF.getVariableDbgInfo()) {
493b3cdaef5Sdfukalov     assert(DebugVar.Slot >= MFI.getObjectIndexBegin() &&
494b3cdaef5Sdfukalov            DebugVar.Slot < MFI.getObjectIndexEnd() &&
495df9e3c6fSAlex Lorenz            "Invalid stack object index");
496b3cdaef5Sdfukalov     if (DebugVar.Slot < 0) { // Negative index means fixed objects.
497b3cdaef5Sdfukalov       auto &Object =
498b3cdaef5Sdfukalov           YMF.FixedStackObjects[FixedStackObjectsIdx[DebugVar.Slot +
499b3cdaef5Sdfukalov                                                      MFI.getNumFixedObjects()]];
50057fcd345SFrancis Visoiu Mistrih       printStackObjectDbgInfo(DebugVar, Object, MST);
50157fcd345SFrancis Visoiu Mistrih     } else {
502b3cdaef5Sdfukalov       auto &Object = YMF.StackObjects[StackObjectsIdx[DebugVar.Slot]];
50357fcd345SFrancis Visoiu Mistrih       printStackObjectDbgInfo(DebugVar, Object, MST);
504df9e3c6fSAlex Lorenz     }
505df9e3c6fSAlex Lorenz   }
506f6bc8667SAlex Lorenz }
507f6bc8667SAlex Lorenz 
convertCallSiteObjects(yaml::MachineFunction & YMF,const MachineFunction & MF,ModuleSlotTracker & MST)508a7cde103SDjordje Todorovic void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
509a7cde103SDjordje Todorovic                                         const MachineFunction &MF,
510a7cde103SDjordje Todorovic                                         ModuleSlotTracker &MST) {
511a7cde103SDjordje Todorovic   const auto *TRI = MF.getSubtarget().getRegisterInfo();
512a7cde103SDjordje Todorovic   for (auto CSInfo : MF.getCallSitesInfo()) {
513a7cde103SDjordje Todorovic     yaml::CallSiteInfo YmlCS;
514a7cde103SDjordje Todorovic     yaml::CallSiteInfo::MachineInstrLoc CallLocation;
515a7cde103SDjordje Todorovic 
516a7cde103SDjordje Todorovic     // Prepare instruction position.
51788df53e6SDavid Stenberg     MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator();
518a7cde103SDjordje Todorovic     CallLocation.BlockNum = CallI->getParent()->getNumber();
519a7cde103SDjordje Todorovic     // Get call instruction offset from the beginning of block.
52088df53e6SDavid Stenberg     CallLocation.Offset =
52188df53e6SDavid Stenberg         std::distance(CallI->getParent()->instr_begin(), CallI);
522a7cde103SDjordje Todorovic     YmlCS.CallLocation = CallLocation;
523a7cde103SDjordje Todorovic     // Construct call arguments and theirs forwarding register info.
524a7cde103SDjordje Todorovic     for (auto ArgReg : CSInfo.second) {
525a7cde103SDjordje Todorovic       yaml::CallSiteInfo::ArgRegPair YmlArgReg;
526a7cde103SDjordje Todorovic       YmlArgReg.ArgNo = ArgReg.ArgNo;
527a7cde103SDjordje Todorovic       printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
528a7cde103SDjordje Todorovic       YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
529a7cde103SDjordje Todorovic     }
530a7cde103SDjordje Todorovic     YMF.CallSitesInfo.push_back(YmlCS);
531a7cde103SDjordje Todorovic   }
532a7cde103SDjordje Todorovic 
533a7cde103SDjordje Todorovic   // Sort call info by position of call instructions.
534a7cde103SDjordje Todorovic   llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(),
535a7cde103SDjordje Todorovic              [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {
536a7cde103SDjordje Todorovic                if (A.CallLocation.BlockNum == B.CallLocation.BlockNum)
537a7cde103SDjordje Todorovic                  return A.CallLocation.Offset < B.CallLocation.Offset;
538a7cde103SDjordje Todorovic                return A.CallLocation.BlockNum < B.CallLocation.BlockNum;
539a7cde103SDjordje Todorovic              });
540a7cde103SDjordje Todorovic }
541a7cde103SDjordje Todorovic 
convertMachineMetadataNodes(yaml::MachineFunction & YMF,const MachineFunction & MF,MachineModuleSlotTracker & MST)542b9c05affSMichael Liao void MIRPrinter::convertMachineMetadataNodes(yaml::MachineFunction &YMF,
543b9c05affSMichael Liao                                              const MachineFunction &MF,
544b9c05affSMichael Liao                                              MachineModuleSlotTracker &MST) {
545b9c05affSMichael Liao   MachineModuleSlotTracker::MachineMDNodeListType MDList;
546b9c05affSMichael Liao   MST.collectMachineMDNodes(MDList);
547b9c05affSMichael Liao   for (auto &MD : MDList) {
548b9c05affSMichael Liao     std::string NS;
549b9c05affSMichael Liao     raw_string_ostream StrOS(NS);
550b9c05affSMichael Liao     MD.second->print(StrOS, MST, MF.getFunction().getParent());
551b9c05affSMichael Liao     YMF.MachineMetadataNodes.push_back(StrOS.str());
552b9c05affSMichael Liao   }
553b9c05affSMichael Liao }
554b9c05affSMichael Liao 
convert(yaml::MachineFunction & MF,const MachineConstantPool & ConstantPool)555ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF,
556ab980499SAlex Lorenz                          const MachineConstantPool &ConstantPool) {
557ab980499SAlex Lorenz   unsigned ID = 0;
558ab980499SAlex Lorenz   for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
559ab980499SAlex Lorenz     std::string Str;
560ab980499SAlex Lorenz     raw_string_ostream StrOS(Str);
561d5a00b0fSDiana Picus     if (Constant.isMachineConstantPoolEntry()) {
562d5a00b0fSDiana Picus       Constant.Val.MachineCPVal->print(StrOS);
563d5a00b0fSDiana Picus     } else {
564ab980499SAlex Lorenz       Constant.Val.ConstVal->printAsOperand(StrOS);
565d5a00b0fSDiana Picus     }
566d5a00b0fSDiana Picus 
567d5a00b0fSDiana Picus     yaml::MachineConstantPoolValue YamlConstant;
568ab980499SAlex Lorenz     YamlConstant.ID = ID++;
569ab980499SAlex Lorenz     YamlConstant.Value = StrOS.str();
5708c72b027SCraig Topper     YamlConstant.Alignment = Constant.getAlign();
571d5a00b0fSDiana Picus     YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();
572d5a00b0fSDiana Picus 
573ab980499SAlex Lorenz     MF.Constants.push_back(YamlConstant);
574ab980499SAlex Lorenz   }
575ab980499SAlex Lorenz }
576ab980499SAlex Lorenz 
convert(ModuleSlotTracker & MST,yaml::MachineJumpTable & YamlJTI,const MachineJumpTableInfo & JTI)577900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST,
5786799e9b3SAlex Lorenz                          yaml::MachineJumpTable &YamlJTI,
5796799e9b3SAlex Lorenz                          const MachineJumpTableInfo &JTI) {
5806799e9b3SAlex Lorenz   YamlJTI.Kind = JTI.getEntryKind();
5816799e9b3SAlex Lorenz   unsigned ID = 0;
5826799e9b3SAlex Lorenz   for (const auto &Table : JTI.getJumpTables()) {
5836799e9b3SAlex Lorenz     std::string Str;
5846799e9b3SAlex Lorenz     yaml::MachineJumpTable::Entry Entry;
5856799e9b3SAlex Lorenz     Entry.ID = ID++;
5866799e9b3SAlex Lorenz     for (const auto *MBB : Table.MBBs) {
5876799e9b3SAlex Lorenz       raw_string_ostream StrOS(Str);
58825528d6dSFrancis Visoiu Mistrih       StrOS << printMBBReference(*MBB);
5896799e9b3SAlex Lorenz       Entry.Blocks.push_back(StrOS.str());
5906799e9b3SAlex Lorenz       Str.clear();
5916799e9b3SAlex Lorenz     }
5926799e9b3SAlex Lorenz     YamlJTI.Entries.push_back(Entry);
5936799e9b3SAlex Lorenz   }
5946799e9b3SAlex Lorenz }
5956799e9b3SAlex Lorenz 
initRegisterMaskIds(const MachineFunction & MF)5968f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
5978f6f4285SAlex Lorenz   const auto *TRI = MF.getSubtarget().getRegisterInfo();
5988f6f4285SAlex Lorenz   unsigned I = 0;
5998f6f4285SAlex Lorenz   for (const uint32_t *Mask : TRI->getRegMasks())
6008f6f4285SAlex Lorenz     RegisterMaskIds.insert(std::make_pair(Mask, I++));
6018f6f4285SAlex Lorenz }
6028f6f4285SAlex Lorenz 
guessSuccessors(const MachineBasicBlock & MBB,SmallVectorImpl<MachineBasicBlock * > & Result,bool & IsFallthrough)6038940114fSMatthias Braun void llvm::guessSuccessors(const MachineBasicBlock &MBB,
6048940114fSMatthias Braun                            SmallVectorImpl<MachineBasicBlock*> &Result,
6058940114fSMatthias Braun                            bool &IsFallthrough) {
6068940114fSMatthias Braun   SmallPtrSet<MachineBasicBlock*,8> Seen;
6078940114fSMatthias Braun 
6088940114fSMatthias Braun   for (const MachineInstr &MI : MBB) {
6098940114fSMatthias Braun     if (MI.isPHI())
6108940114fSMatthias Braun       continue;
6118940114fSMatthias Braun     for (const MachineOperand &MO : MI.operands()) {
6128940114fSMatthias Braun       if (!MO.isMBB())
6138940114fSMatthias Braun         continue;
6148940114fSMatthias Braun       MachineBasicBlock *Succ = MO.getMBB();
6158940114fSMatthias Braun       auto RP = Seen.insert(Succ);
6168940114fSMatthias Braun       if (RP.second)
6178940114fSMatthias Braun         Result.push_back(Succ);
6188940114fSMatthias Braun     }
6198940114fSMatthias Braun   }
6208940114fSMatthias Braun   MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
6218940114fSMatthias Braun   IsFallthrough = I == MBB.end() || !I->isBarrier();
6228940114fSMatthias Braun }
6238940114fSMatthias Braun 
6248940114fSMatthias Braun bool
canPredictBranchProbabilities(const MachineBasicBlock & MBB) const6258940114fSMatthias Braun MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const {
6268940114fSMatthias Braun   if (MBB.succ_size() <= 1)
6278940114fSMatthias Braun     return true;
6288940114fSMatthias Braun   if (!MBB.hasSuccessorProbabilities())
6298940114fSMatthias Braun     return true;
6308940114fSMatthias Braun 
6318940114fSMatthias Braun   SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(),
6328940114fSMatthias Braun                                               MBB.Probs.end());
6338940114fSMatthias Braun   BranchProbability::normalizeProbabilities(Normalized.begin(),
6348940114fSMatthias Braun                                             Normalized.end());
6358940114fSMatthias Braun   SmallVector<BranchProbability,8> Equal(Normalized.size());
6368940114fSMatthias Braun   BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end());
6378940114fSMatthias Braun 
6388940114fSMatthias Braun   return std::equal(Normalized.begin(), Normalized.end(), Equal.begin());
6398940114fSMatthias Braun }
6408940114fSMatthias Braun 
canPredictSuccessors(const MachineBasicBlock & MBB) const6418940114fSMatthias Braun bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const {
6428940114fSMatthias Braun   SmallVector<MachineBasicBlock*,8> GuessedSuccs;
6438940114fSMatthias Braun   bool GuessedFallthrough;
6448940114fSMatthias Braun   guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough);
6458940114fSMatthias Braun   if (GuessedFallthrough) {
6468940114fSMatthias Braun     const MachineFunction &MF = *MBB.getParent();
6478940114fSMatthias Braun     MachineFunction::const_iterator NextI = std::next(MBB.getIterator());
6488940114fSMatthias Braun     if (NextI != MF.end()) {
6498940114fSMatthias Braun       MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);
6508940114fSMatthias Braun       if (!is_contained(GuessedSuccs, Next))
6518940114fSMatthias Braun         GuessedSuccs.push_back(Next);
6528940114fSMatthias Braun     }
6538940114fSMatthias Braun   }
6548940114fSMatthias Braun   if (GuessedSuccs.size() != MBB.succ_size())
6558940114fSMatthias Braun     return false;
6568940114fSMatthias Braun   return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin());
6578940114fSMatthias Braun }
6588940114fSMatthias Braun 
print(const MachineBasicBlock & MBB)6595022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) {
6605022f6bbSAlex Lorenz   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
6615934df0cSNicolai Hähnle   MBB.printName(OS,
6625934df0cSNicolai Hähnle                 MachineBasicBlock::PrintNameIr |
6635934df0cSNicolai Hähnle                     MachineBasicBlock::PrintNameAttributes,
6645934df0cSNicolai Hähnle                 &MST);
6655022f6bbSAlex Lorenz   OS << ":\n";
6665022f6bbSAlex Lorenz 
6675022f6bbSAlex Lorenz   bool HasLineAttributes = false;
6685022f6bbSAlex Lorenz   // Print the successors
6698940114fSMatthias Braun   bool canPredictProbs = canPredictBranchProbabilities(MBB);
670d652aeb1SQuentin Colombet   // Even if the list of successors is empty, if we cannot guess it,
671d652aeb1SQuentin Colombet   // we need to print it to tell the parser that the list is empty.
672d652aeb1SQuentin Colombet   // This is needed, because MI model unreachable as empty blocks
673d652aeb1SQuentin Colombet   // with an empty successor list. If the parser would see that
674d652aeb1SQuentin Colombet   // without the successor list, it would guess the code would
675d652aeb1SQuentin Colombet   // fallthrough.
676d652aeb1SQuentin Colombet   if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||
677d652aeb1SQuentin Colombet       !canPredictSuccessors(MBB)) {
6785022f6bbSAlex Lorenz     OS.indent(2) << "successors: ";
6795022f6bbSAlex Lorenz     for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
6805022f6bbSAlex Lorenz       if (I != MBB.succ_begin())
6815022f6bbSAlex Lorenz         OS << ", ";
68225528d6dSFrancis Visoiu Mistrih       OS << printMBBReference(**I);
6838940114fSMatthias Braun       if (!SimplifyMIR || !canPredictProbs)
684b51774acSGeoff Berry         OS << '('
685b51774acSGeoff Berry            << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator())
686b51774acSGeoff Berry            << ')';
6875022f6bbSAlex Lorenz     }
6885022f6bbSAlex Lorenz     OS << "\n";
6895022f6bbSAlex Lorenz     HasLineAttributes = true;
6905022f6bbSAlex Lorenz   }
6915022f6bbSAlex Lorenz 
6925022f6bbSAlex Lorenz   // Print the live in registers.
69311723322SMatthias Braun   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
694*56303223SMatt Arsenault   if (!MBB.livein_empty()) {
69511723322SMatthias Braun     const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
6965022f6bbSAlex Lorenz     OS.indent(2) << "liveins: ";
697b2b7ef1dSMatthias Braun     bool First = true;
698*56303223SMatt Arsenault     for (const auto &LI : MBB.liveins_dbg()) {
699b2b7ef1dSMatthias Braun       if (!First)
7005022f6bbSAlex Lorenz         OS << ", ";
701b2b7ef1dSMatthias Braun       First = false;
702c71cced0SFrancis Visoiu Mistrih       OS << printReg(LI.PhysReg, &TRI);
70391b5cf84SKrzysztof Parzyszek       if (!LI.LaneMask.all())
704d62669d7SKrzysztof Parzyszek         OS << ":0x" << PrintLaneMask(LI.LaneMask);
7055022f6bbSAlex Lorenz     }
7065022f6bbSAlex Lorenz     OS << "\n";
7075022f6bbSAlex Lorenz     HasLineAttributes = true;
7085022f6bbSAlex Lorenz   }
7095022f6bbSAlex Lorenz 
7105022f6bbSAlex Lorenz   if (HasLineAttributes)
7115022f6bbSAlex Lorenz     OS << "\n";
712f9a2b123SAlex Lorenz   bool IsInBundle = false;
713f9a2b123SAlex Lorenz   for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) {
714f9a2b123SAlex Lorenz     const MachineInstr &MI = *I;
715f9a2b123SAlex Lorenz     if (IsInBundle && !MI.isInsideBundle()) {
716f9a2b123SAlex Lorenz       OS.indent(2) << "}\n";
717f9a2b123SAlex Lorenz       IsInBundle = false;
718f9a2b123SAlex Lorenz     }
719f9a2b123SAlex Lorenz     OS.indent(IsInBundle ? 4 : 2);
7205022f6bbSAlex Lorenz     print(MI);
721f9a2b123SAlex Lorenz     if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
722f9a2b123SAlex Lorenz       OS << " {";
723f9a2b123SAlex Lorenz       IsInBundle = true;
724f9a2b123SAlex Lorenz     }
7255022f6bbSAlex Lorenz     OS << "\n";
7265022f6bbSAlex Lorenz   }
727f9a2b123SAlex Lorenz   if (IsInBundle)
728f9a2b123SAlex Lorenz     OS.indent(2) << "}\n";
7295022f6bbSAlex Lorenz }
7305022f6bbSAlex Lorenz 
print(const MachineInstr & MI)7318e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) {
732fdf9bf4fSJustin Bogner   const auto *MF = MI.getMF();
7334e14a497SQuentin Colombet   const auto &MRI = MF->getRegInfo();
7344e14a497SQuentin Colombet   const auto &SubTarget = MF->getSubtarget();
735f3db51deSAlex Lorenz   const auto *TRI = SubTarget.getRegisterInfo();
736f3db51deSAlex Lorenz   assert(TRI && "Expected target register info");
7378e0a1b48SAlex Lorenz   const auto *TII = SubTarget.getInstrInfo();
7388e0a1b48SAlex Lorenz   assert(TII && "Expected target instruction info");
739f4baeb51SAlex Lorenz   if (MI.isCFIInstruction())
740f4baeb51SAlex Lorenz     assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
7418e0a1b48SAlex Lorenz 
742d28d3cc0STim Northover   SmallBitVector PrintedTypes(8);
743a8a83d15SFrancis Visoiu Mistrih   bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();
744f3db51deSAlex Lorenz   unsigned I = 0, E = MI.getNumOperands();
745f3db51deSAlex Lorenz   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
746f3db51deSAlex Lorenz          !MI.getOperand(I).isImplicit();
747f3db51deSAlex Lorenz        ++I) {
748f3db51deSAlex Lorenz     if (I)
749f3db51deSAlex Lorenz       OS << ", ";
7507efabe5cSSjoerd Meijer     print(MI, I, TRI, TII, ShouldPrintRegisterTies,
751a8a83d15SFrancis Visoiu Mistrih           MI.getTypeToPrint(I, PrintedTypes, MRI),
752a8a83d15SFrancis Visoiu Mistrih           /*PrintDef=*/false);
753f3db51deSAlex Lorenz   }
754f3db51deSAlex Lorenz 
755f3db51deSAlex Lorenz   if (I)
756f3db51deSAlex Lorenz     OS << " = ";
757e5a44660SAlex Lorenz   if (MI.getFlag(MachineInstr::FrameSetup))
758e5a44660SAlex Lorenz     OS << "frame-setup ";
7593abf0573SFrancis Visoiu Mistrih   if (MI.getFlag(MachineInstr::FrameDestroy))
760dbf2c48fSFrancis Visoiu Mistrih     OS << "frame-destroy ";
7617d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmNoNans))
7627d1b25d0SMichael Berg     OS << "nnan ";
7637d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmNoInfs))
7647d1b25d0SMichael Berg     OS << "ninf ";
7657d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmNsz))
7667d1b25d0SMichael Berg     OS << "nsz ";
7677d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmArcp))
7687d1b25d0SMichael Berg     OS << "arcp ";
7697d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmContract))
7707d1b25d0SMichael Berg     OS << "contract ";
7717d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmAfn))
7727d1b25d0SMichael Berg     OS << "afn ";
7737d1b25d0SMichael Berg   if (MI.getFlag(MachineInstr::FmReassoc))
7747d1b25d0SMichael Berg     OS << "reassoc ";
775c72a7259SMichael Berg   if (MI.getFlag(MachineInstr::NoUWrap))
776c72a7259SMichael Berg     OS << "nuw ";
777c72a7259SMichael Berg   if (MI.getFlag(MachineInstr::NoSWrap))
778c72a7259SMichael Berg     OS << "nsw ";
779c72a7259SMichael Berg   if (MI.getFlag(MachineInstr::IsExact))
780c72a7259SMichael Berg     OS << "exact ";
781f0fd11dfSUlrich Weigand   if (MI.getFlag(MachineInstr::NoFPExcept))
782f0fd11dfSUlrich Weigand     OS << "nofpexcept ";
78380e107ccSZequan Wu   if (MI.getFlag(MachineInstr::NoMerge))
78480e107ccSZequan Wu     OS << "nomerge ";
785dbf2c48fSFrancis Visoiu Mistrih 
7868e0a1b48SAlex Lorenz   OS << TII->getName(MI.getOpcode());
787f3db51deSAlex Lorenz   if (I < E)
788f3db51deSAlex Lorenz     OS << ' ';
789f3db51deSAlex Lorenz 
790f3db51deSAlex Lorenz   bool NeedComma = false;
791f3db51deSAlex Lorenz   for (; I < E; ++I) {
792f3db51deSAlex Lorenz     if (NeedComma)
793f3db51deSAlex Lorenz       OS << ", ";
7947efabe5cSSjoerd Meijer     print(MI, I, TRI, TII, ShouldPrintRegisterTies,
795a8a83d15SFrancis Visoiu Mistrih           MI.getTypeToPrint(I, PrintedTypes, MRI));
796f3db51deSAlex Lorenz     NeedComma = true;
797f3db51deSAlex Lorenz   }
79846d760d1SAlex Lorenz 
79975ca6be1SChandler Carruth   // Print any optional symbols attached to this instruction as-if they were
80075ca6be1SChandler Carruth   // operands.
80175ca6be1SChandler Carruth   if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {
80275ca6be1SChandler Carruth     if (NeedComma)
80375ca6be1SChandler Carruth       OS << ',';
80475ca6be1SChandler Carruth     OS << " pre-instr-symbol ";
80575ca6be1SChandler Carruth     MachineOperand::printSymbol(OS, *PreInstrSymbol);
80675ca6be1SChandler Carruth     NeedComma = true;
80775ca6be1SChandler Carruth   }
80875ca6be1SChandler Carruth   if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {
80975ca6be1SChandler Carruth     if (NeedComma)
81075ca6be1SChandler Carruth       OS << ',';
81175ca6be1SChandler Carruth     OS << " post-instr-symbol ";
81275ca6be1SChandler Carruth     MachineOperand::printSymbol(OS, *PostInstrSymbol);
81375ca6be1SChandler Carruth     NeedComma = true;
81475ca6be1SChandler Carruth   }
815a078c77dSAmy Huang   if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) {
816a078c77dSAmy Huang     if (NeedComma)
817a078c77dSAmy Huang       OS << ',';
818a078c77dSAmy Huang     OS << " heap-alloc-marker ";
819a078c77dSAmy Huang     HeapAllocMarker->printAsOperand(OS, MST);
820a078c77dSAmy Huang     NeedComma = true;
821a078c77dSAmy Huang   }
82275ca6be1SChandler Carruth 
8232c5f3d54SJeremy Morse   if (auto Num = MI.peekDebugInstrNum()) {
8242c5f3d54SJeremy Morse     if (NeedComma)
8252c5f3d54SJeremy Morse       OS << ',';
8262c5f3d54SJeremy Morse     OS << " debug-instr-number " << Num;
8272c5f3d54SJeremy Morse     NeedComma = true;
8282c5f3d54SJeremy Morse   }
8292c5f3d54SJeremy Morse 
830f27cea72SDaniel Sanders   if (PrintLocations) {
831548add99SFrancis Visoiu Mistrih     if (const DebugLoc &DL = MI.getDebugLoc()) {
83246d760d1SAlex Lorenz       if (NeedComma)
83346d760d1SAlex Lorenz         OS << ',';
83446d760d1SAlex Lorenz       OS << " debug-location ";
835548add99SFrancis Visoiu Mistrih       DL->printAsOperand(OS, MST);
83646d760d1SAlex Lorenz     }
837f27cea72SDaniel Sanders   }
8384af7e610SAlex Lorenz 
8394af7e610SAlex Lorenz   if (!MI.memoperands_empty()) {
8404af7e610SAlex Lorenz     OS << " :: ";
841f1caa283SMatthias Braun     const LLVMContext &Context = MF->getFunction().getContext();
842e85b06d6SFrancis Visoiu Mistrih     const MachineFrameInfo &MFI = MF->getFrameInfo();
8434af7e610SAlex Lorenz     bool NeedComma = false;
8444af7e610SAlex Lorenz     for (const auto *Op : MI.memoperands()) {
8454af7e610SAlex Lorenz       if (NeedComma)
8464af7e610SAlex Lorenz         OS << ", ";
847cfd84984SPeng Guo       Op->print(OS, MST, SSNs, Context, &MFI, TII);
8484af7e610SAlex Lorenz       NeedComma = true;
8494af7e610SAlex Lorenz     }
8504af7e610SAlex Lorenz   }
851f3db51deSAlex Lorenz }
852f3db51deSAlex Lorenz 
printStackObjectReference(int FrameIndex)8537feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) {
8547feaf7c6SAlex Lorenz   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
8557feaf7c6SAlex Lorenz   assert(ObjectInfo != StackObjectOperandMapping.end() &&
8567feaf7c6SAlex Lorenz          "Invalid frame index");
8577feaf7c6SAlex Lorenz   const FrameIndexOperand &Operand = ObjectInfo->second;
8580b5bdceaSFrancis Visoiu Mistrih   MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed,
8590b5bdceaSFrancis Visoiu Mistrih                                             Operand.Name);
8607feaf7c6SAlex Lorenz }
8617feaf7c6SAlex Lorenz 
formatOperandComment(std::string Comment)8627efabe5cSSjoerd Meijer static std::string formatOperandComment(std::string Comment) {
8637efabe5cSSjoerd Meijer   if (Comment.empty())
8647efabe5cSSjoerd Meijer     return Comment;
8657efabe5cSSjoerd Meijer   return std::string(" /* " + Comment + " */");
8667efabe5cSSjoerd Meijer }
8677efabe5cSSjoerd Meijer 
print(const MachineInstr & MI,unsigned OpIdx,const TargetRegisterInfo * TRI,const TargetInstrInfo * TII,bool ShouldPrintRegisterTies,LLT TypeToPrint,bool PrintDef)868a42ed3e3SBjorn Pettersson void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
869a42ed3e3SBjorn Pettersson                       const TargetRegisterInfo *TRI,
8707efabe5cSSjoerd Meijer                       const TargetInstrInfo *TII,
871a42ed3e3SBjorn Pettersson                       bool ShouldPrintRegisterTies, LLT TypeToPrint,
872a8a83d15SFrancis Visoiu Mistrih                       bool PrintDef) {
873a42ed3e3SBjorn Pettersson   const MachineOperand &Op = MI.getOperand(OpIdx);
8741a3e89aaSKonstantin Schwarz   std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx, TRI);
8757efabe5cSSjoerd Meijer 
876f3db51deSAlex Lorenz   switch (Op.getType()) {
877440f69c9SFrancis Visoiu Mistrih   case MachineOperand::MO_Immediate:
878440f69c9SFrancis Visoiu Mistrih     if (MI.isOperandSubregIdx(OpIdx)) {
8795df3bbf3SFrancis Visoiu Mistrih       MachineOperand::printTargetFlags(OS, Op);
880ecd0b833SFrancis Visoiu Mistrih       MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI);
881440f69c9SFrancis Visoiu Mistrih       break;
882440f69c9SFrancis Visoiu Mistrih     }
883440f69c9SFrancis Visoiu Mistrih     LLVM_FALLTHROUGH;
8846c4ca713SFrancis Visoiu Mistrih   case MachineOperand::MO_Register:
885f4bd2955SFrancis Visoiu Mistrih   case MachineOperand::MO_CImmediate:
8863b265c8fSFrancis Visoiu Mistrih   case MachineOperand::MO_FPImmediate:
88726ae8a65SFrancis Visoiu Mistrih   case MachineOperand::MO_MachineBasicBlock:
888b3a0d513SFrancis Visoiu Mistrih   case MachineOperand::MO_ConstantPoolIndex:
889b41dbbe3SFrancis Visoiu Mistrih   case MachineOperand::MO_TargetIndex:
890e76c5fcdSFrancis Visoiu Mistrih   case MachineOperand::MO_JumpTableIndex:
8915df3bbf3SFrancis Visoiu Mistrih   case MachineOperand::MO_ExternalSymbol:
892bdaf8bfaSFrancis Visoiu Mistrih   case MachineOperand::MO_GlobalAddress:
8932db59382SFrancis Visoiu Mistrih   case MachineOperand::MO_RegisterLiveOut:
8943c99371cSFrancis Visoiu Mistrih   case MachineOperand::MO_Metadata:
895874ae6faSFrancis Visoiu Mistrih   case MachineOperand::MO_MCSymbol:
896bbd610aeSFrancis Visoiu Mistrih   case MachineOperand::MO_CFIIndex:
897cb2683d4SFrancis Visoiu Mistrih   case MachineOperand::MO_IntrinsicID:
898f81727d1SFrancis Visoiu Mistrih   case MachineOperand::MO_Predicate:
8995af9cf04SMatt Arsenault   case MachineOperand::MO_BlockAddress:
9005af9cf04SMatt Arsenault   case MachineOperand::MO_ShuffleMask: {
901a8a83d15SFrancis Visoiu Mistrih     unsigned TiedOperandIdx = 0;
902440f69c9SFrancis Visoiu Mistrih     if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
903a8a83d15SFrancis Visoiu Mistrih       TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
904a8a83d15SFrancis Visoiu Mistrih     const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo();
905de3d0ee0SDaniel Sanders     Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false,
906378b5f3dSFrancis Visoiu Mistrih              ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII);
9077efabe5cSSjoerd Meijer       OS << formatOperandComment(MOComment);
908f3db51deSAlex Lorenz     break;
9096c452834SJustin Bogner   }
9107feaf7c6SAlex Lorenz   case MachineOperand::MO_FrameIndex:
9117feaf7c6SAlex Lorenz     printStackObjectReference(Op.getIndex());
9127feaf7c6SAlex Lorenz     break;
9138f6f4285SAlex Lorenz   case MachineOperand::MO_RegisterMask: {
9148f6f4285SAlex Lorenz     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
9158f6f4285SAlex Lorenz     if (RegMaskInfo != RegisterMaskIds.end())
9168f6f4285SAlex Lorenz       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
9178f6f4285SAlex Lorenz     else
9180ef61ec3SOren Ben Simhon       printCustomRegMask(Op.getRegMask(), OS, TRI);
9198f6f4285SAlex Lorenz     break;
9208f6f4285SAlex Lorenz   }
921f3db51deSAlex Lorenz   }
9224f093bf1SAlex Lorenz }
9234f093bf1SAlex Lorenz 
printIRValue(raw_ostream & OS,const Value & V,ModuleSlotTracker & MST)924de3d0ee0SDaniel Sanders void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
925de3d0ee0SDaniel Sanders                                 ModuleSlotTracker &MST) {
926de3d0ee0SDaniel Sanders   if (isa<GlobalValue>(V)) {
927de3d0ee0SDaniel Sanders     V.printAsOperand(OS, /*PrintType=*/false, MST);
928de3d0ee0SDaniel Sanders     return;
929de3d0ee0SDaniel Sanders   }
930de3d0ee0SDaniel Sanders   if (isa<Constant>(V)) {
931de3d0ee0SDaniel Sanders     // Machine memory operands can load/store to/from constant value pointers.
932de3d0ee0SDaniel Sanders     OS << '`';
933de3d0ee0SDaniel Sanders     V.printAsOperand(OS, /*PrintType=*/true, MST);
934de3d0ee0SDaniel Sanders     OS << '`';
935de3d0ee0SDaniel Sanders     return;
936de3d0ee0SDaniel Sanders   }
937de3d0ee0SDaniel Sanders   OS << "%ir.";
938de3d0ee0SDaniel Sanders   if (V.hasName()) {
939de3d0ee0SDaniel Sanders     printLLVMNameWithoutPrefix(OS, V.getName());
940de3d0ee0SDaniel Sanders     return;
941de3d0ee0SDaniel Sanders   }
942de3d0ee0SDaniel Sanders   int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1;
943de3d0ee0SDaniel Sanders   MachineOperand::printIRSlotNumber(OS, Slot);
944de3d0ee0SDaniel Sanders }
945de3d0ee0SDaniel Sanders 
printMIR(raw_ostream & OS,const Module & M)946345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) {
947345c1449SAlex Lorenz   yaml::Output Out(OS);
948345c1449SAlex Lorenz   Out << const_cast<Module &>(M);
949345c1449SAlex Lorenz }
950345c1449SAlex Lorenz 
printMIR(raw_ostream & OS,const MachineFunction & MF)951345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
952345c1449SAlex Lorenz   MIRPrinter Printer(OS);
953345c1449SAlex Lorenz   Printer.print(MF);
954345c1449SAlex Lorenz }
955