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