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