13a0822f0SDimitry Andric //===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
23a0822f0SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63a0822f0SDimitry Andric //
73a0822f0SDimitry Andric //===----------------------------------------------------------------------===//
83a0822f0SDimitry Andric //
93a0822f0SDimitry Andric // This file implements the class that prints out the LLVM IR and machine
103a0822f0SDimitry Andric // functions using the MIR serialization format.
113a0822f0SDimitry Andric //
123a0822f0SDimitry Andric //===----------------------------------------------------------------------===//
133a0822f0SDimitry Andric
14044eb2f6SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
157ab83427SDimitry Andric #include "llvm/ADT/DenseMap.h"
16044eb2f6SDimitry Andric #include "llvm/ADT/STLExtras.h"
17b915e9e0SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
187ab83427SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
197ab83427SDimitry Andric #include "llvm/ADT/SmallVector.h"
207ab83427SDimitry Andric #include "llvm/ADT/StringRef.h"
21044eb2f6SDimitry Andric #include "llvm/CodeGen/MIRYamlMapping.h"
227ab83427SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
23dd58ef01SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
24ee8648bdSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
2501095a5dSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
267ab83427SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
277ab83427SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
28dd58ef01SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
29344a3780SDimitry Andric #include "llvm/CodeGen/MachineModuleSlotTracker.h"
307ab83427SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
311a82d4c0SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
32344a3780SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
33044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
34044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
35044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
36ac9a064cSDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
37145449b1SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
387ab83427SDimitry Andric #include "llvm/IR/DebugLoc.h"
397ab83427SDimitry Andric #include "llvm/IR/Function.h"
40044eb2f6SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
4101095a5dSDimitry Andric #include "llvm/IR/Instructions.h"
423a0822f0SDimitry Andric #include "llvm/IR/Module.h"
43ee8648bdSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
447ab83427SDimitry Andric #include "llvm/IR/Value.h"
457ab83427SDimitry Andric #include "llvm/MC/LaneBitmask.h"
467ab83427SDimitry Andric #include "llvm/Support/BranchProbability.h"
477ab83427SDimitry Andric #include "llvm/Support/Casting.h"
487ab83427SDimitry Andric #include "llvm/Support/CommandLine.h"
497ab83427SDimitry Andric #include "llvm/Support/ErrorHandling.h"
50b915e9e0SDimitry Andric #include "llvm/Support/Format.h"
517ab83427SDimitry Andric #include "llvm/Support/YAMLTraits.h"
52044eb2f6SDimitry Andric #include "llvm/Support/raw_ostream.h"
537ab83427SDimitry Andric #include "llvm/Target/TargetMachine.h"
547ab83427SDimitry Andric #include <algorithm>
557ab83427SDimitry Andric #include <cassert>
567ab83427SDimitry Andric #include <cinttypes>
577ab83427SDimitry Andric #include <cstdint>
587ab83427SDimitry Andric #include <iterator>
597ab83427SDimitry Andric #include <string>
607ab83427SDimitry Andric #include <utility>
617ab83427SDimitry Andric #include <vector>
623a0822f0SDimitry Andric
633a0822f0SDimitry Andric using namespace llvm;
643a0822f0SDimitry Andric
65044eb2f6SDimitry Andric static cl::opt<bool> SimplifyMIR(
66044eb2f6SDimitry Andric "simplify-mir", cl::Hidden,
67c46e6a59SDimitry Andric cl::desc("Leave out unnecessary information when printing MIR"));
68c46e6a59SDimitry Andric
69cfca06d7SDimitry Andric static cl::opt<bool> PrintLocations("mir-debug-loc", cl::Hidden, cl::init(true),
70cfca06d7SDimitry Andric cl::desc("Print MIR debug-locations"));
71cfca06d7SDimitry Andric
72ac9a064cSDimitry Andric extern cl::opt<bool> WriteNewDbgInfoFormat;
73ac9a064cSDimitry Andric
743a0822f0SDimitry Andric namespace {
753a0822f0SDimitry Andric
76dd58ef01SDimitry Andric /// This structure describes how to print out stack object references.
77dd58ef01SDimitry Andric struct FrameIndexOperand {
78dd58ef01SDimitry Andric std::string Name;
79dd58ef01SDimitry Andric unsigned ID;
80dd58ef01SDimitry Andric bool IsFixed;
81dd58ef01SDimitry Andric
FrameIndexOperand__anon5e715b950111::FrameIndexOperand82dd58ef01SDimitry Andric FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
83dd58ef01SDimitry Andric : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
84dd58ef01SDimitry Andric
85dd58ef01SDimitry Andric /// Return an ordinary stack object reference.
create__anon5e715b950111::FrameIndexOperand86dd58ef01SDimitry Andric static FrameIndexOperand create(StringRef Name, unsigned ID) {
87dd58ef01SDimitry Andric return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
88dd58ef01SDimitry Andric }
89dd58ef01SDimitry Andric
90dd58ef01SDimitry Andric /// Return a fixed stack object reference.
createFixed__anon5e715b950111::FrameIndexOperand91dd58ef01SDimitry Andric static FrameIndexOperand createFixed(unsigned ID) {
92dd58ef01SDimitry Andric return FrameIndexOperand("", ID, /*IsFixed=*/true);
93dd58ef01SDimitry Andric }
94dd58ef01SDimitry Andric };
95dd58ef01SDimitry Andric
96dd58ef01SDimitry Andric } // end anonymous namespace
97dd58ef01SDimitry Andric
98dd58ef01SDimitry Andric namespace llvm {
99dd58ef01SDimitry Andric
1003a0822f0SDimitry Andric /// This class prints out the machine functions using the MIR serialization
1013a0822f0SDimitry Andric /// format.
1023a0822f0SDimitry Andric class MIRPrinter {
1033a0822f0SDimitry Andric raw_ostream &OS;
1041a82d4c0SDimitry Andric DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
105dd58ef01SDimitry Andric /// Maps from stack object indices to operand indices which will be used when
106dd58ef01SDimitry Andric /// printing frame index machine operands.
107dd58ef01SDimitry Andric DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
1083a0822f0SDimitry Andric
1093a0822f0SDimitry Andric public:
MIRPrinter(raw_ostream & OS)1103a0822f0SDimitry Andric MIRPrinter(raw_ostream &OS) : OS(OS) {}
1113a0822f0SDimitry Andric
1123a0822f0SDimitry Andric void print(const MachineFunction &MF);
1133a0822f0SDimitry Andric
114ee8648bdSDimitry Andric void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
115ee8648bdSDimitry Andric const TargetRegisterInfo *TRI);
116dd58ef01SDimitry Andric void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
117ee8648bdSDimitry Andric const MachineFrameInfo &MFI);
118dd58ef01SDimitry Andric void convert(yaml::MachineFunction &MF,
119dd58ef01SDimitry Andric const MachineConstantPool &ConstantPool);
120dd58ef01SDimitry Andric void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
121dd58ef01SDimitry Andric const MachineJumpTableInfo &JTI);
122b915e9e0SDimitry Andric void convertStackObjects(yaml::MachineFunction &YMF,
123b915e9e0SDimitry Andric const MachineFunction &MF, ModuleSlotTracker &MST);
1247fa27ce4SDimitry Andric void convertEntryValueObjects(yaml::MachineFunction &YMF,
1257fa27ce4SDimitry Andric const MachineFunction &MF,
1267fa27ce4SDimitry Andric ModuleSlotTracker &MST);
127e6d15924SDimitry Andric void convertCallSiteObjects(yaml::MachineFunction &YMF,
128e6d15924SDimitry Andric const MachineFunction &MF,
129e6d15924SDimitry Andric ModuleSlotTracker &MST);
130344a3780SDimitry Andric void convertMachineMetadataNodes(yaml::MachineFunction &YMF,
131344a3780SDimitry Andric const MachineFunction &MF,
132344a3780SDimitry Andric MachineModuleSlotTracker &MST);
1331a82d4c0SDimitry Andric
1341a82d4c0SDimitry Andric private:
1351a82d4c0SDimitry Andric void initRegisterMaskIds(const MachineFunction &MF);
1361a82d4c0SDimitry Andric };
1371a82d4c0SDimitry Andric
1381a82d4c0SDimitry Andric /// This class prints out the machine instructions using the MIR serialization
1391a82d4c0SDimitry Andric /// format.
1401a82d4c0SDimitry Andric class MIPrinter {
1411a82d4c0SDimitry Andric raw_ostream &OS;
142ee8648bdSDimitry Andric ModuleSlotTracker &MST;
1431a82d4c0SDimitry Andric const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
144dd58ef01SDimitry Andric const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
145ca089b24SDimitry Andric /// Synchronization scope names registered with LLVMContext.
146ca089b24SDimitry Andric SmallVector<StringRef, 8> SSNs;
1471a82d4c0SDimitry Andric
148c46e6a59SDimitry Andric bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const;
149c46e6a59SDimitry Andric bool canPredictSuccessors(const MachineBasicBlock &MBB) const;
150c46e6a59SDimitry Andric
1511a82d4c0SDimitry Andric public:
MIPrinter(raw_ostream & OS,ModuleSlotTracker & MST,const DenseMap<const uint32_t *,unsigned> & RegisterMaskIds,const DenseMap<int,FrameIndexOperand> & StackObjectOperandMapping)152ee8648bdSDimitry Andric MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
153dd58ef01SDimitry Andric const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
154dd58ef01SDimitry Andric const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
155dd58ef01SDimitry Andric : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
156dd58ef01SDimitry Andric StackObjectOperandMapping(StackObjectOperandMapping) {}
157dd58ef01SDimitry Andric
158dd58ef01SDimitry Andric void print(const MachineBasicBlock &MBB);
1591a82d4c0SDimitry Andric
1601a82d4c0SDimitry Andric void print(const MachineInstr &MI);
161dd58ef01SDimitry Andric void printStackObjectReference(int FrameIndex);
162044eb2f6SDimitry Andric void print(const MachineInstr &MI, unsigned OpIdx,
163cfca06d7SDimitry Andric const TargetRegisterInfo *TRI, const TargetInstrInfo *TII,
164cfca06d7SDimitry Andric bool ShouldPrintRegisterTies, LLT TypeToPrint,
165cfca06d7SDimitry Andric bool PrintDef = true);
1663a0822f0SDimitry Andric };
1673a0822f0SDimitry Andric
168dd58ef01SDimitry Andric } // end namespace llvm
1693a0822f0SDimitry Andric
1703a0822f0SDimitry Andric namespace llvm {
1713a0822f0SDimitry Andric namespace yaml {
1723a0822f0SDimitry Andric
1733a0822f0SDimitry Andric /// This struct serializes the LLVM IR module.
1743a0822f0SDimitry Andric template <> struct BlockScalarTraits<Module> {
outputllvm::yaml::BlockScalarTraits1753a0822f0SDimitry Andric static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
1763a0822f0SDimitry Andric Mod.print(OS, nullptr);
1773a0822f0SDimitry Andric }
1787ab83427SDimitry Andric
inputllvm::yaml::BlockScalarTraits1793a0822f0SDimitry Andric static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
1803a0822f0SDimitry Andric llvm_unreachable("LLVM Module is supposed to be parsed separately");
1813a0822f0SDimitry Andric return "";
1823a0822f0SDimitry Andric }
1833a0822f0SDimitry Andric };
1843a0822f0SDimitry Andric
1853a0822f0SDimitry Andric } // end namespace yaml
1863a0822f0SDimitry Andric } // end namespace llvm
1873a0822f0SDimitry Andric
printRegMIR(unsigned Reg,yaml::StringValue & Dest,const TargetRegisterInfo * TRI)188044eb2f6SDimitry Andric static void printRegMIR(unsigned Reg, yaml::StringValue &Dest,
189dd58ef01SDimitry Andric const TargetRegisterInfo *TRI) {
190dd58ef01SDimitry Andric raw_string_ostream OS(Dest.Value);
191044eb2f6SDimitry Andric OS << printReg(Reg, TRI);
192dd58ef01SDimitry Andric }
193dd58ef01SDimitry Andric
print(const MachineFunction & MF)1943a0822f0SDimitry Andric void MIRPrinter::print(const MachineFunction &MF) {
1951a82d4c0SDimitry Andric initRegisterMaskIds(MF);
1961a82d4c0SDimitry Andric
1973a0822f0SDimitry Andric yaml::MachineFunction YamlMF;
1983a0822f0SDimitry Andric YamlMF.Name = MF.getName();
199cfca06d7SDimitry Andric YamlMF.Alignment = MF.getAlignment();
2003a0822f0SDimitry Andric YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
201d8e91e46SDimitry Andric YamlMF.HasWinCFI = MF.hasWinCFI();
202b915e9e0SDimitry Andric
203145449b1SDimitry Andric YamlMF.CallsEHReturn = MF.callsEHReturn();
204145449b1SDimitry Andric YamlMF.CallsUnwindInit = MF.callsUnwindInit();
205145449b1SDimitry Andric YamlMF.HasEHCatchret = MF.hasEHCatchret();
206145449b1SDimitry Andric YamlMF.HasEHScopes = MF.hasEHScopes();
207145449b1SDimitry Andric YamlMF.HasEHFunclets = MF.hasEHFunclets();
2087fa27ce4SDimitry Andric YamlMF.IsOutlined = MF.isOutlined();
209e3b55780SDimitry Andric YamlMF.UseDebugInstrRef = MF.useDebugInstrRef();
210145449b1SDimitry Andric
211b915e9e0SDimitry Andric YamlMF.Legalized = MF.getProperties().hasProperty(
212b915e9e0SDimitry Andric MachineFunctionProperties::Property::Legalized);
213b915e9e0SDimitry Andric YamlMF.RegBankSelected = MF.getProperties().hasProperty(
214b915e9e0SDimitry Andric MachineFunctionProperties::Property::RegBankSelected);
215b915e9e0SDimitry Andric YamlMF.Selected = MF.getProperties().hasProperty(
216b915e9e0SDimitry Andric MachineFunctionProperties::Property::Selected);
217eb11fae6SDimitry Andric YamlMF.FailedISel = MF.getProperties().hasProperty(
218eb11fae6SDimitry Andric MachineFunctionProperties::Property::FailedISel);
219c0981da4SDimitry Andric YamlMF.FailsVerification = MF.getProperties().hasProperty(
220c0981da4SDimitry Andric MachineFunctionProperties::Property::FailsVerification);
22177fc4c14SDimitry Andric YamlMF.TracksDebugUserValues = MF.getProperties().hasProperty(
22277fc4c14SDimitry Andric MachineFunctionProperties::Property::TracksDebugUserValues);
22301095a5dSDimitry Andric
224ee8648bdSDimitry Andric convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
225344a3780SDimitry Andric MachineModuleSlotTracker MST(&MF);
226044eb2f6SDimitry Andric MST.incorporateFunction(MF.getFunction());
227b915e9e0SDimitry Andric convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
228b915e9e0SDimitry Andric convertStackObjects(YamlMF, MF, MST);
2297fa27ce4SDimitry Andric convertEntryValueObjects(YamlMF, MF, MST);
230e6d15924SDimitry Andric convertCallSiteObjects(YamlMF, MF, MST);
231344a3780SDimitry Andric for (const auto &Sub : MF.DebugValueSubstitutions) {
232344a3780SDimitry Andric const auto &SubSrc = Sub.Src;
233344a3780SDimitry Andric const auto &SubDest = Sub.Dest;
234344a3780SDimitry Andric YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second,
235344a3780SDimitry Andric SubDest.first,
236344a3780SDimitry Andric SubDest.second,
237344a3780SDimitry Andric Sub.Subreg});
238344a3780SDimitry Andric }
239dd58ef01SDimitry Andric if (const auto *ConstantPool = MF.getConstantPool())
240dd58ef01SDimitry Andric convert(YamlMF, *ConstantPool);
241dd58ef01SDimitry Andric if (const auto *JumpTableInfo = MF.getJumpTableInfo())
242dd58ef01SDimitry Andric convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
243e6d15924SDimitry Andric
244e6d15924SDimitry Andric const TargetMachine &TM = MF.getTarget();
245e6d15924SDimitry Andric YamlMF.MachineFuncInfo =
246e6d15924SDimitry Andric std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF));
247e6d15924SDimitry Andric
248dd58ef01SDimitry Andric raw_string_ostream StrOS(YamlMF.Body.Value.Value);
249dd58ef01SDimitry Andric bool IsNewlineNeeded = false;
2503a0822f0SDimitry Andric for (const auto &MBB : MF) {
251dd58ef01SDimitry Andric if (IsNewlineNeeded)
252dd58ef01SDimitry Andric StrOS << "\n";
253dd58ef01SDimitry Andric MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
254dd58ef01SDimitry Andric .print(MBB);
255dd58ef01SDimitry Andric IsNewlineNeeded = true;
2563a0822f0SDimitry Andric }
257dd58ef01SDimitry Andric StrOS.flush();
258344a3780SDimitry Andric // Convert machine metadata collected during the print of the machine
259344a3780SDimitry Andric // function.
260344a3780SDimitry Andric convertMachineMetadataNodes(YamlMF, MF, MST);
261344a3780SDimitry Andric
2623a0822f0SDimitry Andric yaml::Output Out(OS);
2637ab83427SDimitry Andric if (!SimplifyMIR)
2647ab83427SDimitry Andric Out.setWriteDefaultValues(true);
2653a0822f0SDimitry Andric Out << YamlMF;
2663a0822f0SDimitry Andric }
2673a0822f0SDimitry Andric
printCustomRegMask(const uint32_t * RegMask,raw_ostream & OS,const TargetRegisterInfo * TRI)26871d5a254SDimitry Andric static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,
26971d5a254SDimitry Andric const TargetRegisterInfo *TRI) {
27071d5a254SDimitry Andric assert(RegMask && "Can't print an empty register mask");
27171d5a254SDimitry Andric OS << StringRef("CustomRegMask(");
27271d5a254SDimitry Andric
27371d5a254SDimitry Andric bool IsRegInRegMaskFound = false;
27471d5a254SDimitry Andric for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {
27571d5a254SDimitry Andric // Check whether the register is asserted in regmask.
27671d5a254SDimitry Andric if (RegMask[I / 32] & (1u << (I % 32))) {
27771d5a254SDimitry Andric if (IsRegInRegMaskFound)
27871d5a254SDimitry Andric OS << ',';
279044eb2f6SDimitry Andric OS << printReg(I, TRI);
28071d5a254SDimitry Andric IsRegInRegMaskFound = true;
28171d5a254SDimitry Andric }
28271d5a254SDimitry Andric }
28371d5a254SDimitry Andric
28471d5a254SDimitry Andric OS << ')';
28571d5a254SDimitry Andric }
28671d5a254SDimitry Andric
printRegClassOrBank(unsigned Reg,yaml::StringValue & Dest,const MachineRegisterInfo & RegInfo,const TargetRegisterInfo * TRI)287044eb2f6SDimitry Andric static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest,
288044eb2f6SDimitry Andric const MachineRegisterInfo &RegInfo,
289044eb2f6SDimitry Andric const TargetRegisterInfo *TRI) {
290044eb2f6SDimitry Andric raw_string_ostream OS(Dest.Value);
291044eb2f6SDimitry Andric OS << printRegClassOrBank(Reg, RegInfo, TRI);
292044eb2f6SDimitry Andric }
293044eb2f6SDimitry Andric
294eb11fae6SDimitry Andric template <typename T>
295eb11fae6SDimitry Andric static void
printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo & DebugVar,T & Object,ModuleSlotTracker & MST)296eb11fae6SDimitry Andric printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo &DebugVar,
297eb11fae6SDimitry Andric T &Object, ModuleSlotTracker &MST) {
298eb11fae6SDimitry Andric std::array<std::string *, 3> Outputs{{&Object.DebugVar.Value,
299eb11fae6SDimitry Andric &Object.DebugExpr.Value,
300eb11fae6SDimitry Andric &Object.DebugLoc.Value}};
301eb11fae6SDimitry Andric std::array<const Metadata *, 3> Metas{{DebugVar.Var,
302eb11fae6SDimitry Andric DebugVar.Expr,
303eb11fae6SDimitry Andric DebugVar.Loc}};
304eb11fae6SDimitry Andric for (unsigned i = 0; i < 3; ++i) {
305eb11fae6SDimitry Andric raw_string_ostream StrOS(*Outputs[i]);
306eb11fae6SDimitry Andric Metas[i]->printAsOperand(StrOS, MST);
307eb11fae6SDimitry Andric }
308eb11fae6SDimitry Andric }
309044eb2f6SDimitry Andric
convert(yaml::MachineFunction & MF,const MachineRegisterInfo & RegInfo,const TargetRegisterInfo * TRI)3101a82d4c0SDimitry Andric void MIRPrinter::convert(yaml::MachineFunction &MF,
311ee8648bdSDimitry Andric const MachineRegisterInfo &RegInfo,
312ee8648bdSDimitry Andric const TargetRegisterInfo *TRI) {
3131a82d4c0SDimitry Andric MF.TracksRegLiveness = RegInfo.tracksLiveness();
314ee8648bdSDimitry Andric
315ee8648bdSDimitry Andric // Print the virtual register definitions.
316ee8648bdSDimitry Andric for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
317e3b55780SDimitry Andric Register Reg = Register::index2VirtReg(I);
318ee8648bdSDimitry Andric yaml::VirtualRegisterDefinition VReg;
319ee8648bdSDimitry Andric VReg.ID = I;
320eb11fae6SDimitry Andric if (RegInfo.getVRegName(Reg) != "")
321eb11fae6SDimitry Andric continue;
322044eb2f6SDimitry Andric ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);
323e3b55780SDimitry Andric Register PreferredReg = RegInfo.getSimpleHint(Reg);
324dd58ef01SDimitry Andric if (PreferredReg)
325044eb2f6SDimitry Andric printRegMIR(PreferredReg, VReg.PreferredRegister, TRI);
326ee8648bdSDimitry Andric MF.VirtualRegisters.push_back(VReg);
327ee8648bdSDimitry Andric }
328dd58ef01SDimitry Andric
329dd58ef01SDimitry Andric // Print the live ins.
330044eb2f6SDimitry Andric for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) {
331dd58ef01SDimitry Andric yaml::MachineFunctionLiveIn LiveIn;
332044eb2f6SDimitry Andric printRegMIR(LI.first, LiveIn.Register, TRI);
333044eb2f6SDimitry Andric if (LI.second)
334044eb2f6SDimitry Andric printRegMIR(LI.second, LiveIn.VirtualRegister, TRI);
335dd58ef01SDimitry Andric MF.LiveIns.push_back(LiveIn);
336dd58ef01SDimitry Andric }
33771d5a254SDimitry Andric
33871d5a254SDimitry Andric // Prints the callee saved registers.
33971d5a254SDimitry Andric if (RegInfo.isUpdatedCSRsInitialized()) {
34071d5a254SDimitry Andric const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
341dd58ef01SDimitry Andric std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
34271d5a254SDimitry Andric for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
343dd58ef01SDimitry Andric yaml::FlowStringValue Reg;
344044eb2f6SDimitry Andric printRegMIR(*I, Reg, TRI);
345dd58ef01SDimitry Andric CalleeSavedRegisters.push_back(Reg);
346dd58ef01SDimitry Andric }
347dd58ef01SDimitry Andric MF.CalleeSavedRegisters = CalleeSavedRegisters;
3481a82d4c0SDimitry Andric }
34971d5a254SDimitry Andric }
3501a82d4c0SDimitry Andric
convert(ModuleSlotTracker & MST,yaml::MachineFrameInfo & YamlMFI,const MachineFrameInfo & MFI)351dd58ef01SDimitry Andric void MIRPrinter::convert(ModuleSlotTracker &MST,
352dd58ef01SDimitry Andric yaml::MachineFrameInfo &YamlMFI,
353ee8648bdSDimitry Andric const MachineFrameInfo &MFI) {
354ee8648bdSDimitry Andric YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
355ee8648bdSDimitry Andric YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
356ee8648bdSDimitry Andric YamlMFI.HasStackMap = MFI.hasStackMap();
357ee8648bdSDimitry Andric YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
358ee8648bdSDimitry Andric YamlMFI.StackSize = MFI.getStackSize();
359ee8648bdSDimitry Andric YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
360cfca06d7SDimitry Andric YamlMFI.MaxAlignment = MFI.getMaxAlign().value();
361ee8648bdSDimitry Andric YamlMFI.AdjustsStack = MFI.adjustsStack();
362ee8648bdSDimitry Andric YamlMFI.HasCalls = MFI.hasCalls();
363a303c417SDimitry Andric YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()
364a303c417SDimitry Andric ? MFI.getMaxCallFrameSize() : ~0u;
365d8e91e46SDimitry Andric YamlMFI.CVBytesOfCalleeSavedRegisters =
366d8e91e46SDimitry Andric MFI.getCVBytesOfCalleeSavedRegisters();
367ee8648bdSDimitry Andric YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
368ee8648bdSDimitry Andric YamlMFI.HasVAStart = MFI.hasVAStart();
369ee8648bdSDimitry Andric YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
370344a3780SDimitry Andric YamlMFI.HasTailCall = MFI.hasTailCall();
371ac9a064cSDimitry Andric YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid();
372eb11fae6SDimitry Andric YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();
373dd58ef01SDimitry Andric if (MFI.getSavePoint()) {
374dd58ef01SDimitry Andric raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
375044eb2f6SDimitry Andric StrOS << printMBBReference(*MFI.getSavePoint());
376dd58ef01SDimitry Andric }
377dd58ef01SDimitry Andric if (MFI.getRestorePoint()) {
378dd58ef01SDimitry Andric raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
379044eb2f6SDimitry Andric StrOS << printMBBReference(*MFI.getRestorePoint());
380dd58ef01SDimitry Andric }
381ee8648bdSDimitry Andric }
382ee8648bdSDimitry Andric
convertEntryValueObjects(yaml::MachineFunction & YMF,const MachineFunction & MF,ModuleSlotTracker & MST)3837fa27ce4SDimitry Andric void MIRPrinter::convertEntryValueObjects(yaml::MachineFunction &YMF,
3847fa27ce4SDimitry Andric const MachineFunction &MF,
3857fa27ce4SDimitry Andric ModuleSlotTracker &MST) {
3867fa27ce4SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
3877fa27ce4SDimitry Andric for (const MachineFunction::VariableDbgInfo &DebugVar :
3887fa27ce4SDimitry Andric MF.getEntryValueVariableDbgInfo()) {
3897fa27ce4SDimitry Andric yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back();
3907fa27ce4SDimitry Andric printStackObjectDbgInfo(DebugVar, Obj, MST);
3917fa27ce4SDimitry Andric MCRegister EntryValReg = DebugVar.getEntryValueRegister();
3927fa27ce4SDimitry Andric printRegMIR(EntryValReg, Obj.EntryValueRegister, TRI);
3937fa27ce4SDimitry Andric }
3947fa27ce4SDimitry Andric }
3957fa27ce4SDimitry Andric
convertStackObjects(yaml::MachineFunction & YMF,const MachineFunction & MF,ModuleSlotTracker & MST)396b915e9e0SDimitry Andric void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
397b915e9e0SDimitry Andric const MachineFunction &MF,
398b915e9e0SDimitry Andric ModuleSlotTracker &MST) {
399b915e9e0SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
400b915e9e0SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
401b60736ecSDimitry Andric
402ee8648bdSDimitry Andric // Process fixed stack objects.
403b60736ecSDimitry Andric assert(YMF.FixedStackObjects.empty());
404b60736ecSDimitry Andric SmallVector<int, 32> FixedStackObjectsIdx;
405b60736ecSDimitry Andric const int BeginIdx = MFI.getObjectIndexBegin();
406b60736ecSDimitry Andric if (BeginIdx < 0)
407b60736ecSDimitry Andric FixedStackObjectsIdx.reserve(-BeginIdx);
408b60736ecSDimitry Andric
409ee8648bdSDimitry Andric unsigned ID = 0;
410b60736ecSDimitry Andric for (int I = BeginIdx; I < 0; ++I, ++ID) {
411b60736ecSDimitry Andric FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.
412ee8648bdSDimitry Andric if (MFI.isDeadObjectIndex(I))
413ee8648bdSDimitry Andric continue;
414ee8648bdSDimitry Andric
415ee8648bdSDimitry Andric yaml::FixedMachineStackObject YamlObject;
416dd58ef01SDimitry Andric YamlObject.ID = ID;
417ee8648bdSDimitry Andric YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
418ee8648bdSDimitry Andric ? yaml::FixedMachineStackObject::SpillSlot
419ee8648bdSDimitry Andric : yaml::FixedMachineStackObject::DefaultType;
420ee8648bdSDimitry Andric YamlObject.Offset = MFI.getObjectOffset(I);
421ee8648bdSDimitry Andric YamlObject.Size = MFI.getObjectSize(I);
422cfca06d7SDimitry Andric YamlObject.Alignment = MFI.getObjectAlign(I);
423e6d15924SDimitry Andric YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
424ee8648bdSDimitry Andric YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
425ee8648bdSDimitry Andric YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
426b60736ecSDimitry Andric // Save the ID' position in FixedStackObjects storage vector.
427b60736ecSDimitry Andric FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
428b915e9e0SDimitry Andric YMF.FixedStackObjects.push_back(YamlObject);
429dd58ef01SDimitry Andric StackObjectOperandMapping.insert(
430e6d15924SDimitry Andric std::make_pair(I, FrameIndexOperand::createFixed(ID)));
431ee8648bdSDimitry Andric }
432ee8648bdSDimitry Andric
433ee8648bdSDimitry Andric // Process ordinary stack objects.
434b60736ecSDimitry Andric assert(YMF.StackObjects.empty());
435b60736ecSDimitry Andric SmallVector<unsigned, 32> StackObjectsIdx;
436b60736ecSDimitry Andric const int EndIdx = MFI.getObjectIndexEnd();
437b60736ecSDimitry Andric if (EndIdx > 0)
438b60736ecSDimitry Andric StackObjectsIdx.reserve(EndIdx);
439ee8648bdSDimitry Andric ID = 0;
440b60736ecSDimitry Andric for (int I = 0; I < EndIdx; ++I, ++ID) {
441b60736ecSDimitry Andric StackObjectsIdx.push_back(-1); // Fill index for possible dead.
442ee8648bdSDimitry Andric if (MFI.isDeadObjectIndex(I))
443ee8648bdSDimitry Andric continue;
444ee8648bdSDimitry Andric
445ee8648bdSDimitry Andric yaml::MachineStackObject YamlObject;
446dd58ef01SDimitry Andric YamlObject.ID = ID;
447dd58ef01SDimitry Andric if (const auto *Alloca = MFI.getObjectAllocation(I))
448cfca06d7SDimitry Andric YamlObject.Name.Value = std::string(
449b60736ecSDimitry Andric Alloca->hasName() ? Alloca->getName() : "");
450ee8648bdSDimitry Andric YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
451ee8648bdSDimitry Andric ? yaml::MachineStackObject::SpillSlot
452ee8648bdSDimitry Andric : MFI.isVariableSizedObjectIndex(I)
453ee8648bdSDimitry Andric ? yaml::MachineStackObject::VariableSized
454ee8648bdSDimitry Andric : yaml::MachineStackObject::DefaultType;
455ee8648bdSDimitry Andric YamlObject.Offset = MFI.getObjectOffset(I);
456ee8648bdSDimitry Andric YamlObject.Size = MFI.getObjectSize(I);
457cfca06d7SDimitry Andric YamlObject.Alignment = MFI.getObjectAlign(I);
458e6d15924SDimitry Andric YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
459ee8648bdSDimitry Andric
460b60736ecSDimitry Andric // Save the ID' position in StackObjects storage vector.
461b60736ecSDimitry Andric StackObjectsIdx[ID] = YMF.StackObjects.size();
462b915e9e0SDimitry Andric YMF.StackObjects.push_back(YamlObject);
463dd58ef01SDimitry Andric StackObjectOperandMapping.insert(std::make_pair(
464e6d15924SDimitry Andric I, FrameIndexOperand::create(YamlObject.Name.Value, ID)));
465dd58ef01SDimitry Andric }
466dd58ef01SDimitry Andric
467dd58ef01SDimitry Andric for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
468b60736ecSDimitry Andric const int FrameIdx = CSInfo.getFrameIdx();
469b60736ecSDimitry Andric if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))
470e6d15924SDimitry Andric continue;
471e6d15924SDimitry Andric
472dd58ef01SDimitry Andric yaml::StringValue Reg;
473044eb2f6SDimitry Andric printRegMIR(CSInfo.getReg(), Reg, TRI);
474d8e91e46SDimitry Andric if (!CSInfo.isSpilledToReg()) {
475b60736ecSDimitry Andric assert(FrameIdx >= MFI.getObjectIndexBegin() &&
476b60736ecSDimitry Andric FrameIdx < MFI.getObjectIndexEnd() &&
477dd58ef01SDimitry Andric "Invalid stack object index");
478b60736ecSDimitry Andric if (FrameIdx < 0) { // Negative index means fixed objects.
479b60736ecSDimitry Andric auto &Object =
480b60736ecSDimitry Andric YMF.FixedStackObjects
481b60736ecSDimitry Andric [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
482b60736ecSDimitry Andric Object.CalleeSavedRegister = Reg;
483b60736ecSDimitry Andric Object.CalleeSavedRestored = CSInfo.isRestored();
484044eb2f6SDimitry Andric } else {
485b60736ecSDimitry Andric auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
486b60736ecSDimitry Andric Object.CalleeSavedRegister = Reg;
487b60736ecSDimitry Andric Object.CalleeSavedRestored = CSInfo.isRestored();
488044eb2f6SDimitry Andric }
489dd58ef01SDimitry Andric }
490d8e91e46SDimitry Andric }
491dd58ef01SDimitry Andric for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
492dd58ef01SDimitry Andric auto LocalObject = MFI.getLocalFrameObjectMap(I);
493b60736ecSDimitry Andric assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
494b60736ecSDimitry Andric YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
495b60736ecSDimitry Andric LocalObject.second;
496dd58ef01SDimitry Andric }
497dd58ef01SDimitry Andric
498dd58ef01SDimitry Andric // Print the stack object references in the frame information class after
499dd58ef01SDimitry Andric // converting the stack objects.
500dd58ef01SDimitry Andric if (MFI.hasStackProtectorIndex()) {
501b915e9e0SDimitry Andric raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);
502dd58ef01SDimitry Andric MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
503dd58ef01SDimitry Andric .printStackObjectReference(MFI.getStackProtectorIndex());
504dd58ef01SDimitry Andric }
505dd58ef01SDimitry Andric
506145449b1SDimitry Andric if (MFI.hasFunctionContextIndex()) {
507145449b1SDimitry Andric raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value);
508145449b1SDimitry Andric MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
509145449b1SDimitry Andric .printStackObjectReference(MFI.getFunctionContextIndex());
510145449b1SDimitry Andric }
511145449b1SDimitry Andric
512dd58ef01SDimitry Andric // Print the debug variable information.
513b915e9e0SDimitry Andric for (const MachineFunction::VariableDbgInfo &DebugVar :
5147fa27ce4SDimitry Andric MF.getInStackSlotVariableDbgInfo()) {
5157fa27ce4SDimitry Andric int Idx = DebugVar.getStackSlot();
5167fa27ce4SDimitry Andric assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() &&
517dd58ef01SDimitry Andric "Invalid stack object index");
5187fa27ce4SDimitry Andric if (Idx < 0) { // Negative index means fixed objects.
519b60736ecSDimitry Andric auto &Object =
5207fa27ce4SDimitry Andric YMF.FixedStackObjects[FixedStackObjectsIdx[Idx +
521b60736ecSDimitry Andric MFI.getNumFixedObjects()]];
522eb11fae6SDimitry Andric printStackObjectDbgInfo(DebugVar, Object, MST);
523eb11fae6SDimitry Andric } else {
5247fa27ce4SDimitry Andric auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]];
525eb11fae6SDimitry Andric printStackObjectDbgInfo(DebugVar, Object, MST);
526dd58ef01SDimitry Andric }
527dd58ef01SDimitry Andric }
528dd58ef01SDimitry Andric }
529dd58ef01SDimitry Andric
convertCallSiteObjects(yaml::MachineFunction & YMF,const MachineFunction & MF,ModuleSlotTracker & MST)530e6d15924SDimitry Andric void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
531e6d15924SDimitry Andric const MachineFunction &MF,
532e6d15924SDimitry Andric ModuleSlotTracker &MST) {
533e6d15924SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
534e6d15924SDimitry Andric for (auto CSInfo : MF.getCallSitesInfo()) {
535e6d15924SDimitry Andric yaml::CallSiteInfo YmlCS;
536e6d15924SDimitry Andric yaml::CallSiteInfo::MachineInstrLoc CallLocation;
537e6d15924SDimitry Andric
538e6d15924SDimitry Andric // Prepare instruction position.
5391d5ae102SDimitry Andric MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator();
540e6d15924SDimitry Andric CallLocation.BlockNum = CallI->getParent()->getNumber();
541e6d15924SDimitry Andric // Get call instruction offset from the beginning of block.
5421d5ae102SDimitry Andric CallLocation.Offset =
5431d5ae102SDimitry Andric std::distance(CallI->getParent()->instr_begin(), CallI);
544e6d15924SDimitry Andric YmlCS.CallLocation = CallLocation;
545e6d15924SDimitry Andric // Construct call arguments and theirs forwarding register info.
546ac9a064cSDimitry Andric for (auto ArgReg : CSInfo.second.ArgRegPairs) {
547e6d15924SDimitry Andric yaml::CallSiteInfo::ArgRegPair YmlArgReg;
548e6d15924SDimitry Andric YmlArgReg.ArgNo = ArgReg.ArgNo;
549e6d15924SDimitry Andric printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
550e6d15924SDimitry Andric YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
551e6d15924SDimitry Andric }
552e6d15924SDimitry Andric YMF.CallSitesInfo.push_back(YmlCS);
553e6d15924SDimitry Andric }
554e6d15924SDimitry Andric
555e6d15924SDimitry Andric // Sort call info by position of call instructions.
556e6d15924SDimitry Andric llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(),
557e6d15924SDimitry Andric [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {
558e6d15924SDimitry Andric if (A.CallLocation.BlockNum == B.CallLocation.BlockNum)
559e6d15924SDimitry Andric return A.CallLocation.Offset < B.CallLocation.Offset;
560e6d15924SDimitry Andric return A.CallLocation.BlockNum < B.CallLocation.BlockNum;
561e6d15924SDimitry Andric });
562e6d15924SDimitry Andric }
563e6d15924SDimitry Andric
convertMachineMetadataNodes(yaml::MachineFunction & YMF,const MachineFunction & MF,MachineModuleSlotTracker & MST)564344a3780SDimitry Andric void MIRPrinter::convertMachineMetadataNodes(yaml::MachineFunction &YMF,
565344a3780SDimitry Andric const MachineFunction &MF,
566344a3780SDimitry Andric MachineModuleSlotTracker &MST) {
567344a3780SDimitry Andric MachineModuleSlotTracker::MachineMDNodeListType MDList;
568344a3780SDimitry Andric MST.collectMachineMDNodes(MDList);
569344a3780SDimitry Andric for (auto &MD : MDList) {
570344a3780SDimitry Andric std::string NS;
571344a3780SDimitry Andric raw_string_ostream StrOS(NS);
572344a3780SDimitry Andric MD.second->print(StrOS, MST, MF.getFunction().getParent());
573ac9a064cSDimitry Andric YMF.MachineMetadataNodes.push_back(NS);
574344a3780SDimitry Andric }
575344a3780SDimitry Andric }
576344a3780SDimitry Andric
convert(yaml::MachineFunction & MF,const MachineConstantPool & ConstantPool)577dd58ef01SDimitry Andric void MIRPrinter::convert(yaml::MachineFunction &MF,
578dd58ef01SDimitry Andric const MachineConstantPool &ConstantPool) {
579dd58ef01SDimitry Andric unsigned ID = 0;
580dd58ef01SDimitry Andric for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
581dd58ef01SDimitry Andric std::string Str;
582dd58ef01SDimitry Andric raw_string_ostream StrOS(Str);
583044eb2f6SDimitry Andric if (Constant.isMachineConstantPoolEntry()) {
584044eb2f6SDimitry Andric Constant.Val.MachineCPVal->print(StrOS);
585044eb2f6SDimitry Andric } else {
586dd58ef01SDimitry Andric Constant.Val.ConstVal->printAsOperand(StrOS);
587044eb2f6SDimitry Andric }
588044eb2f6SDimitry Andric
589044eb2f6SDimitry Andric yaml::MachineConstantPoolValue YamlConstant;
590dd58ef01SDimitry Andric YamlConstant.ID = ID++;
591ac9a064cSDimitry Andric YamlConstant.Value = Str;
592cfca06d7SDimitry Andric YamlConstant.Alignment = Constant.getAlign();
593044eb2f6SDimitry Andric YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();
594044eb2f6SDimitry Andric
595dd58ef01SDimitry Andric MF.Constants.push_back(YamlConstant);
596ee8648bdSDimitry Andric }
597ee8648bdSDimitry Andric }
598ee8648bdSDimitry Andric
convert(ModuleSlotTracker & MST,yaml::MachineJumpTable & YamlJTI,const MachineJumpTableInfo & JTI)599ee8648bdSDimitry Andric void MIRPrinter::convert(ModuleSlotTracker &MST,
600dd58ef01SDimitry Andric yaml::MachineJumpTable &YamlJTI,
601dd58ef01SDimitry Andric const MachineJumpTableInfo &JTI) {
602dd58ef01SDimitry Andric YamlJTI.Kind = JTI.getEntryKind();
603dd58ef01SDimitry Andric unsigned ID = 0;
604dd58ef01SDimitry Andric for (const auto &Table : JTI.getJumpTables()) {
6051a82d4c0SDimitry Andric std::string Str;
606dd58ef01SDimitry Andric yaml::MachineJumpTable::Entry Entry;
607dd58ef01SDimitry Andric Entry.ID = ID++;
608dd58ef01SDimitry Andric for (const auto *MBB : Table.MBBs) {
6091a82d4c0SDimitry Andric raw_string_ostream StrOS(Str);
610044eb2f6SDimitry Andric StrOS << printMBBReference(*MBB);
611ac9a064cSDimitry Andric Entry.Blocks.push_back(Str);
6121a82d4c0SDimitry Andric Str.clear();
6131a82d4c0SDimitry Andric }
614dd58ef01SDimitry Andric YamlJTI.Entries.push_back(Entry);
615dd58ef01SDimitry Andric }
6161a82d4c0SDimitry Andric }
6171a82d4c0SDimitry Andric
initRegisterMaskIds(const MachineFunction & MF)6181a82d4c0SDimitry Andric void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
6191a82d4c0SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
6201a82d4c0SDimitry Andric unsigned I = 0;
6211a82d4c0SDimitry Andric for (const uint32_t *Mask : TRI->getRegMasks())
6221a82d4c0SDimitry Andric RegisterMaskIds.insert(std::make_pair(Mask, I++));
6231a82d4c0SDimitry Andric }
6241a82d4c0SDimitry Andric
guessSuccessors(const MachineBasicBlock & MBB,SmallVectorImpl<MachineBasicBlock * > & Result,bool & IsFallthrough)625c46e6a59SDimitry Andric void llvm::guessSuccessors(const MachineBasicBlock &MBB,
626c46e6a59SDimitry Andric SmallVectorImpl<MachineBasicBlock*> &Result,
627c46e6a59SDimitry Andric bool &IsFallthrough) {
628c46e6a59SDimitry Andric SmallPtrSet<MachineBasicBlock*,8> Seen;
629c46e6a59SDimitry Andric
630c46e6a59SDimitry Andric for (const MachineInstr &MI : MBB) {
631c46e6a59SDimitry Andric if (MI.isPHI())
632c46e6a59SDimitry Andric continue;
633c46e6a59SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
634c46e6a59SDimitry Andric if (!MO.isMBB())
635c46e6a59SDimitry Andric continue;
636c46e6a59SDimitry Andric MachineBasicBlock *Succ = MO.getMBB();
637c46e6a59SDimitry Andric auto RP = Seen.insert(Succ);
638c46e6a59SDimitry Andric if (RP.second)
639c46e6a59SDimitry Andric Result.push_back(Succ);
640c46e6a59SDimitry Andric }
641c46e6a59SDimitry Andric }
642c46e6a59SDimitry Andric MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
643c46e6a59SDimitry Andric IsFallthrough = I == MBB.end() || !I->isBarrier();
644c46e6a59SDimitry Andric }
645c46e6a59SDimitry Andric
646c46e6a59SDimitry Andric bool
canPredictBranchProbabilities(const MachineBasicBlock & MBB) const647c46e6a59SDimitry Andric MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const {
648c46e6a59SDimitry Andric if (MBB.succ_size() <= 1)
649c46e6a59SDimitry Andric return true;
650c46e6a59SDimitry Andric if (!MBB.hasSuccessorProbabilities())
651c46e6a59SDimitry Andric return true;
652c46e6a59SDimitry Andric
653c46e6a59SDimitry Andric SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(),
654c46e6a59SDimitry Andric MBB.Probs.end());
655c46e6a59SDimitry Andric BranchProbability::normalizeProbabilities(Normalized.begin(),
656c46e6a59SDimitry Andric Normalized.end());
657c46e6a59SDimitry Andric SmallVector<BranchProbability,8> Equal(Normalized.size());
658c46e6a59SDimitry Andric BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end());
659c46e6a59SDimitry Andric
660c46e6a59SDimitry Andric return std::equal(Normalized.begin(), Normalized.end(), Equal.begin());
661c46e6a59SDimitry Andric }
662c46e6a59SDimitry Andric
canPredictSuccessors(const MachineBasicBlock & MBB) const663c46e6a59SDimitry Andric bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const {
664c46e6a59SDimitry Andric SmallVector<MachineBasicBlock*,8> GuessedSuccs;
665c46e6a59SDimitry Andric bool GuessedFallthrough;
666c46e6a59SDimitry Andric guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough);
667c46e6a59SDimitry Andric if (GuessedFallthrough) {
668c46e6a59SDimitry Andric const MachineFunction &MF = *MBB.getParent();
669c46e6a59SDimitry Andric MachineFunction::const_iterator NextI = std::next(MBB.getIterator());
670c46e6a59SDimitry Andric if (NextI != MF.end()) {
671c46e6a59SDimitry Andric MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);
672c46e6a59SDimitry Andric if (!is_contained(GuessedSuccs, Next))
673c46e6a59SDimitry Andric GuessedSuccs.push_back(Next);
674c46e6a59SDimitry Andric }
675c46e6a59SDimitry Andric }
676c46e6a59SDimitry Andric if (GuessedSuccs.size() != MBB.succ_size())
677c46e6a59SDimitry Andric return false;
678c46e6a59SDimitry Andric return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin());
679c46e6a59SDimitry Andric }
680c46e6a59SDimitry Andric
print(const MachineBasicBlock & MBB)681dd58ef01SDimitry Andric void MIPrinter::print(const MachineBasicBlock &MBB) {
682dd58ef01SDimitry Andric assert(MBB.getNumber() >= 0 && "Invalid MBB number");
683b60736ecSDimitry Andric MBB.printName(OS,
684b60736ecSDimitry Andric MachineBasicBlock::PrintNameIr |
685b60736ecSDimitry Andric MachineBasicBlock::PrintNameAttributes,
686b60736ecSDimitry Andric &MST);
687dd58ef01SDimitry Andric OS << ":\n";
688dd58ef01SDimitry Andric
689dd58ef01SDimitry Andric bool HasLineAttributes = false;
690dd58ef01SDimitry Andric // Print the successors
691c46e6a59SDimitry Andric bool canPredictProbs = canPredictBranchProbabilities(MBB);
692044eb2f6SDimitry Andric // Even if the list of successors is empty, if we cannot guess it,
693044eb2f6SDimitry Andric // we need to print it to tell the parser that the list is empty.
694044eb2f6SDimitry Andric // This is needed, because MI model unreachable as empty blocks
695044eb2f6SDimitry Andric // with an empty successor list. If the parser would see that
696044eb2f6SDimitry Andric // without the successor list, it would guess the code would
697044eb2f6SDimitry Andric // fallthrough.
698044eb2f6SDimitry Andric if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||
699044eb2f6SDimitry Andric !canPredictSuccessors(MBB)) {
700dd58ef01SDimitry Andric OS.indent(2) << "successors:";
701ac9a064cSDimitry Andric if (!MBB.succ_empty())
702ac9a064cSDimitry Andric OS << " ";
703dd58ef01SDimitry Andric for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
704dd58ef01SDimitry Andric if (I != MBB.succ_begin())
705dd58ef01SDimitry Andric OS << ", ";
706044eb2f6SDimitry Andric OS << printMBBReference(**I);
707c46e6a59SDimitry Andric if (!SimplifyMIR || !canPredictProbs)
708b915e9e0SDimitry Andric OS << '('
709b915e9e0SDimitry Andric << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator())
710b915e9e0SDimitry Andric << ')';
711dd58ef01SDimitry Andric }
712dd58ef01SDimitry Andric OS << "\n";
713dd58ef01SDimitry Andric HasLineAttributes = true;
714dd58ef01SDimitry Andric }
715dd58ef01SDimitry Andric
716dd58ef01SDimitry Andric // Print the live in registers.
7177e7b6700SDimitry Andric const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
718145449b1SDimitry Andric if (!MBB.livein_empty()) {
7197e7b6700SDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
720dd58ef01SDimitry Andric OS.indent(2) << "liveins: ";
721dd58ef01SDimitry Andric bool First = true;
722145449b1SDimitry Andric for (const auto &LI : MBB.liveins_dbg()) {
723dd58ef01SDimitry Andric if (!First)
724dd58ef01SDimitry Andric OS << ", ";
725dd58ef01SDimitry Andric First = false;
726044eb2f6SDimitry Andric OS << printReg(LI.PhysReg, &TRI);
727b915e9e0SDimitry Andric if (!LI.LaneMask.all())
728b915e9e0SDimitry Andric OS << ":0x" << PrintLaneMask(LI.LaneMask);
729dd58ef01SDimitry Andric }
730dd58ef01SDimitry Andric OS << "\n";
731dd58ef01SDimitry Andric HasLineAttributes = true;
732dd58ef01SDimitry Andric }
733dd58ef01SDimitry Andric
734ac9a064cSDimitry Andric if (HasLineAttributes && !MBB.empty())
735dd58ef01SDimitry Andric OS << "\n";
736dd58ef01SDimitry Andric bool IsInBundle = false;
737ac9a064cSDimitry Andric for (const MachineInstr &MI : MBB.instrs()) {
738dd58ef01SDimitry Andric if (IsInBundle && !MI.isInsideBundle()) {
739dd58ef01SDimitry Andric OS.indent(2) << "}\n";
740dd58ef01SDimitry Andric IsInBundle = false;
741dd58ef01SDimitry Andric }
742dd58ef01SDimitry Andric OS.indent(IsInBundle ? 4 : 2);
743dd58ef01SDimitry Andric print(MI);
744dd58ef01SDimitry Andric if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
745dd58ef01SDimitry Andric OS << " {";
746dd58ef01SDimitry Andric IsInBundle = true;
747dd58ef01SDimitry Andric }
748dd58ef01SDimitry Andric OS << "\n";
749dd58ef01SDimitry Andric }
750dd58ef01SDimitry Andric if (IsInBundle)
751dd58ef01SDimitry Andric OS.indent(2) << "}\n";
752dd58ef01SDimitry Andric }
753dd58ef01SDimitry Andric
print(const MachineInstr & MI)7541a82d4c0SDimitry Andric void MIPrinter::print(const MachineInstr &MI) {
755044eb2f6SDimitry Andric const auto *MF = MI.getMF();
75601095a5dSDimitry Andric const auto &MRI = MF->getRegInfo();
75701095a5dSDimitry Andric const auto &SubTarget = MF->getSubtarget();
7581a82d4c0SDimitry Andric const auto *TRI = SubTarget.getRegisterInfo();
7591a82d4c0SDimitry Andric assert(TRI && "Expected target register info");
7601a82d4c0SDimitry Andric const auto *TII = SubTarget.getInstrInfo();
7611a82d4c0SDimitry Andric assert(TII && "Expected target instruction info");
762dd58ef01SDimitry Andric if (MI.isCFIInstruction())
763dd58ef01SDimitry Andric assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
7641a82d4c0SDimitry Andric
765b915e9e0SDimitry Andric SmallBitVector PrintedTypes(8);
766044eb2f6SDimitry Andric bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();
7671a82d4c0SDimitry Andric unsigned I = 0, E = MI.getNumOperands();
7681a82d4c0SDimitry Andric for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
7691a82d4c0SDimitry Andric !MI.getOperand(I).isImplicit();
7701a82d4c0SDimitry Andric ++I) {
7711a82d4c0SDimitry Andric if (I)
7721a82d4c0SDimitry Andric OS << ", ";
773cfca06d7SDimitry Andric print(MI, I, TRI, TII, ShouldPrintRegisterTies,
774044eb2f6SDimitry Andric MI.getTypeToPrint(I, PrintedTypes, MRI),
775044eb2f6SDimitry Andric /*PrintDef=*/false);
7761a82d4c0SDimitry Andric }
7771a82d4c0SDimitry Andric
7781a82d4c0SDimitry Andric if (I)
7791a82d4c0SDimitry Andric OS << " = ";
780dd58ef01SDimitry Andric if (MI.getFlag(MachineInstr::FrameSetup))
781dd58ef01SDimitry Andric OS << "frame-setup ";
782eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FrameDestroy))
783eb11fae6SDimitry Andric OS << "frame-destroy ";
784eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmNoNans))
785eb11fae6SDimitry Andric OS << "nnan ";
786eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmNoInfs))
787eb11fae6SDimitry Andric OS << "ninf ";
788eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmNsz))
789eb11fae6SDimitry Andric OS << "nsz ";
790eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmArcp))
791eb11fae6SDimitry Andric OS << "arcp ";
792eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmContract))
793eb11fae6SDimitry Andric OS << "contract ";
794eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmAfn))
795eb11fae6SDimitry Andric OS << "afn ";
796eb11fae6SDimitry Andric if (MI.getFlag(MachineInstr::FmReassoc))
797eb11fae6SDimitry Andric OS << "reassoc ";
798d8e91e46SDimitry Andric if (MI.getFlag(MachineInstr::NoUWrap))
799d8e91e46SDimitry Andric OS << "nuw ";
800d8e91e46SDimitry Andric if (MI.getFlag(MachineInstr::NoSWrap))
801d8e91e46SDimitry Andric OS << "nsw ";
802d8e91e46SDimitry Andric if (MI.getFlag(MachineInstr::IsExact))
803d8e91e46SDimitry Andric OS << "exact ";
804706b4fc4SDimitry Andric if (MI.getFlag(MachineInstr::NoFPExcept))
805706b4fc4SDimitry Andric OS << "nofpexcept ";
806cfca06d7SDimitry Andric if (MI.getFlag(MachineInstr::NoMerge))
807cfca06d7SDimitry Andric OS << "nomerge ";
8087fa27ce4SDimitry Andric if (MI.getFlag(MachineInstr::Unpredictable))
8097fa27ce4SDimitry Andric OS << "unpredictable ";
810b1c73532SDimitry Andric if (MI.getFlag(MachineInstr::NoConvergent))
811b1c73532SDimitry Andric OS << "noconvergent ";
812ac9a064cSDimitry Andric if (MI.getFlag(MachineInstr::NonNeg))
813ac9a064cSDimitry Andric OS << "nneg ";
814ac9a064cSDimitry Andric if (MI.getFlag(MachineInstr::Disjoint))
815ac9a064cSDimitry Andric OS << "disjoint ";
816ac9a064cSDimitry Andric if (MI.getFlag(MachineInstr::NoUSWrap))
817ac9a064cSDimitry Andric OS << "nusw ";
818eb11fae6SDimitry Andric
8191a82d4c0SDimitry Andric OS << TII->getName(MI.getOpcode());
8201a82d4c0SDimitry Andric if (I < E)
8211a82d4c0SDimitry Andric OS << ' ';
8221a82d4c0SDimitry Andric
8231a82d4c0SDimitry Andric bool NeedComma = false;
8241a82d4c0SDimitry Andric for (; I < E; ++I) {
8251a82d4c0SDimitry Andric if (NeedComma)
8261a82d4c0SDimitry Andric OS << ", ";
827cfca06d7SDimitry Andric print(MI, I, TRI, TII, ShouldPrintRegisterTies,
828044eb2f6SDimitry Andric MI.getTypeToPrint(I, PrintedTypes, MRI));
8291a82d4c0SDimitry Andric NeedComma = true;
8301a82d4c0SDimitry Andric }
831dd58ef01SDimitry Andric
832d8e91e46SDimitry Andric // Print any optional symbols attached to this instruction as-if they were
833d8e91e46SDimitry Andric // operands.
834d8e91e46SDimitry Andric if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {
835d8e91e46SDimitry Andric if (NeedComma)
836d8e91e46SDimitry Andric OS << ',';
837d8e91e46SDimitry Andric OS << " pre-instr-symbol ";
838d8e91e46SDimitry Andric MachineOperand::printSymbol(OS, *PreInstrSymbol);
839d8e91e46SDimitry Andric NeedComma = true;
840d8e91e46SDimitry Andric }
841d8e91e46SDimitry Andric if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {
842d8e91e46SDimitry Andric if (NeedComma)
843d8e91e46SDimitry Andric OS << ',';
844d8e91e46SDimitry Andric OS << " post-instr-symbol ";
845d8e91e46SDimitry Andric MachineOperand::printSymbol(OS, *PostInstrSymbol);
846d8e91e46SDimitry Andric NeedComma = true;
847d8e91e46SDimitry Andric }
848706b4fc4SDimitry Andric if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) {
849706b4fc4SDimitry Andric if (NeedComma)
850706b4fc4SDimitry Andric OS << ',';
851706b4fc4SDimitry Andric OS << " heap-alloc-marker ";
852706b4fc4SDimitry Andric HeapAllocMarker->printAsOperand(OS, MST);
853706b4fc4SDimitry Andric NeedComma = true;
854706b4fc4SDimitry Andric }
855e3b55780SDimitry Andric if (MDNode *PCSections = MI.getPCSections()) {
856e3b55780SDimitry Andric if (NeedComma)
857e3b55780SDimitry Andric OS << ',';
858e3b55780SDimitry Andric OS << " pcsections ";
859e3b55780SDimitry Andric PCSections->printAsOperand(OS, MST);
860e3b55780SDimitry Andric NeedComma = true;
861e3b55780SDimitry Andric }
862ac9a064cSDimitry Andric if (MDNode *MMRA = MI.getMMRAMetadata()) {
863ac9a064cSDimitry Andric if (NeedComma)
864ac9a064cSDimitry Andric OS << ',';
865ac9a064cSDimitry Andric OS << " mmra ";
866ac9a064cSDimitry Andric MMRA->printAsOperand(OS, MST);
867ac9a064cSDimitry Andric NeedComma = true;
868ac9a064cSDimitry Andric }
869e3b55780SDimitry Andric if (uint32_t CFIType = MI.getCFIType()) {
870e3b55780SDimitry Andric if (NeedComma)
871e3b55780SDimitry Andric OS << ',';
872e3b55780SDimitry Andric OS << " cfi-type " << CFIType;
873e3b55780SDimitry Andric NeedComma = true;
874e3b55780SDimitry Andric }
875d8e91e46SDimitry Andric
876b60736ecSDimitry Andric if (auto Num = MI.peekDebugInstrNum()) {
877b60736ecSDimitry Andric if (NeedComma)
878b60736ecSDimitry Andric OS << ',';
879b60736ecSDimitry Andric OS << " debug-instr-number " << Num;
880b60736ecSDimitry Andric NeedComma = true;
881b60736ecSDimitry Andric }
882b60736ecSDimitry Andric
883cfca06d7SDimitry Andric if (PrintLocations) {
884eb11fae6SDimitry Andric if (const DebugLoc &DL = MI.getDebugLoc()) {
885dd58ef01SDimitry Andric if (NeedComma)
886dd58ef01SDimitry Andric OS << ',';
887dd58ef01SDimitry Andric OS << " debug-location ";
888eb11fae6SDimitry Andric DL->printAsOperand(OS, MST);
889dd58ef01SDimitry Andric }
890cfca06d7SDimitry Andric }
891dd58ef01SDimitry Andric
892dd58ef01SDimitry Andric if (!MI.memoperands_empty()) {
893dd58ef01SDimitry Andric OS << " :: ";
894044eb2f6SDimitry Andric const LLVMContext &Context = MF->getFunction().getContext();
895eb11fae6SDimitry Andric const MachineFrameInfo &MFI = MF->getFrameInfo();
896dd58ef01SDimitry Andric bool NeedComma = false;
897dd58ef01SDimitry Andric for (const auto *Op : MI.memoperands()) {
898dd58ef01SDimitry Andric if (NeedComma)
899dd58ef01SDimitry Andric OS << ", ";
900eb11fae6SDimitry Andric Op->print(OS, MST, SSNs, Context, &MFI, TII);
901dd58ef01SDimitry Andric NeedComma = true;
902dd58ef01SDimitry Andric }
903dd58ef01SDimitry Andric }
9041a82d4c0SDimitry Andric }
9051a82d4c0SDimitry Andric
printStackObjectReference(int FrameIndex)906dd58ef01SDimitry Andric void MIPrinter::printStackObjectReference(int FrameIndex) {
907dd58ef01SDimitry Andric auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
908dd58ef01SDimitry Andric assert(ObjectInfo != StackObjectOperandMapping.end() &&
909dd58ef01SDimitry Andric "Invalid frame index");
910dd58ef01SDimitry Andric const FrameIndexOperand &Operand = ObjectInfo->second;
911044eb2f6SDimitry Andric MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed,
912044eb2f6SDimitry Andric Operand.Name);
913dd58ef01SDimitry Andric }
914dd58ef01SDimitry Andric
formatOperandComment(std::string Comment)915cfca06d7SDimitry Andric static std::string formatOperandComment(std::string Comment) {
916cfca06d7SDimitry Andric if (Comment.empty())
917cfca06d7SDimitry Andric return Comment;
918cfca06d7SDimitry Andric return std::string(" /* " + Comment + " */");
919cfca06d7SDimitry Andric }
920cfca06d7SDimitry Andric
print(const MachineInstr & MI,unsigned OpIdx,const TargetRegisterInfo * TRI,const TargetInstrInfo * TII,bool ShouldPrintRegisterTies,LLT TypeToPrint,bool PrintDef)921044eb2f6SDimitry Andric void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
922044eb2f6SDimitry Andric const TargetRegisterInfo *TRI,
923cfca06d7SDimitry Andric const TargetInstrInfo *TII,
924044eb2f6SDimitry Andric bool ShouldPrintRegisterTies, LLT TypeToPrint,
925044eb2f6SDimitry Andric bool PrintDef) {
926044eb2f6SDimitry Andric const MachineOperand &Op = MI.getOperand(OpIdx);
927cfca06d7SDimitry Andric std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx, TRI);
928cfca06d7SDimitry Andric
9291a82d4c0SDimitry Andric switch (Op.getType()) {
9301a82d4c0SDimitry Andric case MachineOperand::MO_Immediate:
931044eb2f6SDimitry Andric if (MI.isOperandSubregIdx(OpIdx)) {
932044eb2f6SDimitry Andric MachineOperand::printTargetFlags(OS, Op);
933eb11fae6SDimitry Andric MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI);
9341a82d4c0SDimitry Andric break;
935044eb2f6SDimitry Andric }
936e3b55780SDimitry Andric [[fallthrough]];
937044eb2f6SDimitry Andric case MachineOperand::MO_Register:
938dd58ef01SDimitry Andric case MachineOperand::MO_CImmediate:
939c7dac04cSDimitry Andric case MachineOperand::MO_FPImmediate:
940044eb2f6SDimitry Andric case MachineOperand::MO_MachineBasicBlock:
941044eb2f6SDimitry Andric case MachineOperand::MO_ConstantPoolIndex:
942044eb2f6SDimitry Andric case MachineOperand::MO_TargetIndex:
943044eb2f6SDimitry Andric case MachineOperand::MO_JumpTableIndex:
944044eb2f6SDimitry Andric case MachineOperand::MO_ExternalSymbol:
945044eb2f6SDimitry Andric case MachineOperand::MO_GlobalAddress:
946044eb2f6SDimitry Andric case MachineOperand::MO_RegisterLiveOut:
947044eb2f6SDimitry Andric case MachineOperand::MO_Metadata:
948c7dac04cSDimitry Andric case MachineOperand::MO_MCSymbol:
949c7dac04cSDimitry Andric case MachineOperand::MO_CFIIndex:
950c7dac04cSDimitry Andric case MachineOperand::MO_IntrinsicID:
951c7dac04cSDimitry Andric case MachineOperand::MO_Predicate:
9521d5ae102SDimitry Andric case MachineOperand::MO_BlockAddress:
953e3b55780SDimitry Andric case MachineOperand::MO_DbgInstrRef:
9541d5ae102SDimitry Andric case MachineOperand::MO_ShuffleMask: {
955044eb2f6SDimitry Andric unsigned TiedOperandIdx = 0;
956044eb2f6SDimitry Andric if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
957044eb2f6SDimitry Andric TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
958044eb2f6SDimitry Andric const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo();
959706b4fc4SDimitry Andric Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false,
960eb11fae6SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII);
961cfca06d7SDimitry Andric OS << formatOperandComment(MOComment);
962dd58ef01SDimitry Andric break;
963044eb2f6SDimitry Andric }
964dd58ef01SDimitry Andric case MachineOperand::MO_FrameIndex:
965dd58ef01SDimitry Andric printStackObjectReference(Op.getIndex());
966dd58ef01SDimitry Andric break;
9671a82d4c0SDimitry Andric case MachineOperand::MO_RegisterMask: {
9681a82d4c0SDimitry Andric auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
9691a82d4c0SDimitry Andric if (RegMaskInfo != RegisterMaskIds.end())
9701a82d4c0SDimitry Andric OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
9711a82d4c0SDimitry Andric else
97271d5a254SDimitry Andric printCustomRegMask(Op.getRegMask(), OS, TRI);
9731a82d4c0SDimitry Andric break;
9741a82d4c0SDimitry Andric }
975dd58ef01SDimitry Andric }
976dd58ef01SDimitry Andric }
977dd58ef01SDimitry Andric
printIRValue(raw_ostream & OS,const Value & V,ModuleSlotTracker & MST)978706b4fc4SDimitry Andric void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
979706b4fc4SDimitry Andric ModuleSlotTracker &MST) {
980706b4fc4SDimitry Andric if (isa<GlobalValue>(V)) {
981706b4fc4SDimitry Andric V.printAsOperand(OS, /*PrintType=*/false, MST);
982706b4fc4SDimitry Andric return;
983706b4fc4SDimitry Andric }
984706b4fc4SDimitry Andric if (isa<Constant>(V)) {
985706b4fc4SDimitry Andric // Machine memory operands can load/store to/from constant value pointers.
986706b4fc4SDimitry Andric OS << '`';
987706b4fc4SDimitry Andric V.printAsOperand(OS, /*PrintType=*/true, MST);
988706b4fc4SDimitry Andric OS << '`';
989706b4fc4SDimitry Andric return;
990706b4fc4SDimitry Andric }
991706b4fc4SDimitry Andric OS << "%ir.";
992706b4fc4SDimitry Andric if (V.hasName()) {
993706b4fc4SDimitry Andric printLLVMNameWithoutPrefix(OS, V.getName());
994706b4fc4SDimitry Andric return;
995706b4fc4SDimitry Andric }
996706b4fc4SDimitry Andric int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1;
997706b4fc4SDimitry Andric MachineOperand::printIRSlotNumber(OS, Slot);
998706b4fc4SDimitry Andric }
999706b4fc4SDimitry Andric
printMIR(raw_ostream & OS,const Module & M)10003a0822f0SDimitry Andric void llvm::printMIR(raw_ostream &OS, const Module &M) {
1001ac9a064cSDimitry Andric ScopedDbgInfoFormatSetter FormatSetter(const_cast<Module &>(M),
1002ac9a064cSDimitry Andric WriteNewDbgInfoFormat);
1003b1c73532SDimitry Andric
10043a0822f0SDimitry Andric yaml::Output Out(OS);
10053a0822f0SDimitry Andric Out << const_cast<Module &>(M);
10063a0822f0SDimitry Andric }
10073a0822f0SDimitry Andric
printMIR(raw_ostream & OS,const MachineFunction & MF)10083a0822f0SDimitry Andric void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
1009ac9a064cSDimitry Andric // RemoveDIs: as there's no textual form for DbgRecords yet, print debug-info
1010b1c73532SDimitry Andric // in dbg.value format.
1011ac9a064cSDimitry Andric ScopedDbgInfoFormatSetter FormatSetter(
1012ac9a064cSDimitry Andric const_cast<Function &>(MF.getFunction()), WriteNewDbgInfoFormat);
1013b1c73532SDimitry Andric
10143a0822f0SDimitry Andric MIRPrinter Printer(OS);
10153a0822f0SDimitry Andric Printer.print(MF);
10163a0822f0SDimitry Andric }
1017