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