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