1*9880d681SAndroid Build Coastguard Worker //===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the class that prints out the LLVM IR and machine
11*9880d681SAndroid Build Coastguard Worker // functions using the MIR serialization format.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "MIRPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MIRYamlMapping.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineMemOperand.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRPrintingPasses.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ModuleSlotTracker.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/YAMLTraits.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker using namespace llvm;
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker namespace {
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker /// This structure describes how to print out stack object references.
44*9880d681SAndroid Build Coastguard Worker struct FrameIndexOperand {
45*9880d681SAndroid Build Coastguard Worker std::string Name;
46*9880d681SAndroid Build Coastguard Worker unsigned ID;
47*9880d681SAndroid Build Coastguard Worker bool IsFixed;
48*9880d681SAndroid Build Coastguard Worker
FrameIndexOperand__anone8583c580111::FrameIndexOperand49*9880d681SAndroid Build Coastguard Worker FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
50*9880d681SAndroid Build Coastguard Worker : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker /// Return an ordinary stack object reference.
create__anone8583c580111::FrameIndexOperand53*9880d681SAndroid Build Coastguard Worker static FrameIndexOperand create(StringRef Name, unsigned ID) {
54*9880d681SAndroid Build Coastguard Worker return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker /// Return a fixed stack object reference.
createFixed__anone8583c580111::FrameIndexOperand58*9880d681SAndroid Build Coastguard Worker static FrameIndexOperand createFixed(unsigned ID) {
59*9880d681SAndroid Build Coastguard Worker return FrameIndexOperand("", ID, /*IsFixed=*/true);
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker };
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker namespace llvm {
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker /// This class prints out the machine functions using the MIR serialization
68*9880d681SAndroid Build Coastguard Worker /// format.
69*9880d681SAndroid Build Coastguard Worker class MIRPrinter {
70*9880d681SAndroid Build Coastguard Worker raw_ostream &OS;
71*9880d681SAndroid Build Coastguard Worker DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
72*9880d681SAndroid Build Coastguard Worker /// Maps from stack object indices to operand indices which will be used when
73*9880d681SAndroid Build Coastguard Worker /// printing frame index machine operands.
74*9880d681SAndroid Build Coastguard Worker DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker public:
MIRPrinter(raw_ostream & OS)77*9880d681SAndroid Build Coastguard Worker MIRPrinter(raw_ostream &OS) : OS(OS) {}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker void print(const MachineFunction &MF);
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
82*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI);
83*9880d681SAndroid Build Coastguard Worker void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
84*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo &MFI);
85*9880d681SAndroid Build Coastguard Worker void convert(yaml::MachineFunction &MF,
86*9880d681SAndroid Build Coastguard Worker const MachineConstantPool &ConstantPool);
87*9880d681SAndroid Build Coastguard Worker void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
88*9880d681SAndroid Build Coastguard Worker const MachineJumpTableInfo &JTI);
89*9880d681SAndroid Build Coastguard Worker void convertStackObjects(yaml::MachineFunction &MF,
90*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo &MFI, MachineModuleInfo &MMI,
91*9880d681SAndroid Build Coastguard Worker ModuleSlotTracker &MST,
92*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI);
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker private:
95*9880d681SAndroid Build Coastguard Worker void initRegisterMaskIds(const MachineFunction &MF);
96*9880d681SAndroid Build Coastguard Worker };
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker /// This class prints out the machine instructions using the MIR serialization
99*9880d681SAndroid Build Coastguard Worker /// format.
100*9880d681SAndroid Build Coastguard Worker class MIPrinter {
101*9880d681SAndroid Build Coastguard Worker raw_ostream &OS;
102*9880d681SAndroid Build Coastguard Worker ModuleSlotTracker &MST;
103*9880d681SAndroid Build Coastguard Worker const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
104*9880d681SAndroid Build Coastguard Worker const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker public:
MIPrinter(raw_ostream & OS,ModuleSlotTracker & MST,const DenseMap<const uint32_t *,unsigned> & RegisterMaskIds,const DenseMap<int,FrameIndexOperand> & StackObjectOperandMapping)107*9880d681SAndroid Build Coastguard Worker MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
108*9880d681SAndroid Build Coastguard Worker const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
109*9880d681SAndroid Build Coastguard Worker const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
110*9880d681SAndroid Build Coastguard Worker : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
111*9880d681SAndroid Build Coastguard Worker StackObjectOperandMapping(StackObjectOperandMapping) {}
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker void print(const MachineBasicBlock &MBB);
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker void print(const MachineInstr &MI);
116*9880d681SAndroid Build Coastguard Worker void printMBBReference(const MachineBasicBlock &MBB);
117*9880d681SAndroid Build Coastguard Worker void printIRBlockReference(const BasicBlock &BB);
118*9880d681SAndroid Build Coastguard Worker void printIRValueReference(const Value &V);
119*9880d681SAndroid Build Coastguard Worker void printStackObjectReference(int FrameIndex);
120*9880d681SAndroid Build Coastguard Worker void printOffset(int64_t Offset);
121*9880d681SAndroid Build Coastguard Worker void printTargetFlags(const MachineOperand &Op);
122*9880d681SAndroid Build Coastguard Worker void print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
123*9880d681SAndroid Build Coastguard Worker unsigned I, bool ShouldPrintRegisterTies,
124*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo *MRI = nullptr, bool IsDef = false);
125*9880d681SAndroid Build Coastguard Worker void print(const MachineMemOperand &Op);
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
128*9880d681SAndroid Build Coastguard Worker };
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker namespace llvm {
133*9880d681SAndroid Build Coastguard Worker namespace yaml {
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker /// This struct serializes the LLVM IR module.
136*9880d681SAndroid Build Coastguard Worker template <> struct BlockScalarTraits<Module> {
outputllvm::yaml::BlockScalarTraits137*9880d681SAndroid Build Coastguard Worker static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
138*9880d681SAndroid Build Coastguard Worker Mod.print(OS, nullptr);
139*9880d681SAndroid Build Coastguard Worker }
inputllvm::yaml::BlockScalarTraits140*9880d681SAndroid Build Coastguard Worker static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
141*9880d681SAndroid Build Coastguard Worker llvm_unreachable("LLVM Module is supposed to be parsed separately");
142*9880d681SAndroid Build Coastguard Worker return "";
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker };
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker } // end namespace yaml
147*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
148*9880d681SAndroid Build Coastguard Worker
printReg(unsigned Reg,raw_ostream & OS,const TargetRegisterInfo * TRI)149*9880d681SAndroid Build Coastguard Worker static void printReg(unsigned Reg, raw_ostream &OS,
150*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
151*9880d681SAndroid Build Coastguard Worker // TODO: Print Stack Slots.
152*9880d681SAndroid Build Coastguard Worker if (!Reg)
153*9880d681SAndroid Build Coastguard Worker OS << '_';
154*9880d681SAndroid Build Coastguard Worker else if (TargetRegisterInfo::isVirtualRegister(Reg))
155*9880d681SAndroid Build Coastguard Worker OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
156*9880d681SAndroid Build Coastguard Worker else if (Reg < TRI->getNumRegs())
157*9880d681SAndroid Build Coastguard Worker OS << '%' << StringRef(TRI->getName(Reg)).lower();
158*9880d681SAndroid Build Coastguard Worker else
159*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Can't print this kind of register yet");
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker
printReg(unsigned Reg,yaml::StringValue & Dest,const TargetRegisterInfo * TRI)162*9880d681SAndroid Build Coastguard Worker static void printReg(unsigned Reg, yaml::StringValue &Dest,
163*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
164*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Dest.Value);
165*9880d681SAndroid Build Coastguard Worker printReg(Reg, OS, TRI);
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
print(const MachineFunction & MF)168*9880d681SAndroid Build Coastguard Worker void MIRPrinter::print(const MachineFunction &MF) {
169*9880d681SAndroid Build Coastguard Worker initRegisterMaskIds(MF);
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker yaml::MachineFunction YamlMF;
172*9880d681SAndroid Build Coastguard Worker YamlMF.Name = MF.getName();
173*9880d681SAndroid Build Coastguard Worker YamlMF.Alignment = MF.getAlignment();
174*9880d681SAndroid Build Coastguard Worker YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
175*9880d681SAndroid Build Coastguard Worker YamlMF.HasInlineAsm = MF.hasInlineAsm();
176*9880d681SAndroid Build Coastguard Worker YamlMF.AllVRegsAllocated = MF.getProperties().hasProperty(
177*9880d681SAndroid Build Coastguard Worker MachineFunctionProperties::Property::AllVRegsAllocated);
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
180*9880d681SAndroid Build Coastguard Worker ModuleSlotTracker MST(MF.getFunction()->getParent());
181*9880d681SAndroid Build Coastguard Worker MST.incorporateFunction(*MF.getFunction());
182*9880d681SAndroid Build Coastguard Worker convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
183*9880d681SAndroid Build Coastguard Worker convertStackObjects(YamlMF, *MF.getFrameInfo(), MF.getMMI(), MST,
184*9880d681SAndroid Build Coastguard Worker MF.getSubtarget().getRegisterInfo());
185*9880d681SAndroid Build Coastguard Worker if (const auto *ConstantPool = MF.getConstantPool())
186*9880d681SAndroid Build Coastguard Worker convert(YamlMF, *ConstantPool);
187*9880d681SAndroid Build Coastguard Worker if (const auto *JumpTableInfo = MF.getJumpTableInfo())
188*9880d681SAndroid Build Coastguard Worker convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
189*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(YamlMF.Body.Value.Value);
190*9880d681SAndroid Build Coastguard Worker bool IsNewlineNeeded = false;
191*9880d681SAndroid Build Coastguard Worker for (const auto &MBB : MF) {
192*9880d681SAndroid Build Coastguard Worker if (IsNewlineNeeded)
193*9880d681SAndroid Build Coastguard Worker StrOS << "\n";
194*9880d681SAndroid Build Coastguard Worker MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
195*9880d681SAndroid Build Coastguard Worker .print(MBB);
196*9880d681SAndroid Build Coastguard Worker IsNewlineNeeded = true;
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker StrOS.flush();
199*9880d681SAndroid Build Coastguard Worker yaml::Output Out(OS);
200*9880d681SAndroid Build Coastguard Worker Out << YamlMF;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
convert(yaml::MachineFunction & MF,const MachineRegisterInfo & RegInfo,const TargetRegisterInfo * TRI)203*9880d681SAndroid Build Coastguard Worker void MIRPrinter::convert(yaml::MachineFunction &MF,
204*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo &RegInfo,
205*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
206*9880d681SAndroid Build Coastguard Worker MF.IsSSA = RegInfo.isSSA();
207*9880d681SAndroid Build Coastguard Worker MF.TracksRegLiveness = RegInfo.tracksLiveness();
208*9880d681SAndroid Build Coastguard Worker MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker // Print the virtual register definitions.
211*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
212*9880d681SAndroid Build Coastguard Worker unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
213*9880d681SAndroid Build Coastguard Worker yaml::VirtualRegisterDefinition VReg;
214*9880d681SAndroid Build Coastguard Worker VReg.ID = I;
215*9880d681SAndroid Build Coastguard Worker if (RegInfo.getRegClassOrNull(Reg))
216*9880d681SAndroid Build Coastguard Worker VReg.Class =
217*9880d681SAndroid Build Coastguard Worker StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
218*9880d681SAndroid Build Coastguard Worker else if (RegInfo.getRegBankOrNull(Reg))
219*9880d681SAndroid Build Coastguard Worker VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower();
220*9880d681SAndroid Build Coastguard Worker else {
221*9880d681SAndroid Build Coastguard Worker VReg.Class = std::string("_");
222*9880d681SAndroid Build Coastguard Worker assert(RegInfo.getSize(Reg) && "Generic registers must have a size");
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
225*9880d681SAndroid Build Coastguard Worker if (PreferredReg)
226*9880d681SAndroid Build Coastguard Worker printReg(PreferredReg, VReg.PreferredRegister, TRI);
227*9880d681SAndroid Build Coastguard Worker MF.VirtualRegisters.push_back(VReg);
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker // Print the live ins.
231*9880d681SAndroid Build Coastguard Worker for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
232*9880d681SAndroid Build Coastguard Worker yaml::MachineFunctionLiveIn LiveIn;
233*9880d681SAndroid Build Coastguard Worker printReg(I->first, LiveIn.Register, TRI);
234*9880d681SAndroid Build Coastguard Worker if (I->second)
235*9880d681SAndroid Build Coastguard Worker printReg(I->second, LiveIn.VirtualRegister, TRI);
236*9880d681SAndroid Build Coastguard Worker MF.LiveIns.push_back(LiveIn);
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker // The used physical register mask is printed as an inverted callee saved
239*9880d681SAndroid Build Coastguard Worker // register mask.
240*9880d681SAndroid Build Coastguard Worker const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask();
241*9880d681SAndroid Build Coastguard Worker if (UsedPhysRegMask.none())
242*9880d681SAndroid Build Coastguard Worker return;
243*9880d681SAndroid Build Coastguard Worker std::vector<yaml::FlowStringValue> CalleeSavedRegisters;
244*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) {
245*9880d681SAndroid Build Coastguard Worker if (!UsedPhysRegMask[I]) {
246*9880d681SAndroid Build Coastguard Worker yaml::FlowStringValue Reg;
247*9880d681SAndroid Build Coastguard Worker printReg(I, Reg, TRI);
248*9880d681SAndroid Build Coastguard Worker CalleeSavedRegisters.push_back(Reg);
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker MF.CalleeSavedRegisters = CalleeSavedRegisters;
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker
convert(ModuleSlotTracker & MST,yaml::MachineFrameInfo & YamlMFI,const MachineFrameInfo & MFI)254*9880d681SAndroid Build Coastguard Worker void MIRPrinter::convert(ModuleSlotTracker &MST,
255*9880d681SAndroid Build Coastguard Worker yaml::MachineFrameInfo &YamlMFI,
256*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo &MFI) {
257*9880d681SAndroid Build Coastguard Worker YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
258*9880d681SAndroid Build Coastguard Worker YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
259*9880d681SAndroid Build Coastguard Worker YamlMFI.HasStackMap = MFI.hasStackMap();
260*9880d681SAndroid Build Coastguard Worker YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
261*9880d681SAndroid Build Coastguard Worker YamlMFI.StackSize = MFI.getStackSize();
262*9880d681SAndroid Build Coastguard Worker YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
263*9880d681SAndroid Build Coastguard Worker YamlMFI.MaxAlignment = MFI.getMaxAlignment();
264*9880d681SAndroid Build Coastguard Worker YamlMFI.AdjustsStack = MFI.adjustsStack();
265*9880d681SAndroid Build Coastguard Worker YamlMFI.HasCalls = MFI.hasCalls();
266*9880d681SAndroid Build Coastguard Worker YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
267*9880d681SAndroid Build Coastguard Worker YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
268*9880d681SAndroid Build Coastguard Worker YamlMFI.HasVAStart = MFI.hasVAStart();
269*9880d681SAndroid Build Coastguard Worker YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
270*9880d681SAndroid Build Coastguard Worker if (MFI.getSavePoint()) {
271*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(YamlMFI.SavePoint.Value);
272*9880d681SAndroid Build Coastguard Worker MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
273*9880d681SAndroid Build Coastguard Worker .printMBBReference(*MFI.getSavePoint());
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker if (MFI.getRestorePoint()) {
276*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(YamlMFI.RestorePoint.Value);
277*9880d681SAndroid Build Coastguard Worker MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
278*9880d681SAndroid Build Coastguard Worker .printMBBReference(*MFI.getRestorePoint());
279*9880d681SAndroid Build Coastguard Worker }
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker
convertStackObjects(yaml::MachineFunction & MF,const MachineFrameInfo & MFI,MachineModuleInfo & MMI,ModuleSlotTracker & MST,const TargetRegisterInfo * TRI)282*9880d681SAndroid Build Coastguard Worker void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
283*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo &MFI,
284*9880d681SAndroid Build Coastguard Worker MachineModuleInfo &MMI,
285*9880d681SAndroid Build Coastguard Worker ModuleSlotTracker &MST,
286*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
287*9880d681SAndroid Build Coastguard Worker // Process fixed stack objects.
288*9880d681SAndroid Build Coastguard Worker unsigned ID = 0;
289*9880d681SAndroid Build Coastguard Worker for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
290*9880d681SAndroid Build Coastguard Worker if (MFI.isDeadObjectIndex(I))
291*9880d681SAndroid Build Coastguard Worker continue;
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker yaml::FixedMachineStackObject YamlObject;
294*9880d681SAndroid Build Coastguard Worker YamlObject.ID = ID;
295*9880d681SAndroid Build Coastguard Worker YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
296*9880d681SAndroid Build Coastguard Worker ? yaml::FixedMachineStackObject::SpillSlot
297*9880d681SAndroid Build Coastguard Worker : yaml::FixedMachineStackObject::DefaultType;
298*9880d681SAndroid Build Coastguard Worker YamlObject.Offset = MFI.getObjectOffset(I);
299*9880d681SAndroid Build Coastguard Worker YamlObject.Size = MFI.getObjectSize(I);
300*9880d681SAndroid Build Coastguard Worker YamlObject.Alignment = MFI.getObjectAlignment(I);
301*9880d681SAndroid Build Coastguard Worker YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
302*9880d681SAndroid Build Coastguard Worker YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
303*9880d681SAndroid Build Coastguard Worker MF.FixedStackObjects.push_back(YamlObject);
304*9880d681SAndroid Build Coastguard Worker StackObjectOperandMapping.insert(
305*9880d681SAndroid Build Coastguard Worker std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
306*9880d681SAndroid Build Coastguard Worker }
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker // Process ordinary stack objects.
309*9880d681SAndroid Build Coastguard Worker ID = 0;
310*9880d681SAndroid Build Coastguard Worker for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
311*9880d681SAndroid Build Coastguard Worker if (MFI.isDeadObjectIndex(I))
312*9880d681SAndroid Build Coastguard Worker continue;
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker yaml::MachineStackObject YamlObject;
315*9880d681SAndroid Build Coastguard Worker YamlObject.ID = ID;
316*9880d681SAndroid Build Coastguard Worker if (const auto *Alloca = MFI.getObjectAllocation(I))
317*9880d681SAndroid Build Coastguard Worker YamlObject.Name.Value =
318*9880d681SAndroid Build Coastguard Worker Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
319*9880d681SAndroid Build Coastguard Worker YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
320*9880d681SAndroid Build Coastguard Worker ? yaml::MachineStackObject::SpillSlot
321*9880d681SAndroid Build Coastguard Worker : MFI.isVariableSizedObjectIndex(I)
322*9880d681SAndroid Build Coastguard Worker ? yaml::MachineStackObject::VariableSized
323*9880d681SAndroid Build Coastguard Worker : yaml::MachineStackObject::DefaultType;
324*9880d681SAndroid Build Coastguard Worker YamlObject.Offset = MFI.getObjectOffset(I);
325*9880d681SAndroid Build Coastguard Worker YamlObject.Size = MFI.getObjectSize(I);
326*9880d681SAndroid Build Coastguard Worker YamlObject.Alignment = MFI.getObjectAlignment(I);
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker MF.StackObjects.push_back(YamlObject);
329*9880d681SAndroid Build Coastguard Worker StackObjectOperandMapping.insert(std::make_pair(
330*9880d681SAndroid Build Coastguard Worker I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
334*9880d681SAndroid Build Coastguard Worker yaml::StringValue Reg;
335*9880d681SAndroid Build Coastguard Worker printReg(CSInfo.getReg(), Reg, TRI);
336*9880d681SAndroid Build Coastguard Worker auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
337*9880d681SAndroid Build Coastguard Worker assert(StackObjectInfo != StackObjectOperandMapping.end() &&
338*9880d681SAndroid Build Coastguard Worker "Invalid stack object index");
339*9880d681SAndroid Build Coastguard Worker const FrameIndexOperand &StackObject = StackObjectInfo->second;
340*9880d681SAndroid Build Coastguard Worker if (StackObject.IsFixed)
341*9880d681SAndroid Build Coastguard Worker MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
342*9880d681SAndroid Build Coastguard Worker else
343*9880d681SAndroid Build Coastguard Worker MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
346*9880d681SAndroid Build Coastguard Worker auto LocalObject = MFI.getLocalFrameObjectMap(I);
347*9880d681SAndroid Build Coastguard Worker auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first);
348*9880d681SAndroid Build Coastguard Worker assert(StackObjectInfo != StackObjectOperandMapping.end() &&
349*9880d681SAndroid Build Coastguard Worker "Invalid stack object index");
350*9880d681SAndroid Build Coastguard Worker const FrameIndexOperand &StackObject = StackObjectInfo->second;
351*9880d681SAndroid Build Coastguard Worker assert(!StackObject.IsFixed && "Expected a locally mapped stack object");
352*9880d681SAndroid Build Coastguard Worker MF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second;
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker // Print the stack object references in the frame information class after
356*9880d681SAndroid Build Coastguard Worker // converting the stack objects.
357*9880d681SAndroid Build Coastguard Worker if (MFI.hasStackProtectorIndex()) {
358*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(MF.FrameInfo.StackProtector.Value);
359*9880d681SAndroid Build Coastguard Worker MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
360*9880d681SAndroid Build Coastguard Worker .printStackObjectReference(MFI.getStackProtectorIndex());
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker // Print the debug variable information.
364*9880d681SAndroid Build Coastguard Worker for (MachineModuleInfo::VariableDbgInfo &DebugVar :
365*9880d681SAndroid Build Coastguard Worker MMI.getVariableDbgInfo()) {
366*9880d681SAndroid Build Coastguard Worker auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot);
367*9880d681SAndroid Build Coastguard Worker assert(StackObjectInfo != StackObjectOperandMapping.end() &&
368*9880d681SAndroid Build Coastguard Worker "Invalid stack object index");
369*9880d681SAndroid Build Coastguard Worker const FrameIndexOperand &StackObject = StackObjectInfo->second;
370*9880d681SAndroid Build Coastguard Worker assert(!StackObject.IsFixed && "Expected a non-fixed stack object");
371*9880d681SAndroid Build Coastguard Worker auto &Object = MF.StackObjects[StackObject.ID];
372*9880d681SAndroid Build Coastguard Worker {
373*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(Object.DebugVar.Value);
374*9880d681SAndroid Build Coastguard Worker DebugVar.Var->printAsOperand(StrOS, MST);
375*9880d681SAndroid Build Coastguard Worker }
376*9880d681SAndroid Build Coastguard Worker {
377*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(Object.DebugExpr.Value);
378*9880d681SAndroid Build Coastguard Worker DebugVar.Expr->printAsOperand(StrOS, MST);
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker {
381*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(Object.DebugLoc.Value);
382*9880d681SAndroid Build Coastguard Worker DebugVar.Loc->printAsOperand(StrOS, MST);
383*9880d681SAndroid Build Coastguard Worker }
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker
convert(yaml::MachineFunction & MF,const MachineConstantPool & ConstantPool)387*9880d681SAndroid Build Coastguard Worker void MIRPrinter::convert(yaml::MachineFunction &MF,
388*9880d681SAndroid Build Coastguard Worker const MachineConstantPool &ConstantPool) {
389*9880d681SAndroid Build Coastguard Worker unsigned ID = 0;
390*9880d681SAndroid Build Coastguard Worker for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
391*9880d681SAndroid Build Coastguard Worker // TODO: Serialize target specific constant pool entries.
392*9880d681SAndroid Build Coastguard Worker if (Constant.isMachineConstantPoolEntry())
393*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Can't print target specific constant pool entries yet");
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker yaml::MachineConstantPoolValue YamlConstant;
396*9880d681SAndroid Build Coastguard Worker std::string Str;
397*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(Str);
398*9880d681SAndroid Build Coastguard Worker Constant.Val.ConstVal->printAsOperand(StrOS);
399*9880d681SAndroid Build Coastguard Worker YamlConstant.ID = ID++;
400*9880d681SAndroid Build Coastguard Worker YamlConstant.Value = StrOS.str();
401*9880d681SAndroid Build Coastguard Worker YamlConstant.Alignment = Constant.getAlignment();
402*9880d681SAndroid Build Coastguard Worker MF.Constants.push_back(YamlConstant);
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker }
405*9880d681SAndroid Build Coastguard Worker
convert(ModuleSlotTracker & MST,yaml::MachineJumpTable & YamlJTI,const MachineJumpTableInfo & JTI)406*9880d681SAndroid Build Coastguard Worker void MIRPrinter::convert(ModuleSlotTracker &MST,
407*9880d681SAndroid Build Coastguard Worker yaml::MachineJumpTable &YamlJTI,
408*9880d681SAndroid Build Coastguard Worker const MachineJumpTableInfo &JTI) {
409*9880d681SAndroid Build Coastguard Worker YamlJTI.Kind = JTI.getEntryKind();
410*9880d681SAndroid Build Coastguard Worker unsigned ID = 0;
411*9880d681SAndroid Build Coastguard Worker for (const auto &Table : JTI.getJumpTables()) {
412*9880d681SAndroid Build Coastguard Worker std::string Str;
413*9880d681SAndroid Build Coastguard Worker yaml::MachineJumpTable::Entry Entry;
414*9880d681SAndroid Build Coastguard Worker Entry.ID = ID++;
415*9880d681SAndroid Build Coastguard Worker for (const auto *MBB : Table.MBBs) {
416*9880d681SAndroid Build Coastguard Worker raw_string_ostream StrOS(Str);
417*9880d681SAndroid Build Coastguard Worker MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
418*9880d681SAndroid Build Coastguard Worker .printMBBReference(*MBB);
419*9880d681SAndroid Build Coastguard Worker Entry.Blocks.push_back(StrOS.str());
420*9880d681SAndroid Build Coastguard Worker Str.clear();
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker YamlJTI.Entries.push_back(Entry);
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker }
425*9880d681SAndroid Build Coastguard Worker
initRegisterMaskIds(const MachineFunction & MF)426*9880d681SAndroid Build Coastguard Worker void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
427*9880d681SAndroid Build Coastguard Worker const auto *TRI = MF.getSubtarget().getRegisterInfo();
428*9880d681SAndroid Build Coastguard Worker unsigned I = 0;
429*9880d681SAndroid Build Coastguard Worker for (const uint32_t *Mask : TRI->getRegMasks())
430*9880d681SAndroid Build Coastguard Worker RegisterMaskIds.insert(std::make_pair(Mask, I++));
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker
print(const MachineBasicBlock & MBB)433*9880d681SAndroid Build Coastguard Worker void MIPrinter::print(const MachineBasicBlock &MBB) {
434*9880d681SAndroid Build Coastguard Worker assert(MBB.getNumber() >= 0 && "Invalid MBB number");
435*9880d681SAndroid Build Coastguard Worker OS << "bb." << MBB.getNumber();
436*9880d681SAndroid Build Coastguard Worker bool HasAttributes = false;
437*9880d681SAndroid Build Coastguard Worker if (const auto *BB = MBB.getBasicBlock()) {
438*9880d681SAndroid Build Coastguard Worker if (BB->hasName()) {
439*9880d681SAndroid Build Coastguard Worker OS << "." << BB->getName();
440*9880d681SAndroid Build Coastguard Worker } else {
441*9880d681SAndroid Build Coastguard Worker HasAttributes = true;
442*9880d681SAndroid Build Coastguard Worker OS << " (";
443*9880d681SAndroid Build Coastguard Worker int Slot = MST.getLocalSlot(BB);
444*9880d681SAndroid Build Coastguard Worker if (Slot == -1)
445*9880d681SAndroid Build Coastguard Worker OS << "<ir-block badref>";
446*9880d681SAndroid Build Coastguard Worker else
447*9880d681SAndroid Build Coastguard Worker OS << (Twine("%ir-block.") + Twine(Slot)).str();
448*9880d681SAndroid Build Coastguard Worker }
449*9880d681SAndroid Build Coastguard Worker }
450*9880d681SAndroid Build Coastguard Worker if (MBB.hasAddressTaken()) {
451*9880d681SAndroid Build Coastguard Worker OS << (HasAttributes ? ", " : " (");
452*9880d681SAndroid Build Coastguard Worker OS << "address-taken";
453*9880d681SAndroid Build Coastguard Worker HasAttributes = true;
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker if (MBB.isEHPad()) {
456*9880d681SAndroid Build Coastguard Worker OS << (HasAttributes ? ", " : " (");
457*9880d681SAndroid Build Coastguard Worker OS << "landing-pad";
458*9880d681SAndroid Build Coastguard Worker HasAttributes = true;
459*9880d681SAndroid Build Coastguard Worker }
460*9880d681SAndroid Build Coastguard Worker if (MBB.getAlignment()) {
461*9880d681SAndroid Build Coastguard Worker OS << (HasAttributes ? ", " : " (");
462*9880d681SAndroid Build Coastguard Worker OS << "align " << MBB.getAlignment();
463*9880d681SAndroid Build Coastguard Worker HasAttributes = true;
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker if (HasAttributes)
466*9880d681SAndroid Build Coastguard Worker OS << ")";
467*9880d681SAndroid Build Coastguard Worker OS << ":\n";
468*9880d681SAndroid Build Coastguard Worker
469*9880d681SAndroid Build Coastguard Worker bool HasLineAttributes = false;
470*9880d681SAndroid Build Coastguard Worker // Print the successors
471*9880d681SAndroid Build Coastguard Worker if (!MBB.succ_empty()) {
472*9880d681SAndroid Build Coastguard Worker OS.indent(2) << "successors: ";
473*9880d681SAndroid Build Coastguard Worker for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {
474*9880d681SAndroid Build Coastguard Worker if (I != MBB.succ_begin())
475*9880d681SAndroid Build Coastguard Worker OS << ", ";
476*9880d681SAndroid Build Coastguard Worker printMBBReference(**I);
477*9880d681SAndroid Build Coastguard Worker if (MBB.hasSuccessorProbabilities())
478*9880d681SAndroid Build Coastguard Worker OS << '(' << MBB.getSuccProbability(I) << ')';
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker OS << "\n";
481*9880d681SAndroid Build Coastguard Worker HasLineAttributes = true;
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker // Print the live in registers.
485*9880d681SAndroid Build Coastguard Worker const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
486*9880d681SAndroid Build Coastguard Worker assert(TRI && "Expected target register info");
487*9880d681SAndroid Build Coastguard Worker if (!MBB.livein_empty()) {
488*9880d681SAndroid Build Coastguard Worker OS.indent(2) << "liveins: ";
489*9880d681SAndroid Build Coastguard Worker bool First = true;
490*9880d681SAndroid Build Coastguard Worker for (const auto &LI : MBB.liveins()) {
491*9880d681SAndroid Build Coastguard Worker if (!First)
492*9880d681SAndroid Build Coastguard Worker OS << ", ";
493*9880d681SAndroid Build Coastguard Worker First = false;
494*9880d681SAndroid Build Coastguard Worker printReg(LI.PhysReg, OS, TRI);
495*9880d681SAndroid Build Coastguard Worker if (LI.LaneMask != ~0u)
496*9880d681SAndroid Build Coastguard Worker OS << ':' << PrintLaneMask(LI.LaneMask);
497*9880d681SAndroid Build Coastguard Worker }
498*9880d681SAndroid Build Coastguard Worker OS << "\n";
499*9880d681SAndroid Build Coastguard Worker HasLineAttributes = true;
500*9880d681SAndroid Build Coastguard Worker }
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker if (HasLineAttributes)
503*9880d681SAndroid Build Coastguard Worker OS << "\n";
504*9880d681SAndroid Build Coastguard Worker bool IsInBundle = false;
505*9880d681SAndroid Build Coastguard Worker for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) {
506*9880d681SAndroid Build Coastguard Worker const MachineInstr &MI = *I;
507*9880d681SAndroid Build Coastguard Worker if (IsInBundle && !MI.isInsideBundle()) {
508*9880d681SAndroid Build Coastguard Worker OS.indent(2) << "}\n";
509*9880d681SAndroid Build Coastguard Worker IsInBundle = false;
510*9880d681SAndroid Build Coastguard Worker }
511*9880d681SAndroid Build Coastguard Worker OS.indent(IsInBundle ? 4 : 2);
512*9880d681SAndroid Build Coastguard Worker print(MI);
513*9880d681SAndroid Build Coastguard Worker if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {
514*9880d681SAndroid Build Coastguard Worker OS << " {";
515*9880d681SAndroid Build Coastguard Worker IsInBundle = true;
516*9880d681SAndroid Build Coastguard Worker }
517*9880d681SAndroid Build Coastguard Worker OS << "\n";
518*9880d681SAndroid Build Coastguard Worker }
519*9880d681SAndroid Build Coastguard Worker if (IsInBundle)
520*9880d681SAndroid Build Coastguard Worker OS.indent(2) << "}\n";
521*9880d681SAndroid Build Coastguard Worker }
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker /// Return true when an instruction has tied register that can't be determined
524*9880d681SAndroid Build Coastguard Worker /// by the instruction's descriptor.
hasComplexRegisterTies(const MachineInstr & MI)525*9880d681SAndroid Build Coastguard Worker static bool hasComplexRegisterTies(const MachineInstr &MI) {
526*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &MCID = MI.getDesc();
527*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
528*9880d681SAndroid Build Coastguard Worker const auto &Operand = MI.getOperand(I);
529*9880d681SAndroid Build Coastguard Worker if (!Operand.isReg() || Operand.isDef())
530*9880d681SAndroid Build Coastguard Worker // Ignore the defined registers as MCID marks only the uses as tied.
531*9880d681SAndroid Build Coastguard Worker continue;
532*9880d681SAndroid Build Coastguard Worker int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO);
533*9880d681SAndroid Build Coastguard Worker int TiedIdx = Operand.isTied() ? int(MI.findTiedOperandIdx(I)) : -1;
534*9880d681SAndroid Build Coastguard Worker if (ExpectedTiedIdx != TiedIdx)
535*9880d681SAndroid Build Coastguard Worker return true;
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker return false;
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker
print(const MachineInstr & MI)540*9880d681SAndroid Build Coastguard Worker void MIPrinter::print(const MachineInstr &MI) {
541*9880d681SAndroid Build Coastguard Worker const auto *MF = MI.getParent()->getParent();
542*9880d681SAndroid Build Coastguard Worker const auto &MRI = MF->getRegInfo();
543*9880d681SAndroid Build Coastguard Worker const auto &SubTarget = MF->getSubtarget();
544*9880d681SAndroid Build Coastguard Worker const auto *TRI = SubTarget.getRegisterInfo();
545*9880d681SAndroid Build Coastguard Worker assert(TRI && "Expected target register info");
546*9880d681SAndroid Build Coastguard Worker const auto *TII = SubTarget.getInstrInfo();
547*9880d681SAndroid Build Coastguard Worker assert(TII && "Expected target instruction info");
548*9880d681SAndroid Build Coastguard Worker if (MI.isCFIInstruction())
549*9880d681SAndroid Build Coastguard Worker assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
550*9880d681SAndroid Build Coastguard Worker
551*9880d681SAndroid Build Coastguard Worker bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI);
552*9880d681SAndroid Build Coastguard Worker unsigned I = 0, E = MI.getNumOperands();
553*9880d681SAndroid Build Coastguard Worker for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
554*9880d681SAndroid Build Coastguard Worker !MI.getOperand(I).isImplicit();
555*9880d681SAndroid Build Coastguard Worker ++I) {
556*9880d681SAndroid Build Coastguard Worker if (I)
557*9880d681SAndroid Build Coastguard Worker OS << ", ";
558*9880d681SAndroid Build Coastguard Worker print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, &MRI,
559*9880d681SAndroid Build Coastguard Worker /*IsDef=*/true);
560*9880d681SAndroid Build Coastguard Worker }
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker if (I)
563*9880d681SAndroid Build Coastguard Worker OS << " = ";
564*9880d681SAndroid Build Coastguard Worker if (MI.getFlag(MachineInstr::FrameSetup))
565*9880d681SAndroid Build Coastguard Worker OS << "frame-setup ";
566*9880d681SAndroid Build Coastguard Worker OS << TII->getName(MI.getOpcode());
567*9880d681SAndroid Build Coastguard Worker if (isPreISelGenericOpcode(MI.getOpcode())) {
568*9880d681SAndroid Build Coastguard Worker assert(MI.getType() && "Generic instructions must have a type");
569*9880d681SAndroid Build Coastguard Worker OS << ' ';
570*9880d681SAndroid Build Coastguard Worker MI.getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true);
571*9880d681SAndroid Build Coastguard Worker }
572*9880d681SAndroid Build Coastguard Worker if (I < E)
573*9880d681SAndroid Build Coastguard Worker OS << ' ';
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker bool NeedComma = false;
576*9880d681SAndroid Build Coastguard Worker for (; I < E; ++I) {
577*9880d681SAndroid Build Coastguard Worker if (NeedComma)
578*9880d681SAndroid Build Coastguard Worker OS << ", ";
579*9880d681SAndroid Build Coastguard Worker print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies);
580*9880d681SAndroid Build Coastguard Worker NeedComma = true;
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker if (MI.getDebugLoc()) {
584*9880d681SAndroid Build Coastguard Worker if (NeedComma)
585*9880d681SAndroid Build Coastguard Worker OS << ',';
586*9880d681SAndroid Build Coastguard Worker OS << " debug-location ";
587*9880d681SAndroid Build Coastguard Worker MI.getDebugLoc()->printAsOperand(OS, MST);
588*9880d681SAndroid Build Coastguard Worker }
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker if (!MI.memoperands_empty()) {
591*9880d681SAndroid Build Coastguard Worker OS << " :: ";
592*9880d681SAndroid Build Coastguard Worker bool NeedComma = false;
593*9880d681SAndroid Build Coastguard Worker for (const auto *Op : MI.memoperands()) {
594*9880d681SAndroid Build Coastguard Worker if (NeedComma)
595*9880d681SAndroid Build Coastguard Worker OS << ", ";
596*9880d681SAndroid Build Coastguard Worker print(*Op);
597*9880d681SAndroid Build Coastguard Worker NeedComma = true;
598*9880d681SAndroid Build Coastguard Worker }
599*9880d681SAndroid Build Coastguard Worker }
600*9880d681SAndroid Build Coastguard Worker }
601*9880d681SAndroid Build Coastguard Worker
printMBBReference(const MachineBasicBlock & MBB)602*9880d681SAndroid Build Coastguard Worker void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
603*9880d681SAndroid Build Coastguard Worker OS << "%bb." << MBB.getNumber();
604*9880d681SAndroid Build Coastguard Worker if (const auto *BB = MBB.getBasicBlock()) {
605*9880d681SAndroid Build Coastguard Worker if (BB->hasName())
606*9880d681SAndroid Build Coastguard Worker OS << '.' << BB->getName();
607*9880d681SAndroid Build Coastguard Worker }
608*9880d681SAndroid Build Coastguard Worker }
609*9880d681SAndroid Build Coastguard Worker
printIRSlotNumber(raw_ostream & OS,int Slot)610*9880d681SAndroid Build Coastguard Worker static void printIRSlotNumber(raw_ostream &OS, int Slot) {
611*9880d681SAndroid Build Coastguard Worker if (Slot == -1)
612*9880d681SAndroid Build Coastguard Worker OS << "<badref>";
613*9880d681SAndroid Build Coastguard Worker else
614*9880d681SAndroid Build Coastguard Worker OS << Slot;
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker
printIRBlockReference(const BasicBlock & BB)617*9880d681SAndroid Build Coastguard Worker void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
618*9880d681SAndroid Build Coastguard Worker OS << "%ir-block.";
619*9880d681SAndroid Build Coastguard Worker if (BB.hasName()) {
620*9880d681SAndroid Build Coastguard Worker printLLVMNameWithoutPrefix(OS, BB.getName());
621*9880d681SAndroid Build Coastguard Worker return;
622*9880d681SAndroid Build Coastguard Worker }
623*9880d681SAndroid Build Coastguard Worker const Function *F = BB.getParent();
624*9880d681SAndroid Build Coastguard Worker int Slot;
625*9880d681SAndroid Build Coastguard Worker if (F == MST.getCurrentFunction()) {
626*9880d681SAndroid Build Coastguard Worker Slot = MST.getLocalSlot(&BB);
627*9880d681SAndroid Build Coastguard Worker } else {
628*9880d681SAndroid Build Coastguard Worker ModuleSlotTracker CustomMST(F->getParent(),
629*9880d681SAndroid Build Coastguard Worker /*ShouldInitializeAllMetadata=*/false);
630*9880d681SAndroid Build Coastguard Worker CustomMST.incorporateFunction(*F);
631*9880d681SAndroid Build Coastguard Worker Slot = CustomMST.getLocalSlot(&BB);
632*9880d681SAndroid Build Coastguard Worker }
633*9880d681SAndroid Build Coastguard Worker printIRSlotNumber(OS, Slot);
634*9880d681SAndroid Build Coastguard Worker }
635*9880d681SAndroid Build Coastguard Worker
printIRValueReference(const Value & V)636*9880d681SAndroid Build Coastguard Worker void MIPrinter::printIRValueReference(const Value &V) {
637*9880d681SAndroid Build Coastguard Worker if (isa<GlobalValue>(V)) {
638*9880d681SAndroid Build Coastguard Worker V.printAsOperand(OS, /*PrintType=*/false, MST);
639*9880d681SAndroid Build Coastguard Worker return;
640*9880d681SAndroid Build Coastguard Worker }
641*9880d681SAndroid Build Coastguard Worker if (isa<Constant>(V)) {
642*9880d681SAndroid Build Coastguard Worker // Machine memory operands can load/store to/from constant value pointers.
643*9880d681SAndroid Build Coastguard Worker OS << '`';
644*9880d681SAndroid Build Coastguard Worker V.printAsOperand(OS, /*PrintType=*/true, MST);
645*9880d681SAndroid Build Coastguard Worker OS << '`';
646*9880d681SAndroid Build Coastguard Worker return;
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker OS << "%ir.";
649*9880d681SAndroid Build Coastguard Worker if (V.hasName()) {
650*9880d681SAndroid Build Coastguard Worker printLLVMNameWithoutPrefix(OS, V.getName());
651*9880d681SAndroid Build Coastguard Worker return;
652*9880d681SAndroid Build Coastguard Worker }
653*9880d681SAndroid Build Coastguard Worker printIRSlotNumber(OS, MST.getLocalSlot(&V));
654*9880d681SAndroid Build Coastguard Worker }
655*9880d681SAndroid Build Coastguard Worker
printStackObjectReference(int FrameIndex)656*9880d681SAndroid Build Coastguard Worker void MIPrinter::printStackObjectReference(int FrameIndex) {
657*9880d681SAndroid Build Coastguard Worker auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
658*9880d681SAndroid Build Coastguard Worker assert(ObjectInfo != StackObjectOperandMapping.end() &&
659*9880d681SAndroid Build Coastguard Worker "Invalid frame index");
660*9880d681SAndroid Build Coastguard Worker const FrameIndexOperand &Operand = ObjectInfo->second;
661*9880d681SAndroid Build Coastguard Worker if (Operand.IsFixed) {
662*9880d681SAndroid Build Coastguard Worker OS << "%fixed-stack." << Operand.ID;
663*9880d681SAndroid Build Coastguard Worker return;
664*9880d681SAndroid Build Coastguard Worker }
665*9880d681SAndroid Build Coastguard Worker OS << "%stack." << Operand.ID;
666*9880d681SAndroid Build Coastguard Worker if (!Operand.Name.empty())
667*9880d681SAndroid Build Coastguard Worker OS << '.' << Operand.Name;
668*9880d681SAndroid Build Coastguard Worker }
669*9880d681SAndroid Build Coastguard Worker
printOffset(int64_t Offset)670*9880d681SAndroid Build Coastguard Worker void MIPrinter::printOffset(int64_t Offset) {
671*9880d681SAndroid Build Coastguard Worker if (Offset == 0)
672*9880d681SAndroid Build Coastguard Worker return;
673*9880d681SAndroid Build Coastguard Worker if (Offset < 0) {
674*9880d681SAndroid Build Coastguard Worker OS << " - " << -Offset;
675*9880d681SAndroid Build Coastguard Worker return;
676*9880d681SAndroid Build Coastguard Worker }
677*9880d681SAndroid Build Coastguard Worker OS << " + " << Offset;
678*9880d681SAndroid Build Coastguard Worker }
679*9880d681SAndroid Build Coastguard Worker
getTargetFlagName(const TargetInstrInfo * TII,unsigned TF)680*9880d681SAndroid Build Coastguard Worker static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
681*9880d681SAndroid Build Coastguard Worker auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
682*9880d681SAndroid Build Coastguard Worker for (const auto &I : Flags) {
683*9880d681SAndroid Build Coastguard Worker if (I.first == TF) {
684*9880d681SAndroid Build Coastguard Worker return I.second;
685*9880d681SAndroid Build Coastguard Worker }
686*9880d681SAndroid Build Coastguard Worker }
687*9880d681SAndroid Build Coastguard Worker return nullptr;
688*9880d681SAndroid Build Coastguard Worker }
689*9880d681SAndroid Build Coastguard Worker
printTargetFlags(const MachineOperand & Op)690*9880d681SAndroid Build Coastguard Worker void MIPrinter::printTargetFlags(const MachineOperand &Op) {
691*9880d681SAndroid Build Coastguard Worker if (!Op.getTargetFlags())
692*9880d681SAndroid Build Coastguard Worker return;
693*9880d681SAndroid Build Coastguard Worker const auto *TII =
694*9880d681SAndroid Build Coastguard Worker Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo();
695*9880d681SAndroid Build Coastguard Worker assert(TII && "expected instruction info");
696*9880d681SAndroid Build Coastguard Worker auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
697*9880d681SAndroid Build Coastguard Worker OS << "target-flags(";
698*9880d681SAndroid Build Coastguard Worker const bool HasDirectFlags = Flags.first;
699*9880d681SAndroid Build Coastguard Worker const bool HasBitmaskFlags = Flags.second;
700*9880d681SAndroid Build Coastguard Worker if (!HasDirectFlags && !HasBitmaskFlags) {
701*9880d681SAndroid Build Coastguard Worker OS << "<unknown>) ";
702*9880d681SAndroid Build Coastguard Worker return;
703*9880d681SAndroid Build Coastguard Worker }
704*9880d681SAndroid Build Coastguard Worker if (HasDirectFlags) {
705*9880d681SAndroid Build Coastguard Worker if (const auto *Name = getTargetFlagName(TII, Flags.first))
706*9880d681SAndroid Build Coastguard Worker OS << Name;
707*9880d681SAndroid Build Coastguard Worker else
708*9880d681SAndroid Build Coastguard Worker OS << "<unknown target flag>";
709*9880d681SAndroid Build Coastguard Worker }
710*9880d681SAndroid Build Coastguard Worker if (!HasBitmaskFlags) {
711*9880d681SAndroid Build Coastguard Worker OS << ") ";
712*9880d681SAndroid Build Coastguard Worker return;
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker bool IsCommaNeeded = HasDirectFlags;
715*9880d681SAndroid Build Coastguard Worker unsigned BitMask = Flags.second;
716*9880d681SAndroid Build Coastguard Worker auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
717*9880d681SAndroid Build Coastguard Worker for (const auto &Mask : BitMasks) {
718*9880d681SAndroid Build Coastguard Worker // Check if the flag's bitmask has the bits of the current mask set.
719*9880d681SAndroid Build Coastguard Worker if ((BitMask & Mask.first) == Mask.first) {
720*9880d681SAndroid Build Coastguard Worker if (IsCommaNeeded)
721*9880d681SAndroid Build Coastguard Worker OS << ", ";
722*9880d681SAndroid Build Coastguard Worker IsCommaNeeded = true;
723*9880d681SAndroid Build Coastguard Worker OS << Mask.second;
724*9880d681SAndroid Build Coastguard Worker // Clear the bits which were serialized from the flag's bitmask.
725*9880d681SAndroid Build Coastguard Worker BitMask &= ~(Mask.first);
726*9880d681SAndroid Build Coastguard Worker }
727*9880d681SAndroid Build Coastguard Worker }
728*9880d681SAndroid Build Coastguard Worker if (BitMask) {
729*9880d681SAndroid Build Coastguard Worker // When the resulting flag's bitmask isn't zero, we know that we didn't
730*9880d681SAndroid Build Coastguard Worker // serialize all of the bit flags.
731*9880d681SAndroid Build Coastguard Worker if (IsCommaNeeded)
732*9880d681SAndroid Build Coastguard Worker OS << ", ";
733*9880d681SAndroid Build Coastguard Worker OS << "<unknown bitmask target flag>";
734*9880d681SAndroid Build Coastguard Worker }
735*9880d681SAndroid Build Coastguard Worker OS << ") ";
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker
getTargetIndexName(const MachineFunction & MF,int Index)738*9880d681SAndroid Build Coastguard Worker static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
739*9880d681SAndroid Build Coastguard Worker const auto *TII = MF.getSubtarget().getInstrInfo();
740*9880d681SAndroid Build Coastguard Worker assert(TII && "expected instruction info");
741*9880d681SAndroid Build Coastguard Worker auto Indices = TII->getSerializableTargetIndices();
742*9880d681SAndroid Build Coastguard Worker for (const auto &I : Indices) {
743*9880d681SAndroid Build Coastguard Worker if (I.first == Index) {
744*9880d681SAndroid Build Coastguard Worker return I.second;
745*9880d681SAndroid Build Coastguard Worker }
746*9880d681SAndroid Build Coastguard Worker }
747*9880d681SAndroid Build Coastguard Worker return nullptr;
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker
print(const MachineOperand & Op,const TargetRegisterInfo * TRI,unsigned I,bool ShouldPrintRegisterTies,const MachineRegisterInfo * MRI,bool IsDef)750*9880d681SAndroid Build Coastguard Worker void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
751*9880d681SAndroid Build Coastguard Worker unsigned I, bool ShouldPrintRegisterTies,
752*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo *MRI, bool IsDef) {
753*9880d681SAndroid Build Coastguard Worker printTargetFlags(Op);
754*9880d681SAndroid Build Coastguard Worker switch (Op.getType()) {
755*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Register:
756*9880d681SAndroid Build Coastguard Worker if (Op.isImplicit())
757*9880d681SAndroid Build Coastguard Worker OS << (Op.isDef() ? "implicit-def " : "implicit ");
758*9880d681SAndroid Build Coastguard Worker else if (!IsDef && Op.isDef())
759*9880d681SAndroid Build Coastguard Worker // Print the 'def' flag only when the operand is defined after '='.
760*9880d681SAndroid Build Coastguard Worker OS << "def ";
761*9880d681SAndroid Build Coastguard Worker if (Op.isInternalRead())
762*9880d681SAndroid Build Coastguard Worker OS << "internal ";
763*9880d681SAndroid Build Coastguard Worker if (Op.isDead())
764*9880d681SAndroid Build Coastguard Worker OS << "dead ";
765*9880d681SAndroid Build Coastguard Worker if (Op.isKill())
766*9880d681SAndroid Build Coastguard Worker OS << "killed ";
767*9880d681SAndroid Build Coastguard Worker if (Op.isUndef())
768*9880d681SAndroid Build Coastguard Worker OS << "undef ";
769*9880d681SAndroid Build Coastguard Worker if (Op.isEarlyClobber())
770*9880d681SAndroid Build Coastguard Worker OS << "early-clobber ";
771*9880d681SAndroid Build Coastguard Worker if (Op.isDebug())
772*9880d681SAndroid Build Coastguard Worker OS << "debug-use ";
773*9880d681SAndroid Build Coastguard Worker printReg(Op.getReg(), OS, TRI);
774*9880d681SAndroid Build Coastguard Worker // Print the sub register.
775*9880d681SAndroid Build Coastguard Worker if (Op.getSubReg() != 0)
776*9880d681SAndroid Build Coastguard Worker OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
777*9880d681SAndroid Build Coastguard Worker if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef())
778*9880d681SAndroid Build Coastguard Worker OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")";
779*9880d681SAndroid Build Coastguard Worker assert((!IsDef || MRI) && "for IsDef, MRI must be provided");
780*9880d681SAndroid Build Coastguard Worker if (IsDef && MRI->getSize(Op.getReg()))
781*9880d681SAndroid Build Coastguard Worker OS << '(' << MRI->getSize(Op.getReg()) << ')';
782*9880d681SAndroid Build Coastguard Worker break;
783*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Immediate:
784*9880d681SAndroid Build Coastguard Worker OS << Op.getImm();
785*9880d681SAndroid Build Coastguard Worker break;
786*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_CImmediate:
787*9880d681SAndroid Build Coastguard Worker Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
788*9880d681SAndroid Build Coastguard Worker break;
789*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_FPImmediate:
790*9880d681SAndroid Build Coastguard Worker Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
791*9880d681SAndroid Build Coastguard Worker break;
792*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_MachineBasicBlock:
793*9880d681SAndroid Build Coastguard Worker printMBBReference(*Op.getMBB());
794*9880d681SAndroid Build Coastguard Worker break;
795*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_FrameIndex:
796*9880d681SAndroid Build Coastguard Worker printStackObjectReference(Op.getIndex());
797*9880d681SAndroid Build Coastguard Worker break;
798*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ConstantPoolIndex:
799*9880d681SAndroid Build Coastguard Worker OS << "%const." << Op.getIndex();
800*9880d681SAndroid Build Coastguard Worker printOffset(Op.getOffset());
801*9880d681SAndroid Build Coastguard Worker break;
802*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_TargetIndex: {
803*9880d681SAndroid Build Coastguard Worker OS << "target-index(";
804*9880d681SAndroid Build Coastguard Worker if (const auto *Name = getTargetIndexName(
805*9880d681SAndroid Build Coastguard Worker *Op.getParent()->getParent()->getParent(), Op.getIndex()))
806*9880d681SAndroid Build Coastguard Worker OS << Name;
807*9880d681SAndroid Build Coastguard Worker else
808*9880d681SAndroid Build Coastguard Worker OS << "<unknown>";
809*9880d681SAndroid Build Coastguard Worker OS << ')';
810*9880d681SAndroid Build Coastguard Worker printOffset(Op.getOffset());
811*9880d681SAndroid Build Coastguard Worker break;
812*9880d681SAndroid Build Coastguard Worker }
813*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_JumpTableIndex:
814*9880d681SAndroid Build Coastguard Worker OS << "%jump-table." << Op.getIndex();
815*9880d681SAndroid Build Coastguard Worker break;
816*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ExternalSymbol:
817*9880d681SAndroid Build Coastguard Worker OS << '$';
818*9880d681SAndroid Build Coastguard Worker printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
819*9880d681SAndroid Build Coastguard Worker printOffset(Op.getOffset());
820*9880d681SAndroid Build Coastguard Worker break;
821*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_GlobalAddress:
822*9880d681SAndroid Build Coastguard Worker Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
823*9880d681SAndroid Build Coastguard Worker printOffset(Op.getOffset());
824*9880d681SAndroid Build Coastguard Worker break;
825*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_BlockAddress:
826*9880d681SAndroid Build Coastguard Worker OS << "blockaddress(";
827*9880d681SAndroid Build Coastguard Worker Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
828*9880d681SAndroid Build Coastguard Worker MST);
829*9880d681SAndroid Build Coastguard Worker OS << ", ";
830*9880d681SAndroid Build Coastguard Worker printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
831*9880d681SAndroid Build Coastguard Worker OS << ')';
832*9880d681SAndroid Build Coastguard Worker printOffset(Op.getOffset());
833*9880d681SAndroid Build Coastguard Worker break;
834*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_RegisterMask: {
835*9880d681SAndroid Build Coastguard Worker auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
836*9880d681SAndroid Build Coastguard Worker if (RegMaskInfo != RegisterMaskIds.end())
837*9880d681SAndroid Build Coastguard Worker OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
838*9880d681SAndroid Build Coastguard Worker else
839*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Can't print this machine register mask yet.");
840*9880d681SAndroid Build Coastguard Worker break;
841*9880d681SAndroid Build Coastguard Worker }
842*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_RegisterLiveOut: {
843*9880d681SAndroid Build Coastguard Worker const uint32_t *RegMask = Op.getRegLiveOut();
844*9880d681SAndroid Build Coastguard Worker OS << "liveout(";
845*9880d681SAndroid Build Coastguard Worker bool IsCommaNeeded = false;
846*9880d681SAndroid Build Coastguard Worker for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
847*9880d681SAndroid Build Coastguard Worker if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
848*9880d681SAndroid Build Coastguard Worker if (IsCommaNeeded)
849*9880d681SAndroid Build Coastguard Worker OS << ", ";
850*9880d681SAndroid Build Coastguard Worker printReg(Reg, OS, TRI);
851*9880d681SAndroid Build Coastguard Worker IsCommaNeeded = true;
852*9880d681SAndroid Build Coastguard Worker }
853*9880d681SAndroid Build Coastguard Worker }
854*9880d681SAndroid Build Coastguard Worker OS << ")";
855*9880d681SAndroid Build Coastguard Worker break;
856*9880d681SAndroid Build Coastguard Worker }
857*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Metadata:
858*9880d681SAndroid Build Coastguard Worker Op.getMetadata()->printAsOperand(OS, MST);
859*9880d681SAndroid Build Coastguard Worker break;
860*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_MCSymbol:
861*9880d681SAndroid Build Coastguard Worker OS << "<mcsymbol " << *Op.getMCSymbol() << ">";
862*9880d681SAndroid Build Coastguard Worker break;
863*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_CFIIndex: {
864*9880d681SAndroid Build Coastguard Worker const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
865*9880d681SAndroid Build Coastguard Worker print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
866*9880d681SAndroid Build Coastguard Worker break;
867*9880d681SAndroid Build Coastguard Worker }
868*9880d681SAndroid Build Coastguard Worker }
869*9880d681SAndroid Build Coastguard Worker }
870*9880d681SAndroid Build Coastguard Worker
print(const MachineMemOperand & Op)871*9880d681SAndroid Build Coastguard Worker void MIPrinter::print(const MachineMemOperand &Op) {
872*9880d681SAndroid Build Coastguard Worker OS << '(';
873*9880d681SAndroid Build Coastguard Worker // TODO: Print operand's target specific flags.
874*9880d681SAndroid Build Coastguard Worker if (Op.isVolatile())
875*9880d681SAndroid Build Coastguard Worker OS << "volatile ";
876*9880d681SAndroid Build Coastguard Worker if (Op.isNonTemporal())
877*9880d681SAndroid Build Coastguard Worker OS << "non-temporal ";
878*9880d681SAndroid Build Coastguard Worker if (Op.isInvariant())
879*9880d681SAndroid Build Coastguard Worker OS << "invariant ";
880*9880d681SAndroid Build Coastguard Worker if (Op.isLoad())
881*9880d681SAndroid Build Coastguard Worker OS << "load ";
882*9880d681SAndroid Build Coastguard Worker else {
883*9880d681SAndroid Build Coastguard Worker assert(Op.isStore() && "Non load machine operand must be a store");
884*9880d681SAndroid Build Coastguard Worker OS << "store ";
885*9880d681SAndroid Build Coastguard Worker }
886*9880d681SAndroid Build Coastguard Worker OS << Op.getSize();
887*9880d681SAndroid Build Coastguard Worker if (const Value *Val = Op.getValue()) {
888*9880d681SAndroid Build Coastguard Worker OS << (Op.isLoad() ? " from " : " into ");
889*9880d681SAndroid Build Coastguard Worker printIRValueReference(*Val);
890*9880d681SAndroid Build Coastguard Worker } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) {
891*9880d681SAndroid Build Coastguard Worker OS << (Op.isLoad() ? " from " : " into ");
892*9880d681SAndroid Build Coastguard Worker assert(PVal && "Expected a pseudo source value");
893*9880d681SAndroid Build Coastguard Worker switch (PVal->kind()) {
894*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::Stack:
895*9880d681SAndroid Build Coastguard Worker OS << "stack";
896*9880d681SAndroid Build Coastguard Worker break;
897*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::GOT:
898*9880d681SAndroid Build Coastguard Worker OS << "got";
899*9880d681SAndroid Build Coastguard Worker break;
900*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::JumpTable:
901*9880d681SAndroid Build Coastguard Worker OS << "jump-table";
902*9880d681SAndroid Build Coastguard Worker break;
903*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::ConstantPool:
904*9880d681SAndroid Build Coastguard Worker OS << "constant-pool";
905*9880d681SAndroid Build Coastguard Worker break;
906*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::FixedStack:
907*9880d681SAndroid Build Coastguard Worker printStackObjectReference(
908*9880d681SAndroid Build Coastguard Worker cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex());
909*9880d681SAndroid Build Coastguard Worker break;
910*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::GlobalValueCallEntry:
911*9880d681SAndroid Build Coastguard Worker OS << "call-entry ";
912*9880d681SAndroid Build Coastguard Worker cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
913*9880d681SAndroid Build Coastguard Worker OS, /*PrintType=*/false, MST);
914*9880d681SAndroid Build Coastguard Worker break;
915*9880d681SAndroid Build Coastguard Worker case PseudoSourceValue::ExternalSymbolCallEntry:
916*9880d681SAndroid Build Coastguard Worker OS << "call-entry $";
917*9880d681SAndroid Build Coastguard Worker printLLVMNameWithoutPrefix(
918*9880d681SAndroid Build Coastguard Worker OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
919*9880d681SAndroid Build Coastguard Worker break;
920*9880d681SAndroid Build Coastguard Worker }
921*9880d681SAndroid Build Coastguard Worker }
922*9880d681SAndroid Build Coastguard Worker printOffset(Op.getOffset());
923*9880d681SAndroid Build Coastguard Worker if (Op.getBaseAlignment() != Op.getSize())
924*9880d681SAndroid Build Coastguard Worker OS << ", align " << Op.getBaseAlignment();
925*9880d681SAndroid Build Coastguard Worker auto AAInfo = Op.getAAInfo();
926*9880d681SAndroid Build Coastguard Worker if (AAInfo.TBAA) {
927*9880d681SAndroid Build Coastguard Worker OS << ", !tbaa ";
928*9880d681SAndroid Build Coastguard Worker AAInfo.TBAA->printAsOperand(OS, MST);
929*9880d681SAndroid Build Coastguard Worker }
930*9880d681SAndroid Build Coastguard Worker if (AAInfo.Scope) {
931*9880d681SAndroid Build Coastguard Worker OS << ", !alias.scope ";
932*9880d681SAndroid Build Coastguard Worker AAInfo.Scope->printAsOperand(OS, MST);
933*9880d681SAndroid Build Coastguard Worker }
934*9880d681SAndroid Build Coastguard Worker if (AAInfo.NoAlias) {
935*9880d681SAndroid Build Coastguard Worker OS << ", !noalias ";
936*9880d681SAndroid Build Coastguard Worker AAInfo.NoAlias->printAsOperand(OS, MST);
937*9880d681SAndroid Build Coastguard Worker }
938*9880d681SAndroid Build Coastguard Worker if (Op.getRanges()) {
939*9880d681SAndroid Build Coastguard Worker OS << ", !range ";
940*9880d681SAndroid Build Coastguard Worker Op.getRanges()->printAsOperand(OS, MST);
941*9880d681SAndroid Build Coastguard Worker }
942*9880d681SAndroid Build Coastguard Worker OS << ')';
943*9880d681SAndroid Build Coastguard Worker }
944*9880d681SAndroid Build Coastguard Worker
printCFIRegister(unsigned DwarfReg,raw_ostream & OS,const TargetRegisterInfo * TRI)945*9880d681SAndroid Build Coastguard Worker static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
946*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
947*9880d681SAndroid Build Coastguard Worker int Reg = TRI->getLLVMRegNum(DwarfReg, true);
948*9880d681SAndroid Build Coastguard Worker if (Reg == -1) {
949*9880d681SAndroid Build Coastguard Worker OS << "<badreg>";
950*9880d681SAndroid Build Coastguard Worker return;
951*9880d681SAndroid Build Coastguard Worker }
952*9880d681SAndroid Build Coastguard Worker printReg(Reg, OS, TRI);
953*9880d681SAndroid Build Coastguard Worker }
954*9880d681SAndroid Build Coastguard Worker
print(const MCCFIInstruction & CFI,const TargetRegisterInfo * TRI)955*9880d681SAndroid Build Coastguard Worker void MIPrinter::print(const MCCFIInstruction &CFI,
956*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
957*9880d681SAndroid Build Coastguard Worker switch (CFI.getOperation()) {
958*9880d681SAndroid Build Coastguard Worker case MCCFIInstruction::OpSameValue:
959*9880d681SAndroid Build Coastguard Worker OS << ".cfi_same_value ";
960*9880d681SAndroid Build Coastguard Worker if (CFI.getLabel())
961*9880d681SAndroid Build Coastguard Worker OS << "<mcsymbol> ";
962*9880d681SAndroid Build Coastguard Worker printCFIRegister(CFI.getRegister(), OS, TRI);
963*9880d681SAndroid Build Coastguard Worker break;
964*9880d681SAndroid Build Coastguard Worker case MCCFIInstruction::OpOffset:
965*9880d681SAndroid Build Coastguard Worker OS << ".cfi_offset ";
966*9880d681SAndroid Build Coastguard Worker if (CFI.getLabel())
967*9880d681SAndroid Build Coastguard Worker OS << "<mcsymbol> ";
968*9880d681SAndroid Build Coastguard Worker printCFIRegister(CFI.getRegister(), OS, TRI);
969*9880d681SAndroid Build Coastguard Worker OS << ", " << CFI.getOffset();
970*9880d681SAndroid Build Coastguard Worker break;
971*9880d681SAndroid Build Coastguard Worker case MCCFIInstruction::OpDefCfaRegister:
972*9880d681SAndroid Build Coastguard Worker OS << ".cfi_def_cfa_register ";
973*9880d681SAndroid Build Coastguard Worker if (CFI.getLabel())
974*9880d681SAndroid Build Coastguard Worker OS << "<mcsymbol> ";
975*9880d681SAndroid Build Coastguard Worker printCFIRegister(CFI.getRegister(), OS, TRI);
976*9880d681SAndroid Build Coastguard Worker break;
977*9880d681SAndroid Build Coastguard Worker case MCCFIInstruction::OpDefCfaOffset:
978*9880d681SAndroid Build Coastguard Worker OS << ".cfi_def_cfa_offset ";
979*9880d681SAndroid Build Coastguard Worker if (CFI.getLabel())
980*9880d681SAndroid Build Coastguard Worker OS << "<mcsymbol> ";
981*9880d681SAndroid Build Coastguard Worker OS << CFI.getOffset();
982*9880d681SAndroid Build Coastguard Worker break;
983*9880d681SAndroid Build Coastguard Worker case MCCFIInstruction::OpDefCfa:
984*9880d681SAndroid Build Coastguard Worker OS << ".cfi_def_cfa ";
985*9880d681SAndroid Build Coastguard Worker if (CFI.getLabel())
986*9880d681SAndroid Build Coastguard Worker OS << "<mcsymbol> ";
987*9880d681SAndroid Build Coastguard Worker printCFIRegister(CFI.getRegister(), OS, TRI);
988*9880d681SAndroid Build Coastguard Worker OS << ", " << CFI.getOffset();
989*9880d681SAndroid Build Coastguard Worker break;
990*9880d681SAndroid Build Coastguard Worker default:
991*9880d681SAndroid Build Coastguard Worker // TODO: Print the other CFI Operations.
992*9880d681SAndroid Build Coastguard Worker OS << "<unserializable cfi operation>";
993*9880d681SAndroid Build Coastguard Worker break;
994*9880d681SAndroid Build Coastguard Worker }
995*9880d681SAndroid Build Coastguard Worker }
996*9880d681SAndroid Build Coastguard Worker
printMIR(raw_ostream & OS,const Module & M)997*9880d681SAndroid Build Coastguard Worker void llvm::printMIR(raw_ostream &OS, const Module &M) {
998*9880d681SAndroid Build Coastguard Worker yaml::Output Out(OS);
999*9880d681SAndroid Build Coastguard Worker Out << const_cast<Module &>(M);
1000*9880d681SAndroid Build Coastguard Worker }
1001*9880d681SAndroid Build Coastguard Worker
printMIR(raw_ostream & OS,const MachineFunction & MF)1002*9880d681SAndroid Build Coastguard Worker void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
1003*9880d681SAndroid Build Coastguard Worker MIRPrinter Printer(OS);
1004*9880d681SAndroid Build Coastguard Worker Printer.print(MF);
1005*9880d681SAndroid Build Coastguard Worker }
1006