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
327 // Print the anti-hints.
328 const auto &AntiHints = RegInfo.getRegAllocationAntiHints(VReg: Reg);
329 if (!AntiHints.empty()) {
330 std::vector<yaml::FlowStringValue> AntiHintStrings;
331 for (Register AntiHint : AntiHints) {
332 yaml::FlowStringValue AntiHintStr;
333 printRegMIR(Reg: AntiHint, Dest&: AntiHintStr, TRI);
334 AntiHintStrings.push_back(x: std::move(AntiHintStr));
335 }
336 VReg.AntiHints = std::move(AntiHintStrings);
337 }
338 if (VRM) {
339 Register Orig = VRM->getPreSplitReg(virtReg: Reg);
340 if (Orig && Orig != Reg) {
341 raw_string_ostream OS(VReg.SplitFrom.Value);
342 OS << printReg(Reg: Orig, TRI);
343 }
344 if (VRM->hasPhys(virtReg: Reg)) {
345 raw_string_ostream OS(VReg.AssignedPhys.Value);
346 OS << printReg(Reg: VRM->getPhys(virtReg: Reg), TRI);
347 }
348 }
349 YamlMF.VirtualRegisters.push_back(x: std::move(VReg));
350 }
351
352 // Print the live ins.
353 for (std::pair<MCRegister, Register> LI : RegInfo.liveins()) {
354 yaml::MachineFunctionLiveIn LiveIn;
355 printRegMIR(Reg: LI.first, Dest&: LiveIn.Register, TRI);
356 if (LI.second)
357 printRegMIR(Reg: LI.second, Dest&: LiveIn.VirtualRegister, TRI);
358 YamlMF.LiveIns.push_back(x: std::move(LiveIn));
359 }
360
361 // Prints the callee saved registers.
362 if (RegInfo.isUpdatedCSRsInitialized()) {
363 const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();
364 std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
365 for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {
366 yaml::FlowStringValue Reg;
367 printRegMIR(Reg: *I, Dest&: Reg, TRI);
368 CalleeSavedRegisters.push_back(x: std::move(Reg));
369 }
370 YamlMF.CalleeSavedRegisters = std::move(CalleeSavedRegisters);
371 }
372}
373
374static void convertMFI(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
375 const MachineFrameInfo &MFI,
376 const TargetRegisterInfo *TRI) {
377 YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
378 YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
379 YamlMFI.HasStackMap = MFI.hasStackMap();
380 YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
381 YamlMFI.StackSize = MFI.getStackSize();
382 YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
383 YamlMFI.MaxAlignment = MFI.getMaxAlign().value();
384 YamlMFI.AdjustsStack = MFI.adjustsStack();
385 YamlMFI.HasCalls = MFI.hasCalls();
386 YamlMFI.FramePointerPolicy = MFI.getFramePointerPolicy();
387 YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()
388 ? MFI.getMaxCallFrameSize() : ~0u;
389 YamlMFI.CVBytesOfCalleeSavedRegisters =
390 MFI.getCVBytesOfCalleeSavedRegisters();
391 YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
392 YamlMFI.HasVAStart = MFI.hasVAStart();
393 YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
394 YamlMFI.HasTailCall = MFI.hasTailCall();
395 YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid();
396 YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();
397 if (!MFI.getSavePoints().empty())
398 convertSRPoints(MST, YamlSRPoints&: YamlMFI.SavePoints, SRPoints: MFI.getSavePoints(), TRI);
399 if (!MFI.getRestorePoints().empty())
400 convertSRPoints(MST, YamlSRPoints&: YamlMFI.RestorePoints, SRPoints: MFI.getRestorePoints(), TRI);
401}
402
403static void convertEntryValueObjects(yaml::MachineFunction &YMF,
404 const MachineFunction &MF,
405 ModuleSlotTracker &MST) {
406 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
407 for (const MachineFunction::VariableDbgInfo &DebugVar :
408 MF.getEntryValueVariableDbgInfo()) {
409 yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back();
410 printStackObjectDbgInfo(DebugVar, Object&: Obj, MST);
411 MCRegister EntryValReg = DebugVar.getEntryValueRegister();
412 printRegMIR(Reg: EntryValReg, Dest&: Obj.EntryValueRegister, TRI);
413 }
414}
415
416static void printStackObjectReference(raw_ostream &OS,
417 const MFPrintState &State,
418 int FrameIndex) {
419 auto ObjectInfo = State.StackObjectOperandMapping.find(Val: FrameIndex);
420 assert(ObjectInfo != State.StackObjectOperandMapping.end() &&
421 "Invalid frame index");
422 const FrameIndexOperand &Operand = ObjectInfo->second;
423 MachineOperand::printStackObjectReference(OS, FrameIndex: Operand.ID, IsFixed: Operand.IsFixed,
424 Name: Operand.Name);
425}
426
427static void convertStackObjects(yaml::MachineFunction &YMF,
428 const MachineFunction &MF,
429 ModuleSlotTracker &MST, MFPrintState &State) {
430 const MachineFrameInfo &MFI = MF.getFrameInfo();
431 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
432
433 // Process fixed stack objects.
434 assert(YMF.FixedStackObjects.empty());
435 SmallVector<int, 32> FixedStackObjectsIdx;
436 const int BeginIdx = MFI.getObjectIndexBegin();
437 if (BeginIdx < 0)
438 FixedStackObjectsIdx.reserve(N: -BeginIdx);
439
440 unsigned ID = 0;
441 for (int I = BeginIdx; I < 0; ++I, ++ID) {
442 FixedStackObjectsIdx.push_back(Elt: -1); // Fill index for possible dead.
443 if (MFI.isDeadObjectIndex(ObjectIdx: I))
444 continue;
445
446 yaml::FixedMachineStackObject YamlObject;
447 YamlObject.ID = ID;
448 YamlObject.Type = MFI.isSpillSlotObjectIndex(ObjectIdx: I)
449 ? yaml::FixedMachineStackObject::SpillSlot
450 : yaml::FixedMachineStackObject::DefaultType;
451 YamlObject.Offset = MFI.getObjectOffset(ObjectIdx: I);
452 YamlObject.Size = MFI.getObjectSize(ObjectIdx: I);
453 YamlObject.Alignment = MFI.getObjectAlign(ObjectIdx: I);
454 YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(ObjectIdx: I);
455 YamlObject.IsImmutable = MFI.isImmutableObjectIndex(ObjectIdx: I);
456 YamlObject.IsAliased = MFI.isAliasedObjectIndex(ObjectIdx: I);
457 // Save the ID' position in FixedStackObjects storage vector.
458 FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
459 YMF.FixedStackObjects.push_back(x: std::move(YamlObject));
460 State.StackObjectOperandMapping.insert(
461 KV: std::make_pair(x&: I, y: FrameIndexOperand::createFixed(ID)));
462 }
463
464 // Process ordinary stack objects.
465 assert(YMF.StackObjects.empty());
466 SmallVector<unsigned, 32> StackObjectsIdx;
467 const int EndIdx = MFI.getObjectIndexEnd();
468 if (EndIdx > 0)
469 StackObjectsIdx.reserve(N: EndIdx);
470 ID = 0;
471 for (int I = 0; I < EndIdx; ++I, ++ID) {
472 StackObjectsIdx.push_back(Elt: -1); // Fill index for possible dead.
473 if (MFI.isDeadObjectIndex(ObjectIdx: I))
474 continue;
475
476 yaml::MachineStackObject YamlObject;
477 YamlObject.ID = ID;
478 if (const auto *Alloca = MFI.getObjectAllocation(ObjectIdx: I))
479 YamlObject.Name.Value = std::string(
480 Alloca->hasName() ? Alloca->getName() : "");
481 YamlObject.Type = MFI.isSpillSlotObjectIndex(ObjectIdx: I)
482 ? yaml::MachineStackObject::SpillSlot
483 : MFI.isVariableSizedObjectIndex(ObjectIdx: I)
484 ? yaml::MachineStackObject::VariableSized
485 : yaml::MachineStackObject::DefaultType;
486 YamlObject.Offset = MFI.getObjectOffset(ObjectIdx: I);
487 YamlObject.Size = MFI.getObjectSize(ObjectIdx: I);
488 YamlObject.Alignment = MFI.getObjectAlign(ObjectIdx: I);
489 YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(ObjectIdx: I);
490
491 // Save the ID' position in StackObjects storage vector.
492 StackObjectsIdx[ID] = YMF.StackObjects.size();
493 YMF.StackObjects.push_back(x: YamlObject);
494 State.StackObjectOperandMapping.insert(KV: std::make_pair(
495 x&: I, y: FrameIndexOperand::create(Name: YamlObject.Name.Value, ID)));
496 }
497
498 for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
499 const int FrameIdx = CSInfo.getFrameIdx();
500 if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(ObjectIdx: FrameIdx))
501 continue;
502
503 yaml::StringValue Reg;
504 printRegMIR(Reg: CSInfo.getReg(), Dest&: Reg, TRI);
505 if (!CSInfo.isSpilledToReg()) {
506 assert(FrameIdx >= MFI.getObjectIndexBegin() &&
507 FrameIdx < MFI.getObjectIndexEnd() &&
508 "Invalid stack object index");
509 if (FrameIdx < 0) { // Negative index means fixed objects.
510 auto &Object =
511 YMF.FixedStackObjects
512 [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
513 Object.CalleeSavedRegister = std::move(Reg);
514 Object.CalleeSavedRestored = CSInfo.isRestored();
515 } else {
516 auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
517 Object.CalleeSavedRegister = std::move(Reg);
518 Object.CalleeSavedRestored = CSInfo.isRestored();
519 }
520 }
521 }
522 for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
523 auto LocalObject = MFI.getLocalFrameObjectMap(i: I);
524 assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
525 YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
526 LocalObject.second;
527 }
528
529 // Print the stack object references in the frame information class after
530 // converting the stack objects.
531 if (MFI.hasStackProtectorIndex()) {
532 raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);
533 printStackObjectReference(OS&: StrOS, State, FrameIndex: MFI.getStackProtectorIndex());
534 }
535
536 if (MFI.hasFunctionContextIndex()) {
537 raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value);
538 printStackObjectReference(OS&: StrOS, State, FrameIndex: MFI.getFunctionContextIndex());
539 }
540
541 // Print the debug variable information.
542 for (const MachineFunction::VariableDbgInfo &DebugVar :
543 MF.getInStackSlotVariableDbgInfo()) {
544 int Idx = DebugVar.getStackSlot();
545 assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() &&
546 "Invalid stack object index");
547 if (Idx < 0) { // Negative index means fixed objects.
548 auto &Object =
549 YMF.FixedStackObjects[FixedStackObjectsIdx[Idx +
550 MFI.getNumFixedObjects()]];
551 printStackObjectDbgInfo(DebugVar, Object, MST);
552 } else {
553 auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]];
554 printStackObjectDbgInfo(DebugVar, Object, MST);
555 }
556 }
557}
558
559static void convertCallSiteObjects(yaml::MachineFunction &YMF,
560 const MachineFunction &MF,
561 ModuleSlotTracker &MST) {
562 const auto *TRI = MF.getSubtarget().getRegisterInfo();
563 for (auto [MI, CallSiteInfo] : MF.getCallSitesInfo()) {
564 yaml::CallSiteInfo YmlCS;
565 yaml::MachineInstrLoc CallLocation;
566
567 // Prepare instruction position.
568 MachineBasicBlock::const_instr_iterator CallI = MI->getIterator();
569 CallLocation.BlockNum = CallI->getParent()->getNumber();
570 // Get call instruction offset from the beginning of block.
571 CallLocation.Offset =
572 std::distance(first: CallI->getParent()->instr_begin(), last: CallI);
573 YmlCS.CallLocation = CallLocation;
574
575 auto [ArgRegPairs, CalleeTypeIds, _] = CallSiteInfo;
576 // Construct call arguments and theirs forwarding register info.
577 for (auto ArgReg : ArgRegPairs) {
578 yaml::CallSiteInfo::ArgRegPair YmlArgReg;
579 YmlArgReg.ArgNo = ArgReg.ArgNo;
580 printRegMIR(Reg: ArgReg.Reg, Dest&: YmlArgReg.Reg, TRI);
581 YmlCS.ArgForwardingRegs.emplace_back(args&: YmlArgReg);
582 }
583 // Get type ids.
584 for (auto *CalleeTypeId : CalleeTypeIds) {
585 YmlCS.CalleeTypeIds.push_back(x: CalleeTypeId->getZExtValue());
586 }
587 YMF.CallSitesInfo.push_back(x: std::move(YmlCS));
588 }
589
590 // Sort call info by position of call instructions.
591 llvm::sort(Start: YMF.CallSitesInfo.begin(), End: YMF.CallSitesInfo.end(),
592 Comp: [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {
593 return std::tie(args&: A.CallLocation.BlockNum, args&: A.CallLocation.Offset) <
594 std::tie(args&: B.CallLocation.BlockNum, args&: B.CallLocation.Offset);
595 });
596}
597
598static void convertMachineMetadataNodes(yaml::MachineFunction &YMF,
599 const MachineFunction &MF,
600 MachineModuleSlotTracker &MST) {
601 MachineModuleSlotTracker::MachineMDNodeListType MDList;
602 MST.collectMachineMDNodes(L&: MDList);
603 for (auto &MD : MDList) {
604 std::string NS;
605 raw_string_ostream StrOS(NS);
606 MD.second->print(OS&: StrOS, MST, M: MF.getFunction().getParent());
607 YMF.MachineMetadataNodes.push_back(x: std::move(NS));
608 }
609}
610
611static void convertCalledGlobals(yaml::MachineFunction &YMF,
612 const MachineFunction &MF,
613 MachineModuleSlotTracker &MST) {
614 for (const auto &[CallInst, CG] : MF.getCalledGlobals()) {
615 yaml::MachineInstrLoc CallSite;
616 CallSite.BlockNum = CallInst->getParent()->getNumber();
617 CallSite.Offset = std::distance(first: CallInst->getParent()->instr_begin(),
618 last: CallInst->getIterator());
619
620 yaml::CalledGlobal YamlCG{.CallSite: CallSite, .Callee: CG.Callee->getName().str(),
621 .Flags: CG.TargetFlags};
622 YMF.CalledGlobals.push_back(x: std::move(YamlCG));
623 }
624
625 // Sort by position of call instructions.
626 llvm::sort(Start: YMF.CalledGlobals.begin(), End: YMF.CalledGlobals.end(),
627 Comp: [](yaml::CalledGlobal A, yaml::CalledGlobal B) {
628 return std::tie(args&: A.CallSite.BlockNum, args&: A.CallSite.Offset) <
629 std::tie(args&: B.CallSite.BlockNum, args&: B.CallSite.Offset);
630 });
631}
632
633static void convertPrefetchTargets(yaml::MachineFunction &YMF,
634 const MachineFunction &MF) {
635 for (const auto &[BBID, CallsiteIndexes] : MF.getPrefetchTargets()) {
636 for (auto CallsiteIndex : CallsiteIndexes) {
637 std::string Str;
638 raw_string_ostream StrOS(Str);
639 StrOS << "bb_id " << BBID.BaseID << ", " << BBID.CloneID << ", "
640 << CallsiteIndex;
641 YMF.PrefetchTargets.push_back(x: yaml::FlowStringValue(Str));
642 }
643 }
644}
645
646static void convertMCP(yaml::MachineFunction &MF,
647 const MachineConstantPool &ConstantPool) {
648 unsigned ID = 0;
649 for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
650 std::string Str;
651 raw_string_ostream StrOS(Str);
652 if (Constant.isMachineConstantPoolEntry())
653 Constant.Val.MachineCPVal->print(O&: StrOS);
654 else
655 Constant.Val.ConstVal->printAsOperand(O&: StrOS);
656
657 yaml::MachineConstantPoolValue YamlConstant;
658 YamlConstant.ID = ID++;
659 YamlConstant.Value = std::move(Str);
660 YamlConstant.Alignment = Constant.getAlign();
661 YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();
662
663 MF.Constants.push_back(x: std::move(YamlConstant));
664 }
665}
666
667static void
668convertSRPoints(ModuleSlotTracker &MST,
669 std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,
670 const llvm::SaveRestorePoints &SRPoints,
671 const TargetRegisterInfo *TRI) {
672 for (const auto &[MBB, CSInfos] : SRPoints) {
673 SmallString<16> Str;
674 yaml::SaveRestorePointEntry Entry;
675 raw_svector_ostream StrOS(Str);
676 StrOS << printMBBReference(MBB: *MBB);
677 Entry.Point = StrOS.str().str();
678 Str.clear();
679 for (const CalleeSavedInfo &Info : CSInfos) {
680 if (Info.getReg()) {
681 StrOS << printReg(Reg: Info.getReg(), TRI);
682 Entry.Registers.push_back(x: StrOS.str().str());
683 Str.clear();
684 }
685 }
686 // Sort here needed for stable output for lit tests
687 std::sort(first: Entry.Registers.begin(), last: Entry.Registers.end(),
688 comp: [](const yaml::StringValue &Lhs, const yaml::StringValue &Rhs) {
689 return Lhs.Value < Rhs.Value;
690 });
691 YamlSRPoints.push_back(x: std::move(Entry));
692 }
693 // Sort here needed for stable output for lit tests
694 std::sort(first: YamlSRPoints.begin(), last: YamlSRPoints.end(),
695 comp: [](const yaml::SaveRestorePointEntry &Lhs,
696 const yaml::SaveRestorePointEntry &Rhs) {
697 return Lhs.Point.Value < Rhs.Point.Value;
698 });
699}
700
701static void convertMJTI(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
702 const MachineJumpTableInfo &JTI) {
703 YamlJTI.Kind = JTI.getEntryKind();
704 unsigned ID = 0;
705 for (const auto &Table : JTI.getJumpTables()) {
706 std::string Str;
707 yaml::MachineJumpTable::Entry Entry;
708 Entry.ID = ID++;
709 for (const auto *MBB : Table.MBBs) {
710 raw_string_ostream StrOS(Str);
711 StrOS << printMBBReference(MBB: *MBB);
712 Entry.Blocks.push_back(x: Str);
713 Str.clear();
714 }
715 YamlJTI.Entries.push_back(x: std::move(Entry));
716 }
717}
718
719void llvm::guessSuccessors(const MachineBasicBlock &MBB,
720 SmallVectorImpl<MachineBasicBlock*> &Result,
721 bool &IsFallthrough) {
722 SmallPtrSet<MachineBasicBlock*,8> Seen;
723
724 for (const MachineInstr &MI : MBB) {
725 if (MI.isPHI())
726 continue;
727 for (const MachineOperand &MO : MI.operands()) {
728 if (!MO.isMBB())
729 continue;
730 MachineBasicBlock *Succ = MO.getMBB();
731 auto RP = Seen.insert(Ptr: Succ);
732 if (RP.second)
733 Result.push_back(Elt: Succ);
734 }
735 }
736 MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
737 IsFallthrough = I == MBB.end() || !I->isBarrier();
738}
739
740static bool canPredictSuccessors(const MachineBasicBlock &MBB) {
741 SmallVector<MachineBasicBlock*,8> GuessedSuccs;
742 bool GuessedFallthrough;
743 guessSuccessors(MBB, Result&: GuessedSuccs, IsFallthrough&: GuessedFallthrough);
744 if (GuessedFallthrough) {
745 const MachineFunction &MF = *MBB.getParent();
746 MachineFunction::const_iterator NextI = std::next(x: MBB.getIterator());
747 if (NextI != MF.end()) {
748 MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);
749 if (!is_contained(Range&: GuessedSuccs, Element: Next))
750 GuessedSuccs.push_back(Elt: Next);
751 }
752 }
753 if (GuessedSuccs.size() != MBB.succ_size())
754 return false;
755 return std::equal(first1: MBB.succ_begin(), last1: MBB.succ_end(), first2: GuessedSuccs.begin());
756}
757
758static void printMI(raw_ostream &OS, MFPrintState &State,
759 const MachineInstr &MI);
760
761static void printMIOperand(raw_ostream &OS, MFPrintState &State,
762 const MachineInstr &MI, unsigned OpIdx,
763 const TargetRegisterInfo *TRI,
764 const TargetInstrInfo *TII,
765 bool ShouldPrintRegisterTies,
766 SmallBitVector &PrintedTypes,
767 const MachineRegisterInfo &MRI, bool PrintDef);
768
769void printMBB(raw_ostream &OS, MFPrintState &State,
770 const MachineBasicBlock &MBB) {
771 assert(MBB.getNumber() >= 0 && "Invalid MBB number");
772 MBB.printName(os&: OS,
773 printNameFlags: MachineBasicBlock::PrintNameIr |
774 MachineBasicBlock::PrintNameAttributes,
775 moduleSlotTracker: &State.MST);
776 OS << ":\n";
777
778 bool HasLineAttributes = false;
779 // Print the successors
780 bool canPredictProbs = MBB.canPredictBranchProbabilities();
781 // Even if the list of successors is empty, if we cannot guess it,
782 // we need to print it to tell the parser that the list is empty.
783 // This is needed, because MI model unreachable as empty blocks
784 // with an empty successor list. If the parser would see that
785 // without the successor list, it would guess the code would
786 // fallthrough.
787 if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||
788 !canPredictSuccessors(MBB)) {
789 OS.indent(NumSpaces: 2) << "successors:";
790 if (!MBB.succ_empty())
791 OS << " ";
792 ListSeparator LS;
793 for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
794 OS << LS << printMBBReference(MBB: **I);
795 if (!SimplifyMIR || !canPredictProbs)
796 OS << format(Fmt: "(0x%08" PRIx32 ")",
797 Vals: MBB.getSuccProbability(Succ: I).getNumerator());
798 }
799 OS << "\n";
800 HasLineAttributes = true;
801 }
802
803 // Print the live in registers.
804 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
805 if (!MBB.livein_empty()) {
806 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
807 OS.indent(NumSpaces: 2) << "liveins: ";
808 ListSeparator LS;
809 for (const auto &LI : MBB.liveins_dbg()) {
810 OS << LS << printReg(Reg: LI.PhysReg, TRI: &TRI);
811 if (!LI.LaneMask.all())
812 OS << ":0x" << PrintLaneMask(LaneMask: LI.LaneMask);
813 }
814 OS << "\n";
815 HasLineAttributes = true;
816 }
817
818 if (HasLineAttributes && !MBB.empty())
819 OS << "\n";
820 bool IsInBundle = false;
821 for (const MachineInstr &MI : MBB.instrs()) {
822 if (IsInBundle && !MI.isInsideBundle()) {
823 OS.indent(NumSpaces: 2) << "}\n";
824 IsInBundle = false;
825 }
826 OS.indent(NumSpaces: IsInBundle ? 4 : 2);
827 printMI(OS, State, MI);
828 if (!IsInBundle && MI.getFlag(Flag: MachineInstr::BundledSucc)) {
829 OS << " {";
830 IsInBundle = true;
831 }
832 OS << "\n";
833 }
834 if (IsInBundle)
835 OS.indent(NumSpaces: 2) << "}\n";
836}
837
838static void printMI(raw_ostream &OS, MFPrintState &State,
839 const MachineInstr &MI) {
840 const auto *MF = MI.getMF();
841 const auto &MRI = MF->getRegInfo();
842 const auto &SubTarget = MF->getSubtarget();
843 const auto *TRI = SubTarget.getRegisterInfo();
844 assert(TRI && "Expected target register info");
845 const auto *TII = SubTarget.getInstrInfo();
846 assert(TII && "Expected target instruction info");
847 if (MI.isCFIInstruction())
848 assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
849
850 SmallBitVector PrintedTypes(8);
851 bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();
852 ListSeparator LS;
853 unsigned I = 0, E = MI.getNumOperands();
854 for (; I < E; ++I) {
855 const MachineOperand MO = MI.getOperand(i: I);
856 if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
857 break;
858 OS << LS;
859 printMIOperand(OS, State, MI, OpIdx: I, TRI, TII, ShouldPrintRegisterTies,
860 PrintedTypes, MRI, /*PrintDef=*/false);
861 }
862
863 if (I)
864 OS << " = ";
865 if (MI.getFlag(Flag: MachineInstr::FrameSetup))
866 OS << "frame-setup ";
867 if (MI.getFlag(Flag: MachineInstr::FrameDestroy))
868 OS << "frame-destroy ";
869 if (MI.getFlag(Flag: MachineInstr::FmNoNans))
870 OS << "nnan ";
871 if (MI.getFlag(Flag: MachineInstr::FmNoInfs))
872 OS << "ninf ";
873 if (MI.getFlag(Flag: MachineInstr::FmNsz))
874 OS << "nsz ";
875 if (MI.getFlag(Flag: MachineInstr::FmArcp))
876 OS << "arcp ";
877 if (MI.getFlag(Flag: MachineInstr::FmContract))
878 OS << "contract ";
879 if (MI.getFlag(Flag: MachineInstr::FmAfn))
880 OS << "afn ";
881 if (MI.getFlag(Flag: MachineInstr::FmReassoc))
882 OS << "reassoc ";
883 if (MI.getFlag(Flag: MachineInstr::NoUWrap))
884 OS << "nuw ";
885 if (MI.getFlag(Flag: MachineInstr::NoSWrap))
886 OS << "nsw ";
887 if (MI.getFlag(Flag: MachineInstr::IsExact))
888 OS << "exact ";
889 if (MI.getFlag(Flag: MachineInstr::NoFPExcept))
890 OS << "nofpexcept ";
891 if (MI.getFlag(Flag: MachineInstr::NoMerge))
892 OS << "nomerge ";
893 if (MI.getFlag(Flag: MachineInstr::Unpredictable))
894 OS << "unpredictable ";
895 if (MI.getFlag(Flag: MachineInstr::NoConvergent))
896 OS << "noconvergent ";
897 if (MI.getFlag(Flag: MachineInstr::NonNeg))
898 OS << "nneg ";
899 if (MI.getFlag(Flag: MachineInstr::Disjoint))
900 OS << "disjoint ";
901 if (MI.getFlag(Flag: MachineInstr::NoUSWrap))
902 OS << "nusw ";
903 if (MI.getFlag(Flag: MachineInstr::SameSign))
904 OS << "samesign ";
905 if (MI.getFlag(Flag: MachineInstr::InBounds))
906 OS << "inbounds ";
907 if (MI.getFlag(Flag: MachineInstr::LRSplit))
908 OS << "lr-split ";
909 if (MI.getFlag(Flag: MachineInstr::NonNull))
910 OS << "nonnull ";
911
912 // NOTE: Please add new MIFlags also to the MI_FLAGS_STR in
913 // llvm/utils/UpdateTestChecks/mir.py.
914
915 OS << TII->getName(Opcode: MI.getOpcode());
916
917 // Print a space after the opcode if any additional tokens are printed.
918 LS = ListSeparator(", ", " ");
919
920 for (; I < E; ++I) {
921 OS << LS;
922 printMIOperand(OS, State, MI, OpIdx: I, TRI, TII, ShouldPrintRegisterTies,
923 PrintedTypes, MRI, /*PrintDef=*/true);
924 }
925
926 // Print any optional symbols attached to this instruction as-if they were
927 // operands.
928 if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {
929 OS << LS << "pre-instr-symbol ";
930 MachineOperand::printSymbol(OS, Sym&: *PreInstrSymbol);
931 }
932 if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {
933 OS << LS << "post-instr-symbol ";
934 MachineOperand::printSymbol(OS, Sym&: *PostInstrSymbol);
935 }
936 if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) {
937 OS << LS << "heap-alloc-marker ";
938 HeapAllocMarker->printAsOperand(OS, MST&: State.MST);
939 }
940 if (MDNode *PCSections = MI.getPCSections()) {
941 OS << LS << "pcsections ";
942 PCSections->printAsOperand(OS, MST&: State.MST);
943 }
944 if (MDNode *MMRA = MI.getMMRAMetadata()) {
945 OS << LS << "mmra ";
946 MMRA->printAsOperand(OS, MST&: State.MST);
947 }
948 if (uint32_t CFIType = MI.getCFIType())
949 OS << LS << "cfi-type " << CFIType;
950 if (Value *DS = MI.getDeactivationSymbol()) {
951 OS << LS << "deactivation-symbol ";
952 MIRFormatter::printIRValue(OS, V: *DS, MST&: State.MST);
953 }
954
955 if (auto Num = MI.peekDebugInstrNum())
956 OS << LS << "debug-instr-number " << Num;
957
958 if (PrintLocations) {
959 if (const DebugLoc &DL = MI.getDebugLoc()) {
960 OS << LS << "debug-location ";
961 DL->printAsOperand(OS, MST&: State.MST);
962 }
963 }
964
965 if (!MI.memoperands_empty()) {
966 OS << " :: ";
967 const LLVMContext &Context = MF->getFunction().getContext();
968 const MachineFrameInfo &MFI = MF->getFrameInfo();
969 LS = ListSeparator();
970 for (const auto *Op : MI.memoperands()) {
971 OS << LS;
972 Op->print(OS, MST&: State.MST, SSNs&: State.SSNs, Context, MFI: &MFI, TII);
973 }
974 }
975}
976
977static std::string formatOperandComment(std::string Comment) {
978 if (Comment.empty())
979 return Comment;
980 return std::string(" /* " + Comment + " */");
981}
982
983static void printMIOperand(raw_ostream &OS, MFPrintState &State,
984 const MachineInstr &MI, unsigned OpIdx,
985 const TargetRegisterInfo *TRI,
986 const TargetInstrInfo *TII,
987 bool ShouldPrintRegisterTies,
988 SmallBitVector &PrintedTypes,
989 const MachineRegisterInfo &MRI, bool PrintDef) {
990 LLT TypeToPrint = MI.getTypeToPrint(OpIdx, PrintedTypes, MRI);
991 const MachineOperand &Op = MI.getOperand(i: OpIdx);
992 std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx);
993
994 switch (Op.getType()) {
995 case MachineOperand::MO_Immediate:
996 if (MI.isOperandSubregIdx(OpIdx)) {
997 MachineOperand::printTargetFlags(OS, Op);
998 MachineOperand::printSubRegIdx(OS, Index: Op.getImm(), TRI);
999 break;
1000 }
1001 if (MI.isInlineAsm()) {
1002 if (OpIdx == InlineAsm::MIOp_ExtraInfo) {
1003 unsigned ExtraInfo = Op.getImm();
1004 interleave(c: InlineAsm::getExtraInfoNames(ExtraInfo), os&: OS, separator: " ");
1005 break;
1006 }
1007
1008 int FlagIdx = MI.findInlineAsmFlagIdx(OpIdx);
1009 if (FlagIdx >= 0 && (unsigned)FlagIdx == OpIdx) {
1010 InlineAsm::Flag F(Op.getImm());
1011 OS << F.getKindName();
1012
1013 unsigned RCID;
1014 if ((F.isRegDefKind() || F.isRegUseKind() ||
1015 F.isRegDefEarlyClobberKind()) &&
1016 F.hasRegClassConstraint(RC&: RCID))
1017 OS << ':' << TRI->getRegClassName(Class: TRI->getRegClass(i: RCID));
1018
1019 if (F.isMemKind()) {
1020 InlineAsm::ConstraintCode MCID = F.getMemoryConstraintID();
1021 OS << ':' << InlineAsm::getMemConstraintName(C: MCID);
1022 }
1023
1024 unsigned TiedTo;
1025 if (F.isUseOperandTiedToDef(Idx&: TiedTo))
1026 OS << " tiedto:$" << TiedTo;
1027 break;
1028 }
1029 }
1030 [[fallthrough]];
1031 case MachineOperand::MO_Register:
1032 case MachineOperand::MO_CImmediate:
1033 case MachineOperand::MO_FPImmediate:
1034 case MachineOperand::MO_MachineBasicBlock:
1035 case MachineOperand::MO_ConstantPoolIndex:
1036 case MachineOperand::MO_TargetIndex:
1037 case MachineOperand::MO_JumpTableIndex:
1038 case MachineOperand::MO_ExternalSymbol:
1039 case MachineOperand::MO_GlobalAddress:
1040 case MachineOperand::MO_RegisterLiveOut:
1041 case MachineOperand::MO_Metadata:
1042 case MachineOperand::MO_MCSymbol:
1043 case MachineOperand::MO_CFIIndex:
1044 case MachineOperand::MO_IntrinsicID:
1045 case MachineOperand::MO_Predicate:
1046 case MachineOperand::MO_BlockAddress:
1047 case MachineOperand::MO_DbgInstrRef:
1048 case MachineOperand::MO_ShuffleMask:
1049 case MachineOperand::MO_LaneMask: {
1050 unsigned TiedOperandIdx = 0;
1051 if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
1052 TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
1053 Op.print(os&: OS, MST&: State.MST, TypeToPrint, OpIdx, PrintDef,
1054 /*IsStandalone=*/false, ShouldPrintRegisterTies, TiedOperandIdx,
1055 TRI);
1056 OS << formatOperandComment(Comment: MOComment);
1057 break;
1058 }
1059 case MachineOperand::MO_FrameIndex:
1060 printStackObjectReference(OS, State, FrameIndex: Op.getIndex());
1061 break;
1062 case MachineOperand::MO_RegisterMask: {
1063 const auto &RegisterMaskIds = State.RegisterMaskIds;
1064 auto RegMaskInfo = RegisterMaskIds.find(Val: Op.getRegMask());
1065 if (RegMaskInfo != RegisterMaskIds.end())
1066 OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
1067 else
1068 printCustomRegMask(RegMask: Op.getRegMask(), OS, TRI);
1069 break;
1070 }
1071 }
1072}
1073
1074void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
1075 ModuleSlotTracker &MST) {
1076 if (isa<GlobalValue>(Val: V)) {
1077 V.printAsOperand(O&: OS, /*PrintType=*/false, MST);
1078 return;
1079 }
1080 if (isa<Constant>(Val: V)) {
1081 // Machine memory operands can load/store to/from constant value pointers.
1082 OS << '`';
1083 V.printAsOperand(O&: OS, /*PrintType=*/true, MST);
1084 OS << '`';
1085 return;
1086 }
1087 OS << "%ir.";
1088 if (V.hasName()) {
1089 printLLVMNameWithoutPrefix(OS, Name: V.getName());
1090 return;
1091 }
1092 int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(V: &V) : -1;
1093 MachineOperand::printIRSlotNumber(OS, Slot);
1094}
1095
1096void llvm::printMIR(raw_ostream &OS, const Module &M) {
1097 yaml::Output Out(OS);
1098 Out << const_cast<Module &>(M);
1099}
1100
1101void llvm::printMIR(raw_ostream &OS, const MachineModuleInfo &MMI,
1102 const MachineFunction &MF, const VirtRegMap *VRM) {
1103 printMF(
1104 OS, Fn: [&](const Function &F) { return MMI.getMachineFunction(F); }, MF,
1105 VRM);
1106}
1107
1108void llvm::printMIR(raw_ostream &OS, FunctionAnalysisManager &FAM,
1109 const MachineFunction &MF, const VirtRegMap *VRM) {
1110 printMF(
1111 OS,
1112 Fn: [&](const Function &F) {
1113 return &FAM.getResult<MachineFunctionAnalysis>(
1114 IR&: const_cast<Function &>(F))
1115 .getMF();
1116 },
1117 MF, VRM);
1118}
1119