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