xref: /llvm-project/llvm/lib/CodeGen/MIRPrinter.cpp (revision 19032bfe87fa0f4a3a7b3e68daafc93331b71e0d)
1 //===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the class that prints out the LLVM IR and machine
10 // functions using the MIR serialization format.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/CodeGen/MIRPrinter.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallBitVector.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/CodeGen/MIRYamlMapping.h"
22 #include "llvm/CodeGen/MachineBasicBlock.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstr.h"
27 #include "llvm/CodeGen/MachineJumpTableInfo.h"
28 #include "llvm/CodeGen/MachineMemOperand.h"
29 #include "llvm/CodeGen/MachineModuleSlotTracker.h"
30 #include "llvm/CodeGen/MachineOperand.h"
31 #include "llvm/CodeGen/MachineRegisterInfo.h"
32 #include "llvm/CodeGen/TargetFrameLowering.h"
33 #include "llvm/CodeGen/TargetInstrInfo.h"
34 #include "llvm/CodeGen/TargetRegisterInfo.h"
35 #include "llvm/CodeGen/TargetSubtargetInfo.h"
36 #include "llvm/CodeGenTypes/LowLevelType.h"
37 #include "llvm/IR/DebugInfoMetadata.h"
38 #include "llvm/IR/DebugLoc.h"
39 #include "llvm/IR/Function.h"
40 #include "llvm/IR/IRPrintingPasses.h"
41 #include "llvm/IR/Instructions.h"
42 #include "llvm/IR/Module.h"
43 #include "llvm/IR/ModuleSlotTracker.h"
44 #include "llvm/IR/Value.h"
45 #include "llvm/MC/LaneBitmask.h"
46 #include "llvm/Support/BranchProbability.h"
47 #include "llvm/Support/Casting.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/ErrorHandling.h"
50 #include "llvm/Support/Format.h"
51 #include "llvm/Support/YAMLTraits.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include "llvm/Target/TargetMachine.h"
54 #include <algorithm>
55 #include <cassert>
56 #include <cinttypes>
57 #include <cstdint>
58 #include <iterator>
59 #include <string>
60 #include <utility>
61 #include <vector>
62 
63 using namespace llvm;
64 
65 static cl::opt<bool> SimplifyMIR(
66     "simplify-mir", cl::Hidden,
67     cl::desc("Leave out unnecessary information when printing MIR"));
68 
69 static cl::opt<bool> PrintLocations("mir-debug-loc", cl::Hidden, cl::init(true),
70                                     cl::desc("Print MIR debug-locations"));
71 
72 extern cl::opt<bool> WriteNewDbgInfoFormat;
73 
74 namespace {
75 
76 /// This structure describes how to print out stack object references.
77 struct FrameIndexOperand {
78   std::string Name;
79   unsigned ID;
80   bool IsFixed;
81 
82   FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
83       : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
84 
85   /// Return an ordinary stack object reference.
86   static FrameIndexOperand create(StringRef Name, unsigned ID) {
87     return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
88   }
89 
90   /// Return a fixed stack object reference.
91   static FrameIndexOperand createFixed(unsigned ID) {
92     return FrameIndexOperand("", ID, /*IsFixed=*/true);
93   }
94 };
95 
96 } // end anonymous namespace
97 
98 namespace llvm {
99 
100 /// This class prints out the machine functions using the MIR serialization
101 /// format.
102 class MIRPrinter {
103   raw_ostream &OS;
104   const MachineModuleInfo &MMI;
105   DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
106   /// Maps from stack object indices to operand indices which will be used when
107   /// printing frame index machine operands.
108   DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
109 
110 public:
111   MIRPrinter(raw_ostream &OS, const MachineModuleInfo &MMI)
112       : OS(OS), MMI(MMI) {}
113 
114   void print(const MachineFunction &MF);
115 
116   void convert(yaml::MachineFunction &YamlMF, const MachineFunction &MF,
117                const MachineRegisterInfo &RegInfo,
118                const TargetRegisterInfo *TRI);
119   void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
120                const MachineFrameInfo &MFI);
121   void convert(yaml::MachineFunction &MF,
122                const MachineConstantPool &ConstantPool);
123   void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
124                const MachineJumpTableInfo &JTI);
125   void convertStackObjects(yaml::MachineFunction &YMF,
126                            const MachineFunction &MF, ModuleSlotTracker &MST);
127   void convertEntryValueObjects(yaml::MachineFunction &YMF,
128                                 const MachineFunction &MF,
129                                 ModuleSlotTracker &MST);
130   void convertCallSiteObjects(yaml::MachineFunction &YMF,
131                               const MachineFunction &MF,
132                               ModuleSlotTracker &MST);
133   void convertMachineMetadataNodes(yaml::MachineFunction &YMF,
134                                    const MachineFunction &MF,
135                                    MachineModuleSlotTracker &MST);
136   void convertCalledGlobals(yaml::MachineFunction &YMF,
137                             const MachineFunction &MF,
138                             MachineModuleSlotTracker &MST);
139 
140 private:
141   void initRegisterMaskIds(const MachineFunction &MF);
142 };
143 
144 /// This class prints out the machine instructions using the MIR serialization
145 /// format.
146 class MIPrinter {
147   raw_ostream &OS;
148   ModuleSlotTracker &MST;
149   const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
150   const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
151   /// Synchronization scope names registered with LLVMContext.
152   SmallVector<StringRef, 8> SSNs;
153 
154   bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const;
155   bool canPredictSuccessors(const MachineBasicBlock &MBB) const;
156 
157 public:
158   MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
159             const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
160             const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
161       : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
162         StackObjectOperandMapping(StackObjectOperandMapping) {}
163 
164   void print(const MachineBasicBlock &MBB);
165 
166   void print(const MachineInstr &MI);
167   void printStackObjectReference(int FrameIndex);
168   void print(const MachineInstr &MI, unsigned OpIdx,
169              const TargetRegisterInfo *TRI, const TargetInstrInfo *TII,
170              bool ShouldPrintRegisterTies, LLT TypeToPrint,
171              bool PrintDef = true);
172 };
173 
174 } // end namespace llvm
175 
176 namespace llvm {
177 namespace yaml {
178 
179 /// This struct serializes the LLVM IR module.
180 template <> struct BlockScalarTraits<Module> {
181   static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
182     Mod.print(OS, nullptr);
183   }
184 
185   static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
186     llvm_unreachable("LLVM Module is supposed to be parsed separately");
187     return "";
188   }
189 };
190 
191 } // end namespace yaml
192 } // end namespace llvm
193 
194 static void printRegMIR(unsigned Reg, yaml::StringValue &Dest,
195                         const TargetRegisterInfo *TRI) {
196   raw_string_ostream OS(Dest.Value);
197   OS << printReg(Reg, TRI);
198 }
199 
200 void MIRPrinter::print(const MachineFunction &MF) {
201   initRegisterMaskIds(MF);
202 
203   yaml::MachineFunction YamlMF;
204   YamlMF.Name = MF.getName();
205   YamlMF.Alignment = MF.getAlignment();
206   YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
207   YamlMF.HasWinCFI = MF.hasWinCFI();
208 
209   YamlMF.CallsEHReturn = MF.callsEHReturn();
210   YamlMF.CallsUnwindInit = MF.callsUnwindInit();
211   YamlMF.HasEHCatchret = MF.hasEHCatchret();
212   YamlMF.HasEHScopes = MF.hasEHScopes();
213   YamlMF.HasEHFunclets = MF.hasEHFunclets();
214   YamlMF.HasFakeUses = MF.hasFakeUses();
215   YamlMF.IsOutlined = MF.isOutlined();
216   YamlMF.UseDebugInstrRef = MF.useDebugInstrRef();
217 
218   YamlMF.Legalized = MF.getProperties().hasProperty(
219       MachineFunctionProperties::Property::Legalized);
220   YamlMF.RegBankSelected = MF.getProperties().hasProperty(
221       MachineFunctionProperties::Property::RegBankSelected);
222   YamlMF.Selected = MF.getProperties().hasProperty(
223       MachineFunctionProperties::Property::Selected);
224   YamlMF.FailedISel = MF.getProperties().hasProperty(
225       MachineFunctionProperties::Property::FailedISel);
226   YamlMF.FailsVerification = MF.getProperties().hasProperty(
227       MachineFunctionProperties::Property::FailsVerification);
228   YamlMF.TracksDebugUserValues = MF.getProperties().hasProperty(
229       MachineFunctionProperties::Property::TracksDebugUserValues);
230 
231   YamlMF.NoPHIs = MF.getProperties().hasProperty(
232       MachineFunctionProperties::Property::NoPHIs);
233   YamlMF.IsSSA = MF.getProperties().hasProperty(
234       MachineFunctionProperties::Property::IsSSA);
235   YamlMF.NoVRegs = MF.getProperties().hasProperty(
236       MachineFunctionProperties::Property::NoVRegs);
237 
238   convert(YamlMF, MF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
239   MachineModuleSlotTracker MST(MMI, &MF);
240   MST.incorporateFunction(MF.getFunction());
241   convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
242   convertStackObjects(YamlMF, MF, MST);
243   convertEntryValueObjects(YamlMF, MF, MST);
244   convertCallSiteObjects(YamlMF, MF, MST);
245   for (const auto &Sub : MF.DebugValueSubstitutions) {
246     const auto &SubSrc = Sub.Src;
247     const auto &SubDest = Sub.Dest;
248     YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second,
249                                               SubDest.first,
250                                               SubDest.second,
251                                               Sub.Subreg});
252   }
253   if (const auto *ConstantPool = MF.getConstantPool())
254     convert(YamlMF, *ConstantPool);
255   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
256     convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
257 
258   const TargetMachine &TM = MF.getTarget();
259   YamlMF.MachineFuncInfo =
260       std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF));
261 
262   raw_string_ostream StrOS(YamlMF.Body.Value.Value);
263   bool IsNewlineNeeded = false;
264   for (const auto &MBB : MF) {
265     if (IsNewlineNeeded)
266       StrOS << "\n";
267     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
268         .print(MBB);
269     IsNewlineNeeded = true;
270   }
271   // Convert machine metadata collected during the print of the machine
272   // function.
273   convertMachineMetadataNodes(YamlMF, MF, MST);
274 
275   convertCalledGlobals(YamlMF, MF, MST);
276 
277   yaml::Output Out(OS);
278   if (!SimplifyMIR)
279       Out.setWriteDefaultValues(true);
280   Out << YamlMF;
281 }
282 
283 static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,
284                                const TargetRegisterInfo *TRI) {
285   assert(RegMask && "Can't print an empty register mask");
286   OS << StringRef("CustomRegMask(");
287 
288   bool IsRegInRegMaskFound = false;
289   for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {
290     // Check whether the register is asserted in regmask.
291     if (RegMask[I / 32] & (1u << (I % 32))) {
292       if (IsRegInRegMaskFound)
293         OS << ',';
294       OS << printReg(I, TRI);
295       IsRegInRegMaskFound = true;
296     }
297   }
298 
299   OS << ')';
300 }
301 
302 static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest,
303                                 const MachineRegisterInfo &RegInfo,
304                                 const TargetRegisterInfo *TRI) {
305   raw_string_ostream OS(Dest.Value);
306   OS << printRegClassOrBank(Reg, RegInfo, TRI);
307 }
308 
309 template <typename T>
310 static void
311 printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo &DebugVar,
312                         T &Object, ModuleSlotTracker &MST) {
313   std::array<std::string *, 3> Outputs{{&Object.DebugVar.Value,
314                                         &Object.DebugExpr.Value,
315                                         &Object.DebugLoc.Value}};
316   std::array<const Metadata *, 3> Metas{{DebugVar.Var,
317                                         DebugVar.Expr,
318                                         DebugVar.Loc}};
319   for (unsigned i = 0; i < 3; ++i) {
320     raw_string_ostream StrOS(*Outputs[i]);
321     Metas[i]->printAsOperand(StrOS, MST);
322   }
323 }
324 
325 static void printRegFlags(Register Reg,
326                           std::vector<yaml::FlowStringValue> &RegisterFlags,
327                           const MachineFunction &MF,
328                           const TargetRegisterInfo *TRI) {
329   auto FlagValues = TRI->getVRegFlagsOfReg(Reg, MF);
330   for (auto &Flag : FlagValues) {
331     RegisterFlags.push_back(yaml::FlowStringValue(Flag.str()));
332   }
333 }
334 
335 void MIRPrinter::convert(yaml::MachineFunction &YamlMF,
336                          const MachineFunction &MF,
337                          const MachineRegisterInfo &RegInfo,
338                          const TargetRegisterInfo *TRI) {
339   YamlMF.TracksRegLiveness = RegInfo.tracksLiveness();
340 
341   // Print the virtual register definitions.
342   for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
343     Register Reg = Register::index2VirtReg(I);
344     yaml::VirtualRegisterDefinition VReg;
345     VReg.ID = I;
346     if (RegInfo.getVRegName(Reg) != "")
347       continue;
348     ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);
349     Register PreferredReg = RegInfo.getSimpleHint(Reg);
350     if (PreferredReg)
351       printRegMIR(PreferredReg, VReg.PreferredRegister, TRI);
352     printRegFlags(Reg, VReg.RegisterFlags, MF, TRI);
353     YamlMF.VirtualRegisters.push_back(std::move(VReg));
354   }
355 
356   // Print the live ins.
357   for (std::pair<MCRegister, Register> LI : RegInfo.liveins()) {
358     yaml::MachineFunctionLiveIn LiveIn;
359     printRegMIR(LI.first, LiveIn.Register, TRI);
360     if (LI.second)
361       printRegMIR(LI.second, LiveIn.VirtualRegister, TRI);
362     YamlMF.LiveIns.push_back(std::move(LiveIn));
363   }
364 
365   // Prints the callee saved registers.
366   if (RegInfo.isUpdatedCSRsInitialized()) {
367     const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
368     std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
369     for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
370       yaml::FlowStringValue Reg;
371       printRegMIR(*I, Reg, TRI);
372       CalleeSavedRegisters.push_back(std::move(Reg));
373     }
374     YamlMF.CalleeSavedRegisters = std::move(CalleeSavedRegisters);
375   }
376 }
377 
378 void MIRPrinter::convert(ModuleSlotTracker &MST,
379                          yaml::MachineFrameInfo &YamlMFI,
380                          const MachineFrameInfo &MFI) {
381   YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
382   YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
383   YamlMFI.HasStackMap = MFI.hasStackMap();
384   YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
385   YamlMFI.StackSize = MFI.getStackSize();
386   YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
387   YamlMFI.MaxAlignment = MFI.getMaxAlign().value();
388   YamlMFI.AdjustsStack = MFI.adjustsStack();
389   YamlMFI.HasCalls = MFI.hasCalls();
390   YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()
391     ? MFI.getMaxCallFrameSize() : ~0u;
392   YamlMFI.CVBytesOfCalleeSavedRegisters =
393       MFI.getCVBytesOfCalleeSavedRegisters();
394   YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
395   YamlMFI.HasVAStart = MFI.hasVAStart();
396   YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
397   YamlMFI.HasTailCall = MFI.hasTailCall();
398   YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid();
399   YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();
400   if (MFI.getSavePoint()) {
401     raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
402     StrOS << printMBBReference(*MFI.getSavePoint());
403   }
404   if (MFI.getRestorePoint()) {
405     raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
406     StrOS << printMBBReference(*MFI.getRestorePoint());
407   }
408 }
409 
410 void MIRPrinter::convertEntryValueObjects(yaml::MachineFunction &YMF,
411                                           const MachineFunction &MF,
412                                           ModuleSlotTracker &MST) {
413   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
414   for (const MachineFunction::VariableDbgInfo &DebugVar :
415        MF.getEntryValueVariableDbgInfo()) {
416     yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back();
417     printStackObjectDbgInfo(DebugVar, Obj, MST);
418     MCRegister EntryValReg = DebugVar.getEntryValueRegister();
419     printRegMIR(EntryValReg, Obj.EntryValueRegister, TRI);
420   }
421 }
422 
423 void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
424                                      const MachineFunction &MF,
425                                      ModuleSlotTracker &MST) {
426   const MachineFrameInfo &MFI = MF.getFrameInfo();
427   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
428 
429   // Process fixed stack objects.
430   assert(YMF.FixedStackObjects.empty());
431   SmallVector<int, 32> FixedStackObjectsIdx;
432   const int BeginIdx = MFI.getObjectIndexBegin();
433   if (BeginIdx < 0)
434     FixedStackObjectsIdx.reserve(-BeginIdx);
435 
436   unsigned ID = 0;
437   for (int I = BeginIdx; I < 0; ++I, ++ID) {
438     FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.
439     if (MFI.isDeadObjectIndex(I))
440       continue;
441 
442     yaml::FixedMachineStackObject YamlObject;
443     YamlObject.ID = ID;
444     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
445                           ? yaml::FixedMachineStackObject::SpillSlot
446                           : yaml::FixedMachineStackObject::DefaultType;
447     YamlObject.Offset = MFI.getObjectOffset(I);
448     YamlObject.Size = MFI.getObjectSize(I);
449     YamlObject.Alignment = MFI.getObjectAlign(I);
450     YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
451     YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
452     YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
453     // Save the ID' position in FixedStackObjects storage vector.
454     FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
455     YMF.FixedStackObjects.push_back(YamlObject);
456     StackObjectOperandMapping.insert(
457         std::make_pair(I, FrameIndexOperand::createFixed(ID)));
458   }
459 
460   // Process ordinary stack objects.
461   assert(YMF.StackObjects.empty());
462   SmallVector<unsigned, 32> StackObjectsIdx;
463   const int EndIdx = MFI.getObjectIndexEnd();
464   if (EndIdx > 0)
465     StackObjectsIdx.reserve(EndIdx);
466   ID = 0;
467   for (int I = 0; I < EndIdx; ++I, ++ID) {
468     StackObjectsIdx.push_back(-1); // Fill index for possible dead.
469     if (MFI.isDeadObjectIndex(I))
470       continue;
471 
472     yaml::MachineStackObject YamlObject;
473     YamlObject.ID = ID;
474     if (const auto *Alloca = MFI.getObjectAllocation(I))
475       YamlObject.Name.Value = std::string(
476           Alloca->hasName() ? Alloca->getName() : "");
477     YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
478                           ? yaml::MachineStackObject::SpillSlot
479                           : MFI.isVariableSizedObjectIndex(I)
480                                 ? yaml::MachineStackObject::VariableSized
481                                 : yaml::MachineStackObject::DefaultType;
482     YamlObject.Offset = MFI.getObjectOffset(I);
483     YamlObject.Size = MFI.getObjectSize(I);
484     YamlObject.Alignment = MFI.getObjectAlign(I);
485     YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
486 
487     // Save the ID' position in StackObjects storage vector.
488     StackObjectsIdx[ID] = YMF.StackObjects.size();
489     YMF.StackObjects.push_back(YamlObject);
490     StackObjectOperandMapping.insert(std::make_pair(
491         I, FrameIndexOperand::create(YamlObject.Name.Value, ID)));
492   }
493 
494   for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
495     const int FrameIdx = CSInfo.getFrameIdx();
496     if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))
497       continue;
498 
499     yaml::StringValue Reg;
500     printRegMIR(CSInfo.getReg(), Reg, TRI);
501     if (!CSInfo.isSpilledToReg()) {
502       assert(FrameIdx >= MFI.getObjectIndexBegin() &&
503              FrameIdx < MFI.getObjectIndexEnd() &&
504              "Invalid stack object index");
505       if (FrameIdx < 0) { // Negative index means fixed objects.
506         auto &Object =
507             YMF.FixedStackObjects
508                 [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
509         Object.CalleeSavedRegister = Reg;
510         Object.CalleeSavedRestored = CSInfo.isRestored();
511       } else {
512         auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
513         Object.CalleeSavedRegister = Reg;
514         Object.CalleeSavedRestored = CSInfo.isRestored();
515       }
516     }
517   }
518   for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
519     auto LocalObject = MFI.getLocalFrameObjectMap(I);
520     assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
521     YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
522         LocalObject.second;
523   }
524 
525   // Print the stack object references in the frame information class after
526   // converting the stack objects.
527   if (MFI.hasStackProtectorIndex()) {
528     raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);
529     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
530         .printStackObjectReference(MFI.getStackProtectorIndex());
531   }
532 
533   if (MFI.hasFunctionContextIndex()) {
534     raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value);
535     MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
536         .printStackObjectReference(MFI.getFunctionContextIndex());
537   }
538 
539   // Print the debug variable information.
540   for (const MachineFunction::VariableDbgInfo &DebugVar :
541        MF.getInStackSlotVariableDbgInfo()) {
542     int Idx = DebugVar.getStackSlot();
543     assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() &&
544            "Invalid stack object index");
545     if (Idx < 0) { // Negative index means fixed objects.
546       auto &Object =
547           YMF.FixedStackObjects[FixedStackObjectsIdx[Idx +
548                                                      MFI.getNumFixedObjects()]];
549       printStackObjectDbgInfo(DebugVar, Object, MST);
550     } else {
551       auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]];
552       printStackObjectDbgInfo(DebugVar, Object, MST);
553     }
554   }
555 }
556 
557 void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
558                                         const MachineFunction &MF,
559                                         ModuleSlotTracker &MST) {
560   const auto *TRI = MF.getSubtarget().getRegisterInfo();
561   for (auto CSInfo : MF.getCallSitesInfo()) {
562     yaml::CallSiteInfo YmlCS;
563     yaml::MachineInstrLoc CallLocation;
564 
565     // Prepare instruction position.
566     MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator();
567     CallLocation.BlockNum = CallI->getParent()->getNumber();
568     // Get call instruction offset from the beginning of block.
569     CallLocation.Offset =
570         std::distance(CallI->getParent()->instr_begin(), CallI);
571     YmlCS.CallLocation = CallLocation;
572     // Construct call arguments and theirs forwarding register info.
573     for (auto ArgReg : CSInfo.second.ArgRegPairs) {
574       yaml::CallSiteInfo::ArgRegPair YmlArgReg;
575       YmlArgReg.ArgNo = ArgReg.ArgNo;
576       printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
577       YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
578     }
579     YMF.CallSitesInfo.push_back(YmlCS);
580   }
581 
582   // Sort call info by position of call instructions.
583   llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(),
584              [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {
585                if (A.CallLocation.BlockNum == B.CallLocation.BlockNum)
586                  return A.CallLocation.Offset < B.CallLocation.Offset;
587                return A.CallLocation.BlockNum < B.CallLocation.BlockNum;
588              });
589 }
590 
591 void MIRPrinter::convertMachineMetadataNodes(yaml::MachineFunction &YMF,
592                                              const MachineFunction &MF,
593                                              MachineModuleSlotTracker &MST) {
594   MachineModuleSlotTracker::MachineMDNodeListType MDList;
595   MST.collectMachineMDNodes(MDList);
596   for (auto &MD : MDList) {
597     std::string NS;
598     raw_string_ostream StrOS(NS);
599     MD.second->print(StrOS, MST, MF.getFunction().getParent());
600     YMF.MachineMetadataNodes.push_back(NS);
601   }
602 }
603 
604 void MIRPrinter::convertCalledGlobals(yaml::MachineFunction &YMF,
605                                       const MachineFunction &MF,
606                                       MachineModuleSlotTracker &MST) {
607   for (const auto &[CallInst, CG] : MF.getCalledGlobals()) {
608     yaml::MachineInstrLoc CallSite;
609     CallSite.BlockNum = CallInst->getParent()->getNumber();
610     CallSite.Offset = std::distance(CallInst->getParent()->instr_begin(),
611                                     CallInst->getIterator());
612 
613     yaml::CalledGlobal YamlCG{CallSite, CG.Callee->getName().str(),
614                               CG.TargetFlags};
615     YMF.CalledGlobals.push_back(YamlCG);
616   }
617 
618   // Sort by position of call instructions.
619   llvm::sort(YMF.CalledGlobals.begin(), YMF.CalledGlobals.end(),
620              [](yaml::CalledGlobal A, yaml::CalledGlobal B) {
621                if (A.CallSite.BlockNum == B.CallSite.BlockNum)
622                  return A.CallSite.Offset < B.CallSite.Offset;
623                return A.CallSite.BlockNum < B.CallSite.BlockNum;
624              });
625 }
626 
627 void MIRPrinter::convert(yaml::MachineFunction &MF,
628                          const MachineConstantPool &ConstantPool) {
629   unsigned ID = 0;
630   for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
631     std::string Str;
632     raw_string_ostream StrOS(Str);
633     if (Constant.isMachineConstantPoolEntry()) {
634       Constant.Val.MachineCPVal->print(StrOS);
635     } else {
636       Constant.Val.ConstVal->printAsOperand(StrOS);
637     }
638 
639     yaml::MachineConstantPoolValue YamlConstant;
640     YamlConstant.ID = ID++;
641     YamlConstant.Value = Str;
642     YamlConstant.Alignment = Constant.getAlign();
643     YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();
644 
645     MF.Constants.push_back(YamlConstant);
646   }
647 }
648 
649 void MIRPrinter::convert(ModuleSlotTracker &MST,
650                          yaml::MachineJumpTable &YamlJTI,
651                          const MachineJumpTableInfo &JTI) {
652   YamlJTI.Kind = JTI.getEntryKind();
653   unsigned ID = 0;
654   for (const auto &Table : JTI.getJumpTables()) {
655     std::string Str;
656     yaml::MachineJumpTable::Entry Entry;
657     Entry.ID = ID++;
658     for (const auto *MBB : Table.MBBs) {
659       raw_string_ostream StrOS(Str);
660       StrOS << printMBBReference(*MBB);
661       Entry.Blocks.push_back(Str);
662       Str.clear();
663     }
664     YamlJTI.Entries.push_back(Entry);
665   }
666 }
667 
668 void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
669   const auto *TRI = MF.getSubtarget().getRegisterInfo();
670   unsigned I = 0;
671   for (const uint32_t *Mask : TRI->getRegMasks())
672     RegisterMaskIds.insert(std::make_pair(Mask, I++));
673 }
674 
675 void llvm::guessSuccessors(const MachineBasicBlock &MBB,
676                            SmallVectorImpl<MachineBasicBlock*> &Result,
677                            bool &IsFallthrough) {
678   SmallPtrSet<MachineBasicBlock*,8> Seen;
679 
680   for (const MachineInstr &MI : MBB) {
681     if (MI.isPHI())
682       continue;
683     for (const MachineOperand &MO : MI.operands()) {
684       if (!MO.isMBB())
685         continue;
686       MachineBasicBlock *Succ = MO.getMBB();
687       auto RP = Seen.insert(Succ);
688       if (RP.second)
689         Result.push_back(Succ);
690     }
691   }
692   MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
693   IsFallthrough = I == MBB.end() || !I->isBarrier();
694 }
695 
696 bool
697 MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const {
698   if (MBB.succ_size() <= 1)
699     return true;
700   if (!MBB.hasSuccessorProbabilities())
701     return true;
702 
703   SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(),
704                                               MBB.Probs.end());
705   BranchProbability::normalizeProbabilities(Normalized.begin(),
706                                             Normalized.end());
707   SmallVector<BranchProbability,8> Equal(Normalized.size());
708   BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end());
709 
710   return std::equal(Normalized.begin(), Normalized.end(), Equal.begin());
711 }
712 
713 bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const {
714   SmallVector<MachineBasicBlock*,8> GuessedSuccs;
715   bool GuessedFallthrough;
716   guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough);
717   if (GuessedFallthrough) {
718     const MachineFunction &MF = *MBB.getParent();
719     MachineFunction::const_iterator NextI = std::next(MBB.getIterator());
720     if (NextI != MF.end()) {
721       MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);
722       if (!is_contained(GuessedSuccs, Next))
723         GuessedSuccs.push_back(Next);
724     }
725   }
726   if (GuessedSuccs.size() != MBB.succ_size())
727     return false;
728   return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin());
729 }
730 
731 void MIPrinter::print(const MachineBasicBlock &MBB) {
732   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
733   MBB.printName(OS,
734                 MachineBasicBlock::PrintNameIr |
735                     MachineBasicBlock::PrintNameAttributes,
736                 &MST);
737   OS << ":\n";
738 
739   bool HasLineAttributes = false;
740   // Print the successors
741   bool canPredictProbs = canPredictBranchProbabilities(MBB);
742   // Even if the list of successors is empty, if we cannot guess it,
743   // we need to print it to tell the parser that the list is empty.
744   // This is needed, because MI model unreachable as empty blocks
745   // with an empty successor list. If the parser would see that
746   // without the successor list, it would guess the code would
747   // fallthrough.
748   if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||
749       !canPredictSuccessors(MBB)) {
750     OS.indent(2) << "successors:";
751     if (!MBB.succ_empty())
752       OS << " ";
753     for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
754       if (I != MBB.succ_begin())
755         OS << ", ";
756       OS << printMBBReference(**I);
757       if (!SimplifyMIR || !canPredictProbs)
758         OS << '('
759            << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator())
760            << ')';
761     }
762     OS << "\n";
763     HasLineAttributes = true;
764   }
765 
766   // Print the live in registers.
767   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
768   if (!MBB.livein_empty()) {
769     const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
770     OS.indent(2) << "liveins: ";
771     bool First = true;
772     for (const auto &LI : MBB.liveins_dbg()) {
773       if (!First)
774         OS << ", ";
775       First = false;
776       OS << printReg(LI.PhysReg, &TRI);
777       if (!LI.LaneMask.all())
778         OS << ":0x" << PrintLaneMask(LI.LaneMask);
779     }
780     OS << "\n";
781     HasLineAttributes = true;
782   }
783 
784   if (HasLineAttributes && !MBB.empty())
785     OS << "\n";
786   bool IsInBundle = false;
787   for (const MachineInstr &MI : MBB.instrs()) {
788     if (IsInBundle && !MI.isInsideBundle()) {
789       OS.indent(2) << "}\n";
790       IsInBundle = false;
791     }
792     OS.indent(IsInBundle ? 4 : 2);
793     print(MI);
794     if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
795       OS << " {";
796       IsInBundle = true;
797     }
798     OS << "\n";
799   }
800   if (IsInBundle)
801     OS.indent(2) << "}\n";
802 }
803 
804 void MIPrinter::print(const MachineInstr &MI) {
805   const auto *MF = MI.getMF();
806   const auto &MRI = MF->getRegInfo();
807   const auto &SubTarget = MF->getSubtarget();
808   const auto *TRI = SubTarget.getRegisterInfo();
809   assert(TRI && "Expected target register info");
810   const auto *TII = SubTarget.getInstrInfo();
811   assert(TII && "Expected target instruction info");
812   if (MI.isCFIInstruction())
813     assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
814 
815   SmallBitVector PrintedTypes(8);
816   bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();
817   unsigned I = 0, E = MI.getNumOperands();
818   for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
819          !MI.getOperand(I).isImplicit();
820        ++I) {
821     if (I)
822       OS << ", ";
823     print(MI, I, TRI, TII, ShouldPrintRegisterTies,
824           MI.getTypeToPrint(I, PrintedTypes, MRI),
825           /*PrintDef=*/false);
826   }
827 
828   if (I)
829     OS << " = ";
830   if (MI.getFlag(MachineInstr::FrameSetup))
831     OS << "frame-setup ";
832   if (MI.getFlag(MachineInstr::FrameDestroy))
833     OS << "frame-destroy ";
834   if (MI.getFlag(MachineInstr::FmNoNans))
835     OS << "nnan ";
836   if (MI.getFlag(MachineInstr::FmNoInfs))
837     OS << "ninf ";
838   if (MI.getFlag(MachineInstr::FmNsz))
839     OS << "nsz ";
840   if (MI.getFlag(MachineInstr::FmArcp))
841     OS << "arcp ";
842   if (MI.getFlag(MachineInstr::FmContract))
843     OS << "contract ";
844   if (MI.getFlag(MachineInstr::FmAfn))
845     OS << "afn ";
846   if (MI.getFlag(MachineInstr::FmReassoc))
847     OS << "reassoc ";
848   if (MI.getFlag(MachineInstr::NoUWrap))
849     OS << "nuw ";
850   if (MI.getFlag(MachineInstr::NoSWrap))
851     OS << "nsw ";
852   if (MI.getFlag(MachineInstr::IsExact))
853     OS << "exact ";
854   if (MI.getFlag(MachineInstr::NoFPExcept))
855     OS << "nofpexcept ";
856   if (MI.getFlag(MachineInstr::NoMerge))
857     OS << "nomerge ";
858   if (MI.getFlag(MachineInstr::Unpredictable))
859     OS << "unpredictable ";
860   if (MI.getFlag(MachineInstr::NoConvergent))
861     OS << "noconvergent ";
862   if (MI.getFlag(MachineInstr::NonNeg))
863     OS << "nneg ";
864   if (MI.getFlag(MachineInstr::Disjoint))
865     OS << "disjoint ";
866   if (MI.getFlag(MachineInstr::NoUSWrap))
867     OS << "nusw ";
868   if (MI.getFlag(MachineInstr::SameSign))
869     OS << "samesign ";
870 
871   OS << TII->getName(MI.getOpcode());
872   if (I < E)
873     OS << ' ';
874 
875   bool NeedComma = false;
876   for (; I < E; ++I) {
877     if (NeedComma)
878       OS << ", ";
879     print(MI, I, TRI, TII, ShouldPrintRegisterTies,
880           MI.getTypeToPrint(I, PrintedTypes, MRI));
881     NeedComma = true;
882   }
883 
884   // Print any optional symbols attached to this instruction as-if they were
885   // operands.
886   if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {
887     if (NeedComma)
888       OS << ',';
889     OS << " pre-instr-symbol ";
890     MachineOperand::printSymbol(OS, *PreInstrSymbol);
891     NeedComma = true;
892   }
893   if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {
894     if (NeedComma)
895       OS << ',';
896     OS << " post-instr-symbol ";
897     MachineOperand::printSymbol(OS, *PostInstrSymbol);
898     NeedComma = true;
899   }
900   if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) {
901     if (NeedComma)
902       OS << ',';
903     OS << " heap-alloc-marker ";
904     HeapAllocMarker->printAsOperand(OS, MST);
905     NeedComma = true;
906   }
907   if (MDNode *PCSections = MI.getPCSections()) {
908     if (NeedComma)
909       OS << ',';
910     OS << " pcsections ";
911     PCSections->printAsOperand(OS, MST);
912     NeedComma = true;
913   }
914   if (MDNode *MMRA = MI.getMMRAMetadata()) {
915     if (NeedComma)
916       OS << ',';
917     OS << " mmra ";
918     MMRA->printAsOperand(OS, MST);
919     NeedComma = true;
920   }
921   if (uint32_t CFIType = MI.getCFIType()) {
922     if (NeedComma)
923       OS << ',';
924     OS << " cfi-type " << CFIType;
925     NeedComma = true;
926   }
927 
928   if (auto Num = MI.peekDebugInstrNum()) {
929     if (NeedComma)
930       OS << ',';
931     OS << " debug-instr-number " << Num;
932     NeedComma = true;
933   }
934 
935   if (PrintLocations) {
936     if (const DebugLoc &DL = MI.getDebugLoc()) {
937       if (NeedComma)
938         OS << ',';
939       OS << " debug-location ";
940       DL->printAsOperand(OS, MST);
941     }
942   }
943 
944   if (!MI.memoperands_empty()) {
945     OS << " :: ";
946     const LLVMContext &Context = MF->getFunction().getContext();
947     const MachineFrameInfo &MFI = MF->getFrameInfo();
948     bool NeedComma = false;
949     for (const auto *Op : MI.memoperands()) {
950       if (NeedComma)
951         OS << ", ";
952       Op->print(OS, MST, SSNs, Context, &MFI, TII);
953       NeedComma = true;
954     }
955   }
956 }
957 
958 void MIPrinter::printStackObjectReference(int FrameIndex) {
959   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
960   assert(ObjectInfo != StackObjectOperandMapping.end() &&
961          "Invalid frame index");
962   const FrameIndexOperand &Operand = ObjectInfo->second;
963   MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed,
964                                             Operand.Name);
965 }
966 
967 static std::string formatOperandComment(std::string Comment) {
968   if (Comment.empty())
969     return Comment;
970   return std::string(" /* " + Comment + " */");
971 }
972 
973 void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
974                       const TargetRegisterInfo *TRI,
975                       const TargetInstrInfo *TII,
976                       bool ShouldPrintRegisterTies, LLT TypeToPrint,
977                       bool PrintDef) {
978   const MachineOperand &Op = MI.getOperand(OpIdx);
979   std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx, TRI);
980 
981   switch (Op.getType()) {
982   case MachineOperand::MO_Immediate:
983     if (MI.isOperandSubregIdx(OpIdx)) {
984       MachineOperand::printTargetFlags(OS, Op);
985       MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI);
986       break;
987     }
988     [[fallthrough]];
989   case MachineOperand::MO_Register:
990   case MachineOperand::MO_CImmediate:
991   case MachineOperand::MO_FPImmediate:
992   case MachineOperand::MO_MachineBasicBlock:
993   case MachineOperand::MO_ConstantPoolIndex:
994   case MachineOperand::MO_TargetIndex:
995   case MachineOperand::MO_JumpTableIndex:
996   case MachineOperand::MO_ExternalSymbol:
997   case MachineOperand::MO_GlobalAddress:
998   case MachineOperand::MO_RegisterLiveOut:
999   case MachineOperand::MO_Metadata:
1000   case MachineOperand::MO_MCSymbol:
1001   case MachineOperand::MO_CFIIndex:
1002   case MachineOperand::MO_IntrinsicID:
1003   case MachineOperand::MO_Predicate:
1004   case MachineOperand::MO_BlockAddress:
1005   case MachineOperand::MO_DbgInstrRef:
1006   case MachineOperand::MO_ShuffleMask: {
1007     unsigned TiedOperandIdx = 0;
1008     if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
1009       TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
1010     const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo();
1011     Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false,
1012              ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII);
1013       OS << formatOperandComment(MOComment);
1014     break;
1015   }
1016   case MachineOperand::MO_FrameIndex:
1017     printStackObjectReference(Op.getIndex());
1018     break;
1019   case MachineOperand::MO_RegisterMask: {
1020     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
1021     if (RegMaskInfo != RegisterMaskIds.end())
1022       OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
1023     else
1024       printCustomRegMask(Op.getRegMask(), OS, TRI);
1025     break;
1026   }
1027   }
1028 }
1029 
1030 void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
1031                                 ModuleSlotTracker &MST) {
1032   if (isa<GlobalValue>(V)) {
1033     V.printAsOperand(OS, /*PrintType=*/false, MST);
1034     return;
1035   }
1036   if (isa<Constant>(V)) {
1037     // Machine memory operands can load/store to/from constant value pointers.
1038     OS << '`';
1039     V.printAsOperand(OS, /*PrintType=*/true, MST);
1040     OS << '`';
1041     return;
1042   }
1043   OS << "%ir.";
1044   if (V.hasName()) {
1045     printLLVMNameWithoutPrefix(OS, V.getName());
1046     return;
1047   }
1048   int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1;
1049   MachineOperand::printIRSlotNumber(OS, Slot);
1050 }
1051 
1052 void llvm::printMIR(raw_ostream &OS, const Module &M) {
1053   ScopedDbgInfoFormatSetter FormatSetter(const_cast<Module &>(M),
1054                                          WriteNewDbgInfoFormat);
1055 
1056   yaml::Output Out(OS);
1057   Out << const_cast<Module &>(M);
1058 }
1059 
1060 void llvm::printMIR(raw_ostream &OS, const MachineModuleInfo &MMI,
1061                     const MachineFunction &MF) {
1062   // RemoveDIs: as there's no textual form for DbgRecords yet, print debug-info
1063   // in dbg.value format.
1064   ScopedDbgInfoFormatSetter FormatSetter(
1065       const_cast<Function &>(MF.getFunction()), WriteNewDbgInfoFormat);
1066 
1067   MIRPrinter Printer(OS, MMI);
1068   Printer.print(MF);
1069 }
1070