xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MIRPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the class that prints out the LLVM IR and machine
100b57cec5SDimitry Andric // functions using the MIR serialization format.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
150b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
160b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
180b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MIRYamlMapping.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
29fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineModuleSlotTracker.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
32fe6060f1SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
36*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
3781ad6265SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
380b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
390b57cec5SDimitry Andric #include "llvm/IR/Function.h"
400b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
410b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
420b57cec5SDimitry Andric #include "llvm/IR/Module.h"
430b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
440b57cec5SDimitry Andric #include "llvm/IR/Value.h"
450b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h"
460b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h"
470b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
480b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
490b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
500b57cec5SDimitry Andric #include "llvm/Support/Format.h"
510b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h"
520b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
530b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
540b57cec5SDimitry Andric #include <algorithm>
550b57cec5SDimitry Andric #include <cassert>
560b57cec5SDimitry Andric #include <cinttypes>
570b57cec5SDimitry Andric #include <cstdint>
580b57cec5SDimitry Andric #include <iterator>
590b57cec5SDimitry Andric #include <string>
600b57cec5SDimitry Andric #include <utility>
610b57cec5SDimitry Andric #include <vector>
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric using namespace llvm;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric static cl::opt<bool> SimplifyMIR(
660b57cec5SDimitry Andric     "simplify-mir", cl::Hidden,
670b57cec5SDimitry Andric     cl::desc("Leave out unnecessary information when printing MIR"));
680b57cec5SDimitry Andric 
695ffd83dbSDimitry Andric static cl::opt<bool> PrintLocations("mir-debug-loc", cl::Hidden, cl::init(true),
705ffd83dbSDimitry Andric                                     cl::desc("Print MIR debug-locations"));
715ffd83dbSDimitry Andric 
72*0fca6ea1SDimitry Andric extern cl::opt<bool> WriteNewDbgInfoFormat;
73*0fca6ea1SDimitry Andric 
740b57cec5SDimitry Andric namespace {
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric /// This structure describes how to print out stack object references.
770b57cec5SDimitry Andric struct FrameIndexOperand {
780b57cec5SDimitry Andric   std::string Name;
790b57cec5SDimitry Andric   unsigned ID;
800b57cec5SDimitry Andric   bool IsFixed;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
830b57cec5SDimitry Andric       : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// Return an ordinary stack object reference.
860b57cec5SDimitry Andric   static FrameIndexOperand create(StringRef Name, unsigned ID) {
870b57cec5SDimitry Andric     return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
880b57cec5SDimitry Andric   }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   /// Return a fixed stack object reference.
910b57cec5SDimitry Andric   static FrameIndexOperand createFixed(unsigned ID) {
920b57cec5SDimitry Andric     return FrameIndexOperand("", ID, /*IsFixed=*/true);
930b57cec5SDimitry Andric   }
940b57cec5SDimitry Andric };
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric } // end anonymous namespace
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric namespace llvm {
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric /// This class prints out the machine functions using the MIR serialization
1010b57cec5SDimitry Andric /// format.
1020b57cec5SDimitry Andric class MIRPrinter {
1030b57cec5SDimitry Andric   raw_ostream &OS;
1040b57cec5SDimitry Andric   DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
1050b57cec5SDimitry Andric   /// Maps from stack object indices to operand indices which will be used when
1060b57cec5SDimitry Andric   /// printing frame index machine operands.
1070b57cec5SDimitry Andric   DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric public:
1100b57cec5SDimitry Andric   MIRPrinter(raw_ostream &OS) : OS(OS) {}
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   void print(const MachineFunction &MF);
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
1150b57cec5SDimitry Andric                const TargetRegisterInfo *TRI);
1160b57cec5SDimitry Andric   void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
1170b57cec5SDimitry Andric                const MachineFrameInfo &MFI);
1180b57cec5SDimitry Andric   void convert(yaml::MachineFunction &MF,
1190b57cec5SDimitry Andric                const MachineConstantPool &ConstantPool);
1200b57cec5SDimitry Andric   void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
1210b57cec5SDimitry Andric                const MachineJumpTableInfo &JTI);
1220b57cec5SDimitry Andric   void convertStackObjects(yaml::MachineFunction &YMF,
1230b57cec5SDimitry Andric                            const MachineFunction &MF, ModuleSlotTracker &MST);
12406c3fb27SDimitry Andric   void convertEntryValueObjects(yaml::MachineFunction &YMF,
12506c3fb27SDimitry Andric                                 const MachineFunction &MF,
12606c3fb27SDimitry Andric                                 ModuleSlotTracker &MST);
1270b57cec5SDimitry Andric   void convertCallSiteObjects(yaml::MachineFunction &YMF,
1280b57cec5SDimitry Andric                               const MachineFunction &MF,
1290b57cec5SDimitry Andric                               ModuleSlotTracker &MST);
130fe6060f1SDimitry Andric   void convertMachineMetadataNodes(yaml::MachineFunction &YMF,
131fe6060f1SDimitry Andric                                    const MachineFunction &MF,
132fe6060f1SDimitry Andric                                    MachineModuleSlotTracker &MST);
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric private:
1350b57cec5SDimitry Andric   void initRegisterMaskIds(const MachineFunction &MF);
1360b57cec5SDimitry Andric };
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric /// This class prints out the machine instructions using the MIR serialization
1390b57cec5SDimitry Andric /// format.
1400b57cec5SDimitry Andric class MIPrinter {
1410b57cec5SDimitry Andric   raw_ostream &OS;
1420b57cec5SDimitry Andric   ModuleSlotTracker &MST;
1430b57cec5SDimitry Andric   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
1440b57cec5SDimitry Andric   const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
1450b57cec5SDimitry Andric   /// Synchronization scope names registered with LLVMContext.
1460b57cec5SDimitry Andric   SmallVector<StringRef, 8> SSNs;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const;
1490b57cec5SDimitry Andric   bool canPredictSuccessors(const MachineBasicBlock &MBB) const;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric public:
1520b57cec5SDimitry Andric   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
1530b57cec5SDimitry Andric             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
1540b57cec5SDimitry Andric             const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
1550b57cec5SDimitry Andric       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
1560b57cec5SDimitry Andric         StackObjectOperandMapping(StackObjectOperandMapping) {}
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   void print(const MachineBasicBlock &MBB);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   void print(const MachineInstr &MI);
1610b57cec5SDimitry Andric   void printStackObjectReference(int FrameIndex);
1620b57cec5SDimitry Andric   void print(const MachineInstr &MI, unsigned OpIdx,
1635ffd83dbSDimitry Andric              const TargetRegisterInfo *TRI, const TargetInstrInfo *TII,
1645ffd83dbSDimitry Andric              bool ShouldPrintRegisterTies, LLT TypeToPrint,
1655ffd83dbSDimitry Andric              bool PrintDef = true);
1660b57cec5SDimitry Andric };
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric } // end namespace llvm
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric namespace llvm {
1710b57cec5SDimitry Andric namespace yaml {
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric /// This struct serializes the LLVM IR module.
1740b57cec5SDimitry Andric template <> struct BlockScalarTraits<Module> {
1750b57cec5SDimitry Andric   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
1760b57cec5SDimitry Andric     Mod.print(OS, nullptr);
1770b57cec5SDimitry Andric   }
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
1800b57cec5SDimitry Andric     llvm_unreachable("LLVM Module is supposed to be parsed separately");
1810b57cec5SDimitry Andric     return "";
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric };
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric } // end namespace yaml
1860b57cec5SDimitry Andric } // end namespace llvm
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric static void printRegMIR(unsigned Reg, yaml::StringValue &Dest,
1890b57cec5SDimitry Andric                         const TargetRegisterInfo *TRI) {
1900b57cec5SDimitry Andric   raw_string_ostream OS(Dest.Value);
1910b57cec5SDimitry Andric   OS << printReg(Reg, TRI);
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric void MIRPrinter::print(const MachineFunction &MF) {
1950b57cec5SDimitry Andric   initRegisterMaskIds(MF);
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   yaml::MachineFunction YamlMF;
1980b57cec5SDimitry Andric   YamlMF.Name = MF.getName();
1995ffd83dbSDimitry Andric   YamlMF.Alignment = MF.getAlignment();
2000b57cec5SDimitry Andric   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
2010b57cec5SDimitry Andric   YamlMF.HasWinCFI = MF.hasWinCFI();
2020b57cec5SDimitry Andric 
20381ad6265SDimitry Andric   YamlMF.CallsEHReturn = MF.callsEHReturn();
20481ad6265SDimitry Andric   YamlMF.CallsUnwindInit = MF.callsUnwindInit();
20581ad6265SDimitry Andric   YamlMF.HasEHCatchret = MF.hasEHCatchret();
20681ad6265SDimitry Andric   YamlMF.HasEHScopes = MF.hasEHScopes();
20781ad6265SDimitry Andric   YamlMF.HasEHFunclets = MF.hasEHFunclets();
20806c3fb27SDimitry Andric   YamlMF.IsOutlined = MF.isOutlined();
209bdd1243dSDimitry Andric   YamlMF.UseDebugInstrRef = MF.useDebugInstrRef();
21081ad6265SDimitry Andric 
2110b57cec5SDimitry Andric   YamlMF.Legalized = MF.getProperties().hasProperty(
2120b57cec5SDimitry Andric       MachineFunctionProperties::Property::Legalized);
2130b57cec5SDimitry Andric   YamlMF.RegBankSelected = MF.getProperties().hasProperty(
2140b57cec5SDimitry Andric       MachineFunctionProperties::Property::RegBankSelected);
2150b57cec5SDimitry Andric   YamlMF.Selected = MF.getProperties().hasProperty(
2160b57cec5SDimitry Andric       MachineFunctionProperties::Property::Selected);
2170b57cec5SDimitry Andric   YamlMF.FailedISel = MF.getProperties().hasProperty(
2180b57cec5SDimitry Andric       MachineFunctionProperties::Property::FailedISel);
219349cc55cSDimitry Andric   YamlMF.FailsVerification = MF.getProperties().hasProperty(
220349cc55cSDimitry Andric       MachineFunctionProperties::Property::FailsVerification);
2210eae32dcSDimitry Andric   YamlMF.TracksDebugUserValues = MF.getProperties().hasProperty(
2220eae32dcSDimitry Andric       MachineFunctionProperties::Property::TracksDebugUserValues);
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
225fe6060f1SDimitry Andric   MachineModuleSlotTracker MST(&MF);
2260b57cec5SDimitry Andric   MST.incorporateFunction(MF.getFunction());
2270b57cec5SDimitry Andric   convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
2280b57cec5SDimitry Andric   convertStackObjects(YamlMF, MF, MST);
22906c3fb27SDimitry Andric   convertEntryValueObjects(YamlMF, MF, MST);
2300b57cec5SDimitry Andric   convertCallSiteObjects(YamlMF, MF, MST);
231fe6060f1SDimitry Andric   for (const auto &Sub : MF.DebugValueSubstitutions) {
232fe6060f1SDimitry Andric     const auto &SubSrc = Sub.Src;
233fe6060f1SDimitry Andric     const auto &SubDest = Sub.Dest;
234fe6060f1SDimitry Andric     YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second,
235fe6060f1SDimitry Andric                                               SubDest.first,
236fe6060f1SDimitry Andric                                               SubDest.second,
237fe6060f1SDimitry Andric                                               Sub.Subreg});
238fe6060f1SDimitry Andric   }
2390b57cec5SDimitry Andric   if (const auto *ConstantPool = MF.getConstantPool())
2400b57cec5SDimitry Andric     convert(YamlMF, *ConstantPool);
2410b57cec5SDimitry Andric   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
2420b57cec5SDimitry Andric     convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   const TargetMachine &TM = MF.getTarget();
2450b57cec5SDimitry Andric   YamlMF.MachineFuncInfo =
2460b57cec5SDimitry Andric       std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF));
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   raw_string_ostream StrOS(YamlMF.Body.Value.Value);
2490b57cec5SDimitry Andric   bool IsNewlineNeeded = false;
2500b57cec5SDimitry Andric   for (const auto &MBB : MF) {
2510b57cec5SDimitry Andric     if (IsNewlineNeeded)
2520b57cec5SDimitry Andric       StrOS << "\n";
2530b57cec5SDimitry Andric     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
2540b57cec5SDimitry Andric         .print(MBB);
2550b57cec5SDimitry Andric     IsNewlineNeeded = true;
2560b57cec5SDimitry Andric   }
2570b57cec5SDimitry Andric   StrOS.flush();
258fe6060f1SDimitry Andric   // Convert machine metadata collected during the print of the machine
259fe6060f1SDimitry Andric   // function.
260fe6060f1SDimitry Andric   convertMachineMetadataNodes(YamlMF, MF, MST);
261fe6060f1SDimitry Andric 
2620b57cec5SDimitry Andric   yaml::Output Out(OS);
2630b57cec5SDimitry Andric   if (!SimplifyMIR)
2640b57cec5SDimitry Andric       Out.setWriteDefaultValues(true);
2650b57cec5SDimitry Andric   Out << YamlMF;
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,
2690b57cec5SDimitry Andric                                const TargetRegisterInfo *TRI) {
2700b57cec5SDimitry Andric   assert(RegMask && "Can't print an empty register mask");
2710b57cec5SDimitry Andric   OS << StringRef("CustomRegMask(");
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   bool IsRegInRegMaskFound = false;
2740b57cec5SDimitry Andric   for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {
2750b57cec5SDimitry Andric     // Check whether the register is asserted in regmask.
2760b57cec5SDimitry Andric     if (RegMask[I / 32] & (1u << (I % 32))) {
2770b57cec5SDimitry Andric       if (IsRegInRegMaskFound)
2780b57cec5SDimitry Andric         OS << ',';
2790b57cec5SDimitry Andric       OS << printReg(I, TRI);
2800b57cec5SDimitry Andric       IsRegInRegMaskFound = true;
2810b57cec5SDimitry Andric     }
2820b57cec5SDimitry Andric   }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   OS << ')';
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest,
2880b57cec5SDimitry Andric                                 const MachineRegisterInfo &RegInfo,
2890b57cec5SDimitry Andric                                 const TargetRegisterInfo *TRI) {
2900b57cec5SDimitry Andric   raw_string_ostream OS(Dest.Value);
2910b57cec5SDimitry Andric   OS << printRegClassOrBank(Reg, RegInfo, TRI);
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric template <typename T>
2950b57cec5SDimitry Andric static void
2960b57cec5SDimitry Andric printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo &DebugVar,
2970b57cec5SDimitry Andric                         T &Object, ModuleSlotTracker &MST) {
2980b57cec5SDimitry Andric   std::array<std::string *, 3> Outputs{{&Object.DebugVar.Value,
2990b57cec5SDimitry Andric                                         &Object.DebugExpr.Value,
3000b57cec5SDimitry Andric                                         &Object.DebugLoc.Value}};
3010b57cec5SDimitry Andric   std::array<const Metadata *, 3> Metas{{DebugVar.Var,
3020b57cec5SDimitry Andric                                         DebugVar.Expr,
3030b57cec5SDimitry Andric                                         DebugVar.Loc}};
3040b57cec5SDimitry Andric   for (unsigned i = 0; i < 3; ++i) {
3050b57cec5SDimitry Andric     raw_string_ostream StrOS(*Outputs[i]);
3060b57cec5SDimitry Andric     Metas[i]->printAsOperand(StrOS, MST);
3070b57cec5SDimitry Andric   }
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric void MIRPrinter::convert(yaml::MachineFunction &MF,
3110b57cec5SDimitry Andric                          const MachineRegisterInfo &RegInfo,
3120b57cec5SDimitry Andric                          const TargetRegisterInfo *TRI) {
3130b57cec5SDimitry Andric   MF.TracksRegLiveness = RegInfo.tracksLiveness();
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   // Print the virtual register definitions.
3160b57cec5SDimitry Andric   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
317bdd1243dSDimitry Andric     Register Reg = Register::index2VirtReg(I);
3180b57cec5SDimitry Andric     yaml::VirtualRegisterDefinition VReg;
3190b57cec5SDimitry Andric     VReg.ID = I;
3200b57cec5SDimitry Andric     if (RegInfo.getVRegName(Reg) != "")
3210b57cec5SDimitry Andric       continue;
3220b57cec5SDimitry Andric     ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);
323bdd1243dSDimitry Andric     Register PreferredReg = RegInfo.getSimpleHint(Reg);
3240b57cec5SDimitry Andric     if (PreferredReg)
3250b57cec5SDimitry Andric       printRegMIR(PreferredReg, VReg.PreferredRegister, TRI);
3260b57cec5SDimitry Andric     MF.VirtualRegisters.push_back(VReg);
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric   // Print the live ins.
3300b57cec5SDimitry Andric   for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) {
3310b57cec5SDimitry Andric     yaml::MachineFunctionLiveIn LiveIn;
3320b57cec5SDimitry Andric     printRegMIR(LI.first, LiveIn.Register, TRI);
3330b57cec5SDimitry Andric     if (LI.second)
3340b57cec5SDimitry Andric       printRegMIR(LI.second, LiveIn.VirtualRegister, TRI);
3350b57cec5SDimitry Andric     MF.LiveIns.push_back(LiveIn);
3360b57cec5SDimitry Andric   }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   // Prints the callee saved registers.
3390b57cec5SDimitry Andric   if (RegInfo.isUpdatedCSRsInitialized()) {
3400b57cec5SDimitry Andric     const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
3410b57cec5SDimitry Andric     std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
3420b57cec5SDimitry Andric     for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
3430b57cec5SDimitry Andric       yaml::FlowStringValue Reg;
3440b57cec5SDimitry Andric       printRegMIR(*I, Reg, TRI);
3450b57cec5SDimitry Andric       CalleeSavedRegisters.push_back(Reg);
3460b57cec5SDimitry Andric     }
3470b57cec5SDimitry Andric     MF.CalleeSavedRegisters = CalleeSavedRegisters;
3480b57cec5SDimitry Andric   }
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric void MIRPrinter::convert(ModuleSlotTracker &MST,
3520b57cec5SDimitry Andric                          yaml::MachineFrameInfo &YamlMFI,
3530b57cec5SDimitry Andric                          const MachineFrameInfo &MFI) {
3540b57cec5SDimitry Andric   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
3550b57cec5SDimitry Andric   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
3560b57cec5SDimitry Andric   YamlMFI.HasStackMap = MFI.hasStackMap();
3570b57cec5SDimitry Andric   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
3580b57cec5SDimitry Andric   YamlMFI.StackSize = MFI.getStackSize();
3590b57cec5SDimitry Andric   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
3605ffd83dbSDimitry Andric   YamlMFI.MaxAlignment = MFI.getMaxAlign().value();
3610b57cec5SDimitry Andric   YamlMFI.AdjustsStack = MFI.adjustsStack();
3620b57cec5SDimitry Andric   YamlMFI.HasCalls = MFI.hasCalls();
3630b57cec5SDimitry Andric   YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()
3640b57cec5SDimitry Andric     ? MFI.getMaxCallFrameSize() : ~0u;
3650b57cec5SDimitry Andric   YamlMFI.CVBytesOfCalleeSavedRegisters =
3660b57cec5SDimitry Andric       MFI.getCVBytesOfCalleeSavedRegisters();
3670b57cec5SDimitry Andric   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
3680b57cec5SDimitry Andric   YamlMFI.HasVAStart = MFI.hasVAStart();
3690b57cec5SDimitry Andric   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
370fe6060f1SDimitry Andric   YamlMFI.HasTailCall = MFI.hasTailCall();
371*0fca6ea1SDimitry Andric   YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid();
3720b57cec5SDimitry Andric   YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();
3730b57cec5SDimitry Andric   if (MFI.getSavePoint()) {
3740b57cec5SDimitry Andric     raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
3750b57cec5SDimitry Andric     StrOS << printMBBReference(*MFI.getSavePoint());
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric   if (MFI.getRestorePoint()) {
3780b57cec5SDimitry Andric     raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
3790b57cec5SDimitry Andric     StrOS << printMBBReference(*MFI.getRestorePoint());
3800b57cec5SDimitry Andric   }
3810b57cec5SDimitry Andric }
3820b57cec5SDimitry Andric 
38306c3fb27SDimitry Andric void MIRPrinter::convertEntryValueObjects(yaml::MachineFunction &YMF,
38406c3fb27SDimitry Andric                                           const MachineFunction &MF,
38506c3fb27SDimitry Andric                                           ModuleSlotTracker &MST) {
38606c3fb27SDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
38706c3fb27SDimitry Andric   for (const MachineFunction::VariableDbgInfo &DebugVar :
38806c3fb27SDimitry Andric        MF.getEntryValueVariableDbgInfo()) {
38906c3fb27SDimitry Andric     yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back();
39006c3fb27SDimitry Andric     printStackObjectDbgInfo(DebugVar, Obj, MST);
39106c3fb27SDimitry Andric     MCRegister EntryValReg = DebugVar.getEntryValueRegister();
39206c3fb27SDimitry Andric     printRegMIR(EntryValReg, Obj.EntryValueRegister, TRI);
39306c3fb27SDimitry Andric   }
39406c3fb27SDimitry Andric }
39506c3fb27SDimitry Andric 
3960b57cec5SDimitry Andric void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
3970b57cec5SDimitry Andric                                      const MachineFunction &MF,
3980b57cec5SDimitry Andric                                      ModuleSlotTracker &MST) {
3990b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
4000b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
401e8d8bef9SDimitry Andric 
4020b57cec5SDimitry Andric   // Process fixed stack objects.
403e8d8bef9SDimitry Andric   assert(YMF.FixedStackObjects.empty());
404e8d8bef9SDimitry Andric   SmallVector<int, 32> FixedStackObjectsIdx;
405e8d8bef9SDimitry Andric   const int BeginIdx = MFI.getObjectIndexBegin();
406e8d8bef9SDimitry Andric   if (BeginIdx < 0)
407e8d8bef9SDimitry Andric     FixedStackObjectsIdx.reserve(-BeginIdx);
408e8d8bef9SDimitry Andric 
4090b57cec5SDimitry Andric   unsigned ID = 0;
410e8d8bef9SDimitry Andric   for (int I = BeginIdx; I < 0; ++I, ++ID) {
411e8d8bef9SDimitry Andric     FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.
4120b57cec5SDimitry Andric     if (MFI.isDeadObjectIndex(I))
4130b57cec5SDimitry Andric       continue;
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric     yaml::FixedMachineStackObject YamlObject;
4160b57cec5SDimitry Andric     YamlObject.ID = ID;
4170b57cec5SDimitry Andric     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
4180b57cec5SDimitry Andric                           ? yaml::FixedMachineStackObject::SpillSlot
4190b57cec5SDimitry Andric                           : yaml::FixedMachineStackObject::DefaultType;
4200b57cec5SDimitry Andric     YamlObject.Offset = MFI.getObjectOffset(I);
4210b57cec5SDimitry Andric     YamlObject.Size = MFI.getObjectSize(I);
4225ffd83dbSDimitry Andric     YamlObject.Alignment = MFI.getObjectAlign(I);
4230b57cec5SDimitry Andric     YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
4240b57cec5SDimitry Andric     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
4250b57cec5SDimitry Andric     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
426e8d8bef9SDimitry Andric     // Save the ID' position in FixedStackObjects storage vector.
427e8d8bef9SDimitry Andric     FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
4280b57cec5SDimitry Andric     YMF.FixedStackObjects.push_back(YamlObject);
4290b57cec5SDimitry Andric     StackObjectOperandMapping.insert(
4300b57cec5SDimitry Andric         std::make_pair(I, FrameIndexOperand::createFixed(ID)));
4310b57cec5SDimitry Andric   }
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric   // Process ordinary stack objects.
434e8d8bef9SDimitry Andric   assert(YMF.StackObjects.empty());
435e8d8bef9SDimitry Andric   SmallVector<unsigned, 32> StackObjectsIdx;
436e8d8bef9SDimitry Andric   const int EndIdx = MFI.getObjectIndexEnd();
437e8d8bef9SDimitry Andric   if (EndIdx > 0)
438e8d8bef9SDimitry Andric     StackObjectsIdx.reserve(EndIdx);
4390b57cec5SDimitry Andric   ID = 0;
440e8d8bef9SDimitry Andric   for (int I = 0; I < EndIdx; ++I, ++ID) {
441e8d8bef9SDimitry Andric     StackObjectsIdx.push_back(-1); // Fill index for possible dead.
4420b57cec5SDimitry Andric     if (MFI.isDeadObjectIndex(I))
4430b57cec5SDimitry Andric       continue;
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric     yaml::MachineStackObject YamlObject;
4460b57cec5SDimitry Andric     YamlObject.ID = ID;
4470b57cec5SDimitry Andric     if (const auto *Alloca = MFI.getObjectAllocation(I))
4485ffd83dbSDimitry Andric       YamlObject.Name.Value = std::string(
449e8d8bef9SDimitry Andric           Alloca->hasName() ? Alloca->getName() : "");
4500b57cec5SDimitry Andric     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
4510b57cec5SDimitry Andric                           ? yaml::MachineStackObject::SpillSlot
4520b57cec5SDimitry Andric                           : MFI.isVariableSizedObjectIndex(I)
4530b57cec5SDimitry Andric                                 ? yaml::MachineStackObject::VariableSized
4540b57cec5SDimitry Andric                                 : yaml::MachineStackObject::DefaultType;
4550b57cec5SDimitry Andric     YamlObject.Offset = MFI.getObjectOffset(I);
4560b57cec5SDimitry Andric     YamlObject.Size = MFI.getObjectSize(I);
4575ffd83dbSDimitry Andric     YamlObject.Alignment = MFI.getObjectAlign(I);
4580b57cec5SDimitry Andric     YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
4590b57cec5SDimitry Andric 
460e8d8bef9SDimitry Andric     // Save the ID' position in StackObjects storage vector.
461e8d8bef9SDimitry Andric     StackObjectsIdx[ID] = YMF.StackObjects.size();
4620b57cec5SDimitry Andric     YMF.StackObjects.push_back(YamlObject);
4630b57cec5SDimitry Andric     StackObjectOperandMapping.insert(std::make_pair(
4640b57cec5SDimitry Andric         I, FrameIndexOperand::create(YamlObject.Name.Value, ID)));
4650b57cec5SDimitry Andric   }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
468e8d8bef9SDimitry Andric     const int FrameIdx = CSInfo.getFrameIdx();
469e8d8bef9SDimitry Andric     if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))
4700b57cec5SDimitry Andric       continue;
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric     yaml::StringValue Reg;
4730b57cec5SDimitry Andric     printRegMIR(CSInfo.getReg(), Reg, TRI);
4740b57cec5SDimitry Andric     if (!CSInfo.isSpilledToReg()) {
475e8d8bef9SDimitry Andric       assert(FrameIdx >= MFI.getObjectIndexBegin() &&
476e8d8bef9SDimitry Andric              FrameIdx < MFI.getObjectIndexEnd() &&
4770b57cec5SDimitry Andric              "Invalid stack object index");
478e8d8bef9SDimitry Andric       if (FrameIdx < 0) { // Negative index means fixed objects.
479e8d8bef9SDimitry Andric         auto &Object =
480e8d8bef9SDimitry Andric             YMF.FixedStackObjects
481e8d8bef9SDimitry Andric                 [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
482e8d8bef9SDimitry Andric         Object.CalleeSavedRegister = Reg;
483e8d8bef9SDimitry Andric         Object.CalleeSavedRestored = CSInfo.isRestored();
4840b57cec5SDimitry Andric       } else {
485e8d8bef9SDimitry Andric         auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
486e8d8bef9SDimitry Andric         Object.CalleeSavedRegister = Reg;
487e8d8bef9SDimitry Andric         Object.CalleeSavedRestored = CSInfo.isRestored();
4880b57cec5SDimitry Andric       }
4890b57cec5SDimitry Andric     }
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric   for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
4920b57cec5SDimitry Andric     auto LocalObject = MFI.getLocalFrameObjectMap(I);
493e8d8bef9SDimitry Andric     assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
494e8d8bef9SDimitry Andric     YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
495e8d8bef9SDimitry Andric         LocalObject.second;
4960b57cec5SDimitry Andric   }
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   // Print the stack object references in the frame information class after
4990b57cec5SDimitry Andric   // converting the stack objects.
5000b57cec5SDimitry Andric   if (MFI.hasStackProtectorIndex()) {
5010b57cec5SDimitry Andric     raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);
5020b57cec5SDimitry Andric     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
5030b57cec5SDimitry Andric         .printStackObjectReference(MFI.getStackProtectorIndex());
5040b57cec5SDimitry Andric   }
5050b57cec5SDimitry Andric 
50681ad6265SDimitry Andric   if (MFI.hasFunctionContextIndex()) {
50781ad6265SDimitry Andric     raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value);
50881ad6265SDimitry Andric     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
50981ad6265SDimitry Andric         .printStackObjectReference(MFI.getFunctionContextIndex());
51081ad6265SDimitry Andric   }
51181ad6265SDimitry Andric 
5120b57cec5SDimitry Andric   // Print the debug variable information.
5130b57cec5SDimitry Andric   for (const MachineFunction::VariableDbgInfo &DebugVar :
51406c3fb27SDimitry Andric        MF.getInStackSlotVariableDbgInfo()) {
51506c3fb27SDimitry Andric     int Idx = DebugVar.getStackSlot();
51606c3fb27SDimitry Andric     assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() &&
5170b57cec5SDimitry Andric            "Invalid stack object index");
51806c3fb27SDimitry Andric     if (Idx < 0) { // Negative index means fixed objects.
519e8d8bef9SDimitry Andric       auto &Object =
52006c3fb27SDimitry Andric           YMF.FixedStackObjects[FixedStackObjectsIdx[Idx +
521e8d8bef9SDimitry Andric                                                      MFI.getNumFixedObjects()]];
5220b57cec5SDimitry Andric       printStackObjectDbgInfo(DebugVar, Object, MST);
5230b57cec5SDimitry Andric     } else {
52406c3fb27SDimitry Andric       auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]];
5250b57cec5SDimitry Andric       printStackObjectDbgInfo(DebugVar, Object, MST);
5260b57cec5SDimitry Andric     }
5270b57cec5SDimitry Andric   }
5280b57cec5SDimitry Andric }
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
5310b57cec5SDimitry Andric                                         const MachineFunction &MF,
5320b57cec5SDimitry Andric                                         ModuleSlotTracker &MST) {
5330b57cec5SDimitry Andric   const auto *TRI = MF.getSubtarget().getRegisterInfo();
5340b57cec5SDimitry Andric   for (auto CSInfo : MF.getCallSitesInfo()) {
5350b57cec5SDimitry Andric     yaml::CallSiteInfo YmlCS;
5360b57cec5SDimitry Andric     yaml::CallSiteInfo::MachineInstrLoc CallLocation;
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric     // Prepare instruction position.
5398bcb0991SDimitry Andric     MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator();
5400b57cec5SDimitry Andric     CallLocation.BlockNum = CallI->getParent()->getNumber();
5410b57cec5SDimitry Andric     // Get call instruction offset from the beginning of block.
5428bcb0991SDimitry Andric     CallLocation.Offset =
5438bcb0991SDimitry Andric         std::distance(CallI->getParent()->instr_begin(), CallI);
5440b57cec5SDimitry Andric     YmlCS.CallLocation = CallLocation;
5450b57cec5SDimitry Andric     // Construct call arguments and theirs forwarding register info.
546*0fca6ea1SDimitry Andric     for (auto ArgReg : CSInfo.second.ArgRegPairs) {
5470b57cec5SDimitry Andric       yaml::CallSiteInfo::ArgRegPair YmlArgReg;
5480b57cec5SDimitry Andric       YmlArgReg.ArgNo = ArgReg.ArgNo;
5490b57cec5SDimitry Andric       printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
5500b57cec5SDimitry Andric       YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
5510b57cec5SDimitry Andric     }
5520b57cec5SDimitry Andric     YMF.CallSitesInfo.push_back(YmlCS);
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   // Sort call info by position of call instructions.
5560b57cec5SDimitry Andric   llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(),
5570b57cec5SDimitry Andric              [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {
5580b57cec5SDimitry Andric                if (A.CallLocation.BlockNum == B.CallLocation.BlockNum)
5590b57cec5SDimitry Andric                  return A.CallLocation.Offset < B.CallLocation.Offset;
5600b57cec5SDimitry Andric                return A.CallLocation.BlockNum < B.CallLocation.BlockNum;
5610b57cec5SDimitry Andric              });
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
564fe6060f1SDimitry Andric void MIRPrinter::convertMachineMetadataNodes(yaml::MachineFunction &YMF,
565fe6060f1SDimitry Andric                                              const MachineFunction &MF,
566fe6060f1SDimitry Andric                                              MachineModuleSlotTracker &MST) {
567fe6060f1SDimitry Andric   MachineModuleSlotTracker::MachineMDNodeListType MDList;
568fe6060f1SDimitry Andric   MST.collectMachineMDNodes(MDList);
569fe6060f1SDimitry Andric   for (auto &MD : MDList) {
570fe6060f1SDimitry Andric     std::string NS;
571fe6060f1SDimitry Andric     raw_string_ostream StrOS(NS);
572fe6060f1SDimitry Andric     MD.second->print(StrOS, MST, MF.getFunction().getParent());
573*0fca6ea1SDimitry Andric     YMF.MachineMetadataNodes.push_back(NS);
574fe6060f1SDimitry Andric   }
575fe6060f1SDimitry Andric }
576fe6060f1SDimitry Andric 
5770b57cec5SDimitry Andric void MIRPrinter::convert(yaml::MachineFunction &MF,
5780b57cec5SDimitry Andric                          const MachineConstantPool &ConstantPool) {
5790b57cec5SDimitry Andric   unsigned ID = 0;
5800b57cec5SDimitry Andric   for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
5810b57cec5SDimitry Andric     std::string Str;
5820b57cec5SDimitry Andric     raw_string_ostream StrOS(Str);
5830b57cec5SDimitry Andric     if (Constant.isMachineConstantPoolEntry()) {
5840b57cec5SDimitry Andric       Constant.Val.MachineCPVal->print(StrOS);
5850b57cec5SDimitry Andric     } else {
5860b57cec5SDimitry Andric       Constant.Val.ConstVal->printAsOperand(StrOS);
5870b57cec5SDimitry Andric     }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric     yaml::MachineConstantPoolValue YamlConstant;
5900b57cec5SDimitry Andric     YamlConstant.ID = ID++;
591*0fca6ea1SDimitry Andric     YamlConstant.Value = Str;
5925ffd83dbSDimitry Andric     YamlConstant.Alignment = Constant.getAlign();
5930b57cec5SDimitry Andric     YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric     MF.Constants.push_back(YamlConstant);
5960b57cec5SDimitry Andric   }
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric void MIRPrinter::convert(ModuleSlotTracker &MST,
6000b57cec5SDimitry Andric                          yaml::MachineJumpTable &YamlJTI,
6010b57cec5SDimitry Andric                          const MachineJumpTableInfo &JTI) {
6020b57cec5SDimitry Andric   YamlJTI.Kind = JTI.getEntryKind();
6030b57cec5SDimitry Andric   unsigned ID = 0;
6040b57cec5SDimitry Andric   for (const auto &Table : JTI.getJumpTables()) {
6050b57cec5SDimitry Andric     std::string Str;
6060b57cec5SDimitry Andric     yaml::MachineJumpTable::Entry Entry;
6070b57cec5SDimitry Andric     Entry.ID = ID++;
6080b57cec5SDimitry Andric     for (const auto *MBB : Table.MBBs) {
6090b57cec5SDimitry Andric       raw_string_ostream StrOS(Str);
6100b57cec5SDimitry Andric       StrOS << printMBBReference(*MBB);
611*0fca6ea1SDimitry Andric       Entry.Blocks.push_back(Str);
6120b57cec5SDimitry Andric       Str.clear();
6130b57cec5SDimitry Andric     }
6140b57cec5SDimitry Andric     YamlJTI.Entries.push_back(Entry);
6150b57cec5SDimitry Andric   }
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
6190b57cec5SDimitry Andric   const auto *TRI = MF.getSubtarget().getRegisterInfo();
6200b57cec5SDimitry Andric   unsigned I = 0;
6210b57cec5SDimitry Andric   for (const uint32_t *Mask : TRI->getRegMasks())
6220b57cec5SDimitry Andric     RegisterMaskIds.insert(std::make_pair(Mask, I++));
6230b57cec5SDimitry Andric }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric void llvm::guessSuccessors(const MachineBasicBlock &MBB,
6260b57cec5SDimitry Andric                            SmallVectorImpl<MachineBasicBlock*> &Result,
6270b57cec5SDimitry Andric                            bool &IsFallthrough) {
6280b57cec5SDimitry Andric   SmallPtrSet<MachineBasicBlock*,8> Seen;
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric   for (const MachineInstr &MI : MBB) {
6310b57cec5SDimitry Andric     if (MI.isPHI())
6320b57cec5SDimitry Andric       continue;
6330b57cec5SDimitry Andric     for (const MachineOperand &MO : MI.operands()) {
6340b57cec5SDimitry Andric       if (!MO.isMBB())
6350b57cec5SDimitry Andric         continue;
6360b57cec5SDimitry Andric       MachineBasicBlock *Succ = MO.getMBB();
6370b57cec5SDimitry Andric       auto RP = Seen.insert(Succ);
6380b57cec5SDimitry Andric       if (RP.second)
6390b57cec5SDimitry Andric         Result.push_back(Succ);
6400b57cec5SDimitry Andric     }
6410b57cec5SDimitry Andric   }
6420b57cec5SDimitry Andric   MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
6430b57cec5SDimitry Andric   IsFallthrough = I == MBB.end() || !I->isBarrier();
6440b57cec5SDimitry Andric }
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric bool
6470b57cec5SDimitry Andric MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const {
6480b57cec5SDimitry Andric   if (MBB.succ_size() <= 1)
6490b57cec5SDimitry Andric     return true;
6500b57cec5SDimitry Andric   if (!MBB.hasSuccessorProbabilities())
6510b57cec5SDimitry Andric     return true;
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric   SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(),
6540b57cec5SDimitry Andric                                               MBB.Probs.end());
6550b57cec5SDimitry Andric   BranchProbability::normalizeProbabilities(Normalized.begin(),
6560b57cec5SDimitry Andric                                             Normalized.end());
6570b57cec5SDimitry Andric   SmallVector<BranchProbability,8> Equal(Normalized.size());
6580b57cec5SDimitry Andric   BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end());
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   return std::equal(Normalized.begin(), Normalized.end(), Equal.begin());
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const {
6640b57cec5SDimitry Andric   SmallVector<MachineBasicBlock*,8> GuessedSuccs;
6650b57cec5SDimitry Andric   bool GuessedFallthrough;
6660b57cec5SDimitry Andric   guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough);
6670b57cec5SDimitry Andric   if (GuessedFallthrough) {
6680b57cec5SDimitry Andric     const MachineFunction &MF = *MBB.getParent();
6690b57cec5SDimitry Andric     MachineFunction::const_iterator NextI = std::next(MBB.getIterator());
6700b57cec5SDimitry Andric     if (NextI != MF.end()) {
6710b57cec5SDimitry Andric       MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);
6720b57cec5SDimitry Andric       if (!is_contained(GuessedSuccs, Next))
6730b57cec5SDimitry Andric         GuessedSuccs.push_back(Next);
6740b57cec5SDimitry Andric     }
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric   if (GuessedSuccs.size() != MBB.succ_size())
6770b57cec5SDimitry Andric     return false;
6780b57cec5SDimitry Andric   return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin());
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric void MIPrinter::print(const MachineBasicBlock &MBB) {
6820b57cec5SDimitry Andric   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
683e8d8bef9SDimitry Andric   MBB.printName(OS,
684e8d8bef9SDimitry Andric                 MachineBasicBlock::PrintNameIr |
685e8d8bef9SDimitry Andric                     MachineBasicBlock::PrintNameAttributes,
686e8d8bef9SDimitry Andric                 &MST);
6870b57cec5SDimitry Andric   OS << ":\n";
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   bool HasLineAttributes = false;
6900b57cec5SDimitry Andric   // Print the successors
6910b57cec5SDimitry Andric   bool canPredictProbs = canPredictBranchProbabilities(MBB);
6920b57cec5SDimitry Andric   // Even if the list of successors is empty, if we cannot guess it,
6930b57cec5SDimitry Andric   // we need to print it to tell the parser that the list is empty.
6940b57cec5SDimitry Andric   // This is needed, because MI model unreachable as empty blocks
6950b57cec5SDimitry Andric   // with an empty successor list. If the parser would see that
6960b57cec5SDimitry Andric   // without the successor list, it would guess the code would
6970b57cec5SDimitry Andric   // fallthrough.
6980b57cec5SDimitry Andric   if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||
6990b57cec5SDimitry Andric       !canPredictSuccessors(MBB)) {
7000b57cec5SDimitry Andric     OS.indent(2) << "successors:";
701*0fca6ea1SDimitry Andric     if (!MBB.succ_empty())
702*0fca6ea1SDimitry Andric       OS << " ";
7030b57cec5SDimitry Andric     for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
7040b57cec5SDimitry Andric       if (I != MBB.succ_begin())
7050b57cec5SDimitry Andric         OS << ", ";
7060b57cec5SDimitry Andric       OS << printMBBReference(**I);
7070b57cec5SDimitry Andric       if (!SimplifyMIR || !canPredictProbs)
7080b57cec5SDimitry Andric         OS << '('
7090b57cec5SDimitry Andric            << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator())
7100b57cec5SDimitry Andric            << ')';
7110b57cec5SDimitry Andric     }
7120b57cec5SDimitry Andric     OS << "\n";
7130b57cec5SDimitry Andric     HasLineAttributes = true;
7140b57cec5SDimitry Andric   }
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric   // Print the live in registers.
7170b57cec5SDimitry Andric   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
71881ad6265SDimitry Andric   if (!MBB.livein_empty()) {
7190b57cec5SDimitry Andric     const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
7200b57cec5SDimitry Andric     OS.indent(2) << "liveins: ";
7210b57cec5SDimitry Andric     bool First = true;
72281ad6265SDimitry Andric     for (const auto &LI : MBB.liveins_dbg()) {
7230b57cec5SDimitry Andric       if (!First)
7240b57cec5SDimitry Andric         OS << ", ";
7250b57cec5SDimitry Andric       First = false;
7260b57cec5SDimitry Andric       OS << printReg(LI.PhysReg, &TRI);
7270b57cec5SDimitry Andric       if (!LI.LaneMask.all())
7280b57cec5SDimitry Andric         OS << ":0x" << PrintLaneMask(LI.LaneMask);
7290b57cec5SDimitry Andric     }
7300b57cec5SDimitry Andric     OS << "\n";
7310b57cec5SDimitry Andric     HasLineAttributes = true;
7320b57cec5SDimitry Andric   }
7330b57cec5SDimitry Andric 
734*0fca6ea1SDimitry Andric   if (HasLineAttributes && !MBB.empty())
7350b57cec5SDimitry Andric     OS << "\n";
7360b57cec5SDimitry Andric   bool IsInBundle = false;
737*0fca6ea1SDimitry Andric   for (const MachineInstr &MI : MBB.instrs()) {
7380b57cec5SDimitry Andric     if (IsInBundle && !MI.isInsideBundle()) {
7390b57cec5SDimitry Andric       OS.indent(2) << "}\n";
7400b57cec5SDimitry Andric       IsInBundle = false;
7410b57cec5SDimitry Andric     }
7420b57cec5SDimitry Andric     OS.indent(IsInBundle ? 4 : 2);
7430b57cec5SDimitry Andric     print(MI);
7440b57cec5SDimitry Andric     if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
7450b57cec5SDimitry Andric       OS << " {";
7460b57cec5SDimitry Andric       IsInBundle = true;
7470b57cec5SDimitry Andric     }
7480b57cec5SDimitry Andric     OS << "\n";
7490b57cec5SDimitry Andric   }
7500b57cec5SDimitry Andric   if (IsInBundle)
7510b57cec5SDimitry Andric     OS.indent(2) << "}\n";
7520b57cec5SDimitry Andric }
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric void MIPrinter::print(const MachineInstr &MI) {
7550b57cec5SDimitry Andric   const auto *MF = MI.getMF();
7560b57cec5SDimitry Andric   const auto &MRI = MF->getRegInfo();
7570b57cec5SDimitry Andric   const auto &SubTarget = MF->getSubtarget();
7580b57cec5SDimitry Andric   const auto *TRI = SubTarget.getRegisterInfo();
7590b57cec5SDimitry Andric   assert(TRI && "Expected target register info");
7600b57cec5SDimitry Andric   const auto *TII = SubTarget.getInstrInfo();
7610b57cec5SDimitry Andric   assert(TII && "Expected target instruction info");
7620b57cec5SDimitry Andric   if (MI.isCFIInstruction())
7630b57cec5SDimitry Andric     assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric   SmallBitVector PrintedTypes(8);
7660b57cec5SDimitry Andric   bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();
7670b57cec5SDimitry Andric   unsigned I = 0, E = MI.getNumOperands();
7680b57cec5SDimitry Andric   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
7690b57cec5SDimitry Andric          !MI.getOperand(I).isImplicit();
7700b57cec5SDimitry Andric        ++I) {
7710b57cec5SDimitry Andric     if (I)
7720b57cec5SDimitry Andric       OS << ", ";
7735ffd83dbSDimitry Andric     print(MI, I, TRI, TII, ShouldPrintRegisterTies,
7740b57cec5SDimitry Andric           MI.getTypeToPrint(I, PrintedTypes, MRI),
7750b57cec5SDimitry Andric           /*PrintDef=*/false);
7760b57cec5SDimitry Andric   }
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric   if (I)
7790b57cec5SDimitry Andric     OS << " = ";
7800b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FrameSetup))
7810b57cec5SDimitry Andric     OS << "frame-setup ";
7820b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FrameDestroy))
7830b57cec5SDimitry Andric     OS << "frame-destroy ";
7840b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmNoNans))
7850b57cec5SDimitry Andric     OS << "nnan ";
7860b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmNoInfs))
7870b57cec5SDimitry Andric     OS << "ninf ";
7880b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmNsz))
7890b57cec5SDimitry Andric     OS << "nsz ";
7900b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmArcp))
7910b57cec5SDimitry Andric     OS << "arcp ";
7920b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmContract))
7930b57cec5SDimitry Andric     OS << "contract ";
7940b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmAfn))
7950b57cec5SDimitry Andric     OS << "afn ";
7960b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::FmReassoc))
7970b57cec5SDimitry Andric     OS << "reassoc ";
7980b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::NoUWrap))
7990b57cec5SDimitry Andric     OS << "nuw ";
8000b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::NoSWrap))
8010b57cec5SDimitry Andric     OS << "nsw ";
8020b57cec5SDimitry Andric   if (MI.getFlag(MachineInstr::IsExact))
8030b57cec5SDimitry Andric     OS << "exact ";
804480093f4SDimitry Andric   if (MI.getFlag(MachineInstr::NoFPExcept))
805480093f4SDimitry Andric     OS << "nofpexcept ";
8065ffd83dbSDimitry Andric   if (MI.getFlag(MachineInstr::NoMerge))
8075ffd83dbSDimitry Andric     OS << "nomerge ";
80806c3fb27SDimitry Andric   if (MI.getFlag(MachineInstr::Unpredictable))
80906c3fb27SDimitry Andric     OS << "unpredictable ";
8105f757f3fSDimitry Andric   if (MI.getFlag(MachineInstr::NoConvergent))
8115f757f3fSDimitry Andric     OS << "noconvergent ";
812*0fca6ea1SDimitry Andric   if (MI.getFlag(MachineInstr::NonNeg))
813*0fca6ea1SDimitry Andric     OS << "nneg ";
814*0fca6ea1SDimitry Andric   if (MI.getFlag(MachineInstr::Disjoint))
815*0fca6ea1SDimitry Andric     OS << "disjoint ";
816*0fca6ea1SDimitry Andric   if (MI.getFlag(MachineInstr::NoUSWrap))
817*0fca6ea1SDimitry Andric     OS << "nusw ";
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   OS << TII->getName(MI.getOpcode());
8200b57cec5SDimitry Andric   if (I < E)
8210b57cec5SDimitry Andric     OS << ' ';
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   bool NeedComma = false;
8240b57cec5SDimitry Andric   for (; I < E; ++I) {
8250b57cec5SDimitry Andric     if (NeedComma)
8260b57cec5SDimitry Andric       OS << ", ";
8275ffd83dbSDimitry Andric     print(MI, I, TRI, TII, ShouldPrintRegisterTies,
8280b57cec5SDimitry Andric           MI.getTypeToPrint(I, PrintedTypes, MRI));
8290b57cec5SDimitry Andric     NeedComma = true;
8300b57cec5SDimitry Andric   }
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric   // Print any optional symbols attached to this instruction as-if they were
8330b57cec5SDimitry Andric   // operands.
8340b57cec5SDimitry Andric   if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {
8350b57cec5SDimitry Andric     if (NeedComma)
8360b57cec5SDimitry Andric       OS << ',';
8370b57cec5SDimitry Andric     OS << " pre-instr-symbol ";
8380b57cec5SDimitry Andric     MachineOperand::printSymbol(OS, *PreInstrSymbol);
8390b57cec5SDimitry Andric     NeedComma = true;
8400b57cec5SDimitry Andric   }
8410b57cec5SDimitry Andric   if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {
8420b57cec5SDimitry Andric     if (NeedComma)
8430b57cec5SDimitry Andric       OS << ',';
8440b57cec5SDimitry Andric     OS << " post-instr-symbol ";
8450b57cec5SDimitry Andric     MachineOperand::printSymbol(OS, *PostInstrSymbol);
8460b57cec5SDimitry Andric     NeedComma = true;
8470b57cec5SDimitry Andric   }
848480093f4SDimitry Andric   if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) {
849480093f4SDimitry Andric     if (NeedComma)
850480093f4SDimitry Andric       OS << ',';
851480093f4SDimitry Andric     OS << " heap-alloc-marker ";
852480093f4SDimitry Andric     HeapAllocMarker->printAsOperand(OS, MST);
853480093f4SDimitry Andric     NeedComma = true;
854480093f4SDimitry Andric   }
855bdd1243dSDimitry Andric   if (MDNode *PCSections = MI.getPCSections()) {
856bdd1243dSDimitry Andric     if (NeedComma)
857bdd1243dSDimitry Andric       OS << ',';
858bdd1243dSDimitry Andric     OS << " pcsections ";
859bdd1243dSDimitry Andric     PCSections->printAsOperand(OS, MST);
860bdd1243dSDimitry Andric     NeedComma = true;
861bdd1243dSDimitry Andric   }
862*0fca6ea1SDimitry Andric   if (MDNode *MMRA = MI.getMMRAMetadata()) {
863*0fca6ea1SDimitry Andric     if (NeedComma)
864*0fca6ea1SDimitry Andric       OS << ',';
865*0fca6ea1SDimitry Andric     OS << " mmra ";
866*0fca6ea1SDimitry Andric     MMRA->printAsOperand(OS, MST);
867*0fca6ea1SDimitry Andric     NeedComma = true;
868*0fca6ea1SDimitry Andric   }
869bdd1243dSDimitry Andric   if (uint32_t CFIType = MI.getCFIType()) {
870bdd1243dSDimitry Andric     if (NeedComma)
871bdd1243dSDimitry Andric       OS << ',';
872bdd1243dSDimitry Andric     OS << " cfi-type " << CFIType;
873bdd1243dSDimitry Andric     NeedComma = true;
874bdd1243dSDimitry Andric   }
8750b57cec5SDimitry Andric 
876e8d8bef9SDimitry Andric   if (auto Num = MI.peekDebugInstrNum()) {
877e8d8bef9SDimitry Andric     if (NeedComma)
878e8d8bef9SDimitry Andric       OS << ',';
879e8d8bef9SDimitry Andric     OS << " debug-instr-number " << Num;
880e8d8bef9SDimitry Andric     NeedComma = true;
881e8d8bef9SDimitry Andric   }
882e8d8bef9SDimitry Andric 
8835ffd83dbSDimitry Andric   if (PrintLocations) {
8840b57cec5SDimitry Andric     if (const DebugLoc &DL = MI.getDebugLoc()) {
8850b57cec5SDimitry Andric       if (NeedComma)
8860b57cec5SDimitry Andric         OS << ',';
8870b57cec5SDimitry Andric       OS << " debug-location ";
8880b57cec5SDimitry Andric       DL->printAsOperand(OS, MST);
8890b57cec5SDimitry Andric     }
8905ffd83dbSDimitry Andric   }
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   if (!MI.memoperands_empty()) {
8930b57cec5SDimitry Andric     OS << " :: ";
8940b57cec5SDimitry Andric     const LLVMContext &Context = MF->getFunction().getContext();
8950b57cec5SDimitry Andric     const MachineFrameInfo &MFI = MF->getFrameInfo();
8960b57cec5SDimitry Andric     bool NeedComma = false;
8970b57cec5SDimitry Andric     for (const auto *Op : MI.memoperands()) {
8980b57cec5SDimitry Andric       if (NeedComma)
8990b57cec5SDimitry Andric         OS << ", ";
9000b57cec5SDimitry Andric       Op->print(OS, MST, SSNs, Context, &MFI, TII);
9010b57cec5SDimitry Andric       NeedComma = true;
9020b57cec5SDimitry Andric     }
9030b57cec5SDimitry Andric   }
9040b57cec5SDimitry Andric }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric void MIPrinter::printStackObjectReference(int FrameIndex) {
9070b57cec5SDimitry Andric   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
9080b57cec5SDimitry Andric   assert(ObjectInfo != StackObjectOperandMapping.end() &&
9090b57cec5SDimitry Andric          "Invalid frame index");
9100b57cec5SDimitry Andric   const FrameIndexOperand &Operand = ObjectInfo->second;
9110b57cec5SDimitry Andric   MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed,
9120b57cec5SDimitry Andric                                             Operand.Name);
9130b57cec5SDimitry Andric }
9140b57cec5SDimitry Andric 
9155ffd83dbSDimitry Andric static std::string formatOperandComment(std::string Comment) {
9165ffd83dbSDimitry Andric   if (Comment.empty())
9175ffd83dbSDimitry Andric     return Comment;
9185ffd83dbSDimitry Andric   return std::string(" /* " + Comment + " */");
9195ffd83dbSDimitry Andric }
9205ffd83dbSDimitry Andric 
9210b57cec5SDimitry Andric void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
9220b57cec5SDimitry Andric                       const TargetRegisterInfo *TRI,
9235ffd83dbSDimitry Andric                       const TargetInstrInfo *TII,
9240b57cec5SDimitry Andric                       bool ShouldPrintRegisterTies, LLT TypeToPrint,
9250b57cec5SDimitry Andric                       bool PrintDef) {
9260b57cec5SDimitry Andric   const MachineOperand &Op = MI.getOperand(OpIdx);
9275ffd83dbSDimitry Andric   std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx, TRI);
9285ffd83dbSDimitry Andric 
9290b57cec5SDimitry Andric   switch (Op.getType()) {
9300b57cec5SDimitry Andric   case MachineOperand::MO_Immediate:
9310b57cec5SDimitry Andric     if (MI.isOperandSubregIdx(OpIdx)) {
9320b57cec5SDimitry Andric       MachineOperand::printTargetFlags(OS, Op);
9330b57cec5SDimitry Andric       MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI);
9340b57cec5SDimitry Andric       break;
9350b57cec5SDimitry Andric     }
936bdd1243dSDimitry Andric     [[fallthrough]];
9370b57cec5SDimitry Andric   case MachineOperand::MO_Register:
9380b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
9390b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
9400b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
9410b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
9420b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex:
9430b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
9440b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
9450b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
9460b57cec5SDimitry Andric   case MachineOperand::MO_RegisterLiveOut:
9470b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
9480b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
9490b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex:
9500b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID:
9510b57cec5SDimitry Andric   case MachineOperand::MO_Predicate:
9528bcb0991SDimitry Andric   case MachineOperand::MO_BlockAddress:
953bdd1243dSDimitry Andric   case MachineOperand::MO_DbgInstrRef:
9548bcb0991SDimitry Andric   case MachineOperand::MO_ShuffleMask: {
9550b57cec5SDimitry Andric     unsigned TiedOperandIdx = 0;
9560b57cec5SDimitry Andric     if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
9570b57cec5SDimitry Andric       TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
9580b57cec5SDimitry Andric     const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo();
959480093f4SDimitry Andric     Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false,
9600b57cec5SDimitry Andric              ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII);
9615ffd83dbSDimitry Andric       OS << formatOperandComment(MOComment);
9620b57cec5SDimitry Andric     break;
9630b57cec5SDimitry Andric   }
9640b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex:
9650b57cec5SDimitry Andric     printStackObjectReference(Op.getIndex());
9660b57cec5SDimitry Andric     break;
9670b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask: {
9680b57cec5SDimitry Andric     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
9690b57cec5SDimitry Andric     if (RegMaskInfo != RegisterMaskIds.end())
9700b57cec5SDimitry Andric       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
9710b57cec5SDimitry Andric     else
9720b57cec5SDimitry Andric       printCustomRegMask(Op.getRegMask(), OS, TRI);
9730b57cec5SDimitry Andric     break;
9740b57cec5SDimitry Andric   }
9750b57cec5SDimitry Andric   }
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric 
978480093f4SDimitry Andric void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
979480093f4SDimitry Andric                                 ModuleSlotTracker &MST) {
980480093f4SDimitry Andric   if (isa<GlobalValue>(V)) {
981480093f4SDimitry Andric     V.printAsOperand(OS, /*PrintType=*/false, MST);
982480093f4SDimitry Andric     return;
983480093f4SDimitry Andric   }
984480093f4SDimitry Andric   if (isa<Constant>(V)) {
985480093f4SDimitry Andric     // Machine memory operands can load/store to/from constant value pointers.
986480093f4SDimitry Andric     OS << '`';
987480093f4SDimitry Andric     V.printAsOperand(OS, /*PrintType=*/true, MST);
988480093f4SDimitry Andric     OS << '`';
989480093f4SDimitry Andric     return;
990480093f4SDimitry Andric   }
991480093f4SDimitry Andric   OS << "%ir.";
992480093f4SDimitry Andric   if (V.hasName()) {
993480093f4SDimitry Andric     printLLVMNameWithoutPrefix(OS, V.getName());
994480093f4SDimitry Andric     return;
995480093f4SDimitry Andric   }
996480093f4SDimitry Andric   int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1;
997480093f4SDimitry Andric   MachineOperand::printIRSlotNumber(OS, Slot);
998480093f4SDimitry Andric }
999480093f4SDimitry Andric 
10000b57cec5SDimitry Andric void llvm::printMIR(raw_ostream &OS, const Module &M) {
1001*0fca6ea1SDimitry Andric   ScopedDbgInfoFormatSetter FormatSetter(const_cast<Module &>(M),
1002*0fca6ea1SDimitry Andric                                          WriteNewDbgInfoFormat);
10035f757f3fSDimitry Andric 
10040b57cec5SDimitry Andric   yaml::Output Out(OS);
10050b57cec5SDimitry Andric   Out << const_cast<Module &>(M);
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
1009*0fca6ea1SDimitry Andric   // RemoveDIs: as there's no textual form for DbgRecords yet, print debug-info
10105f757f3fSDimitry Andric   // in dbg.value format.
1011*0fca6ea1SDimitry Andric   ScopedDbgInfoFormatSetter FormatSetter(
1012*0fca6ea1SDimitry Andric       const_cast<Function &>(MF.getFunction()), WriteNewDbgInfoFormat);
10135f757f3fSDimitry Andric 
10140b57cec5SDimitry Andric   MIRPrinter Printer(OS);
10150b57cec5SDimitry Andric   Printer.print(MF);
10160b57cec5SDimitry Andric }
1017