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