blob: 5800db556285883e72018a5bfc1a09e1f976d123 [file] [log] [blame]
Alex Lorenz345c1442015-06-15 23:52:35 +00001//===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the class that prints out the LLVM IR and machine
11// functions using the MIR serialization format.
12//
13//===----------------------------------------------------------------------===//
14
15#include "MIRPrinter.h"
16#include "llvm/ADT/STLExtras.h"
Alex Lorenzab980492015-07-20 20:51:18 +000017#include "llvm/CodeGen/MachineConstantPool.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000018#include "llvm/CodeGen/MachineFunction.h"
Alex Lorenz60541c12015-07-09 19:55:27 +000019#include "llvm/CodeGen/MachineFrameInfo.h"
Alex Lorenzf4baeb52015-07-21 22:28:27 +000020#include "llvm/CodeGen/MachineModuleInfo.h"
Alex Lorenz54565cf2015-06-24 19:56:10 +000021#include "llvm/CodeGen/MachineRegisterInfo.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000022#include "llvm/CodeGen/MIRYamlMapping.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000023#include "llvm/IR/BasicBlock.h"
Alex Lorenz37643a02015-07-15 22:14:49 +000024#include "llvm/IR/Instructions.h"
Alex Lorenz6ede3742015-07-21 16:59:53 +000025#include "llvm/IR/IRPrintingPasses.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000026#include "llvm/IR/Module.h"
Alex Lorenz900b5cb2015-07-07 23:27:53 +000027#include "llvm/IR/ModuleSlotTracker.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000028#include "llvm/Support/MemoryBuffer.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/Support/YAMLTraits.h"
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000031#include "llvm/Target/TargetInstrInfo.h"
32#include "llvm/Target/TargetSubtargetInfo.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000033
34using namespace llvm;
35
36namespace {
37
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000038/// This structure describes how to print out stack object references.
39struct FrameIndexOperand {
40 std::string Name;
41 unsigned ID;
42 bool IsFixed;
43
44 FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
45 : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
46
47 /// Return an ordinary stack object reference.
48 static FrameIndexOperand create(StringRef Name, unsigned ID) {
49 return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
50 }
51
52 /// Return a fixed stack object reference.
53 static FrameIndexOperand createFixed(unsigned ID) {
54 return FrameIndexOperand("", ID, /*IsFixed=*/true);
55 }
56};
57
Alex Lorenz345c1442015-06-15 23:52:35 +000058/// This class prints out the machine functions using the MIR serialization
59/// format.
60class MIRPrinter {
61 raw_ostream &OS;
Alex Lorenz8f6f4282015-06-29 16:57:06 +000062 DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000063 /// Maps from stack object indices to operand indices which will be used when
64 /// printing frame index machine operands.
65 DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
Alex Lorenz345c1442015-06-15 23:52:35 +000066
67public:
68 MIRPrinter(raw_ostream &OS) : OS(OS) {}
69
70 void print(const MachineFunction &MF);
Alex Lorenz4f093bf2015-06-19 17:43:07 +000071
Alex Lorenz28148ba2015-07-09 22:23:13 +000072 void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
73 const TargetRegisterInfo *TRI);
Alex Lorenz60541c12015-07-09 19:55:27 +000074 void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
Alex Lorenzab980492015-07-20 20:51:18 +000075 void convert(yaml::MachineFunction &MF,
76 const MachineConstantPool &ConstantPool);
Alex Lorenz6799e9b2015-07-15 23:31:07 +000077 void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
78 const MachineJumpTableInfo &JTI);
Alex Lorenz900b5cb2015-07-07 23:27:53 +000079 void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz5d6108e2015-06-26 22:56:48 +000080 const MachineBasicBlock &MBB);
Alex Lorenzf6bc8662015-07-10 18:13:57 +000081 void convertStackObjects(yaml::MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +000082 const MachineFrameInfo &MFI,
83 const TargetRegisterInfo *TRI);
Alex Lorenz8f6f4282015-06-29 16:57:06 +000084
85private:
86 void initRegisterMaskIds(const MachineFunction &MF);
Alex Lorenz345c1442015-06-15 23:52:35 +000087};
88
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000089/// This class prints out the machine instructions using the MIR serialization
90/// format.
91class MIPrinter {
92 raw_ostream &OS;
Alex Lorenz900b5cb2015-07-07 23:27:53 +000093 ModuleSlotTracker &MST;
Alex Lorenz8f6f4282015-06-29 16:57:06 +000094 const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000095 const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000096
97public:
Alex Lorenz900b5cb2015-07-07 23:27:53 +000098 MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000099 const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
100 const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
101 : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
102 StackObjectOperandMapping(StackObjectOperandMapping) {}
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000103
104 void print(const MachineInstr &MI);
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000105 void printMBBReference(const MachineBasicBlock &MBB);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000106 void printStackObjectReference(int FrameIndex);
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000107 void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000108
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000109 void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000110};
111
Alex Lorenz345c1442015-06-15 23:52:35 +0000112} // end anonymous namespace
113
114namespace llvm {
115namespace yaml {
116
117/// This struct serializes the LLVM IR module.
118template <> struct BlockScalarTraits<Module> {
119 static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
120 Mod.print(OS, nullptr);
121 }
122 static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
123 llvm_unreachable("LLVM Module is supposed to be parsed separately");
124 return "";
125 }
126};
127
128} // end namespace yaml
129} // end namespace llvm
130
Alex Lorenz15a00a82015-07-14 21:18:25 +0000131static void printReg(unsigned Reg, raw_ostream &OS,
132 const TargetRegisterInfo *TRI) {
133 // TODO: Print Stack Slots.
134 if (!Reg)
135 OS << '_';
136 else if (TargetRegisterInfo::isVirtualRegister(Reg))
137 OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
138 else if (Reg < TRI->getNumRegs())
139 OS << '%' << StringRef(TRI->getName(Reg)).lower();
140 else
141 llvm_unreachable("Can't print this kind of register yet");
142}
143
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000144static void printReg(unsigned Reg, yaml::StringValue &Dest,
145 const TargetRegisterInfo *TRI) {
146 raw_string_ostream OS(Dest.Value);
147 printReg(Reg, OS, TRI);
148}
149
Alex Lorenz345c1442015-06-15 23:52:35 +0000150void MIRPrinter::print(const MachineFunction &MF) {
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000151 initRegisterMaskIds(MF);
152
Alex Lorenz345c1442015-06-15 23:52:35 +0000153 yaml::MachineFunction YamlMF;
154 YamlMF.Name = MF.getName();
Alex Lorenz5b5f9752015-06-16 00:10:47 +0000155 YamlMF.Alignment = MF.getAlignment();
156 YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
157 YamlMF.HasInlineAsm = MF.hasInlineAsm();
Alex Lorenz28148ba2015-07-09 22:23:13 +0000158 convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
Alex Lorenz60541c12015-07-09 19:55:27 +0000159 convert(YamlMF.FrameInfo, *MF.getFrameInfo());
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000160 convertStackObjects(YamlMF, *MF.getFrameInfo(),
161 MF.getSubtarget().getRegisterInfo());
Alex Lorenzab980492015-07-20 20:51:18 +0000162 if (const auto *ConstantPool = MF.getConstantPool())
163 convert(YamlMF, *ConstantPool);
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000164
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000165 ModuleSlotTracker MST(MF.getFunction()->getParent());
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000166 if (const auto *JumpTableInfo = MF.getJumpTableInfo())
167 convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
168 int I = 0;
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000169 for (const auto &MBB : MF) {
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000170 // TODO: Allow printing of non sequentially numbered MBBs.
171 // This is currently needed as the basic block references get their index
172 // from MBB.getNumber(), thus it should be sequential so that the parser can
173 // map back to the correct MBBs when parsing the output.
174 assert(MBB.getNumber() == I++ &&
175 "Can't print MBBs that aren't sequentially numbered");
Alex Lorenzec6b26b2015-06-26 17:07:27 +0000176 (void)I;
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000177 yaml::MachineBasicBlock YamlMBB;
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000178 convert(MST, YamlMBB, MBB);
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000179 YamlMF.BasicBlocks.push_back(YamlMBB);
180 }
Alex Lorenz345c1442015-06-15 23:52:35 +0000181 yaml::Output Out(OS);
182 Out << YamlMF;
183}
184
Alex Lorenz54565cf2015-06-24 19:56:10 +0000185void MIRPrinter::convert(yaml::MachineFunction &MF,
Alex Lorenz28148ba2015-07-09 22:23:13 +0000186 const MachineRegisterInfo &RegInfo,
187 const TargetRegisterInfo *TRI) {
Alex Lorenz54565cf2015-06-24 19:56:10 +0000188 MF.IsSSA = RegInfo.isSSA();
189 MF.TracksRegLiveness = RegInfo.tracksLiveness();
190 MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
Alex Lorenz28148ba2015-07-09 22:23:13 +0000191
192 // Print the virtual register definitions.
193 for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
194 unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
195 yaml::VirtualRegisterDefinition VReg;
196 VReg.ID = I;
197 VReg.Class =
198 StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000199 unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
200 if (PreferredReg)
201 printReg(PreferredReg, VReg.PreferredRegister, TRI);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000202 MF.VirtualRegisters.push_back(VReg);
203 }
Alex Lorenz12045a42015-07-27 17:42:45 +0000204
205 // Print the live ins.
206 for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
207 yaml::MachineFunctionLiveIn LiveIn;
208 printReg(I->first, LiveIn.Register, TRI);
209 if (I->second)
210 printReg(I->second, LiveIn.VirtualRegister, TRI);
211 MF.LiveIns.push_back(LiveIn);
212 }
Alex Lorenz54565cf2015-06-24 19:56:10 +0000213}
214
Alex Lorenz60541c12015-07-09 19:55:27 +0000215void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
216 const MachineFrameInfo &MFI) {
217 YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
218 YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
219 YamlMFI.HasStackMap = MFI.hasStackMap();
220 YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
221 YamlMFI.StackSize = MFI.getStackSize();
222 YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
223 YamlMFI.MaxAlignment = MFI.getMaxAlignment();
224 YamlMFI.AdjustsStack = MFI.adjustsStack();
225 YamlMFI.HasCalls = MFI.hasCalls();
226 YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
227 YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
228 YamlMFI.HasVAStart = MFI.hasVAStart();
229 YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
230}
231
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000232void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000233 const MachineFrameInfo &MFI,
234 const TargetRegisterInfo *TRI) {
Alex Lorenzde491f02015-07-13 18:07:26 +0000235 // Process fixed stack objects.
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000236 unsigned ID = 0;
Alex Lorenzde491f02015-07-13 18:07:26 +0000237 for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
238 if (MFI.isDeadObjectIndex(I))
239 continue;
240
241 yaml::FixedMachineStackObject YamlObject;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000242 YamlObject.ID = ID;
Alex Lorenzde491f02015-07-13 18:07:26 +0000243 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
244 ? yaml::FixedMachineStackObject::SpillSlot
245 : yaml::FixedMachineStackObject::DefaultType;
246 YamlObject.Offset = MFI.getObjectOffset(I);
247 YamlObject.Size = MFI.getObjectSize(I);
248 YamlObject.Alignment = MFI.getObjectAlignment(I);
249 YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
250 YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
251 MF.FixedStackObjects.push_back(YamlObject);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000252 StackObjectOperandMapping.insert(
253 std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
Alex Lorenzde491f02015-07-13 18:07:26 +0000254 }
255
256 // Process ordinary stack objects.
257 ID = 0;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000258 for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
259 if (MFI.isDeadObjectIndex(I))
260 continue;
261
262 yaml::MachineStackObject YamlObject;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000263 YamlObject.ID = ID;
Alex Lorenz37643a02015-07-15 22:14:49 +0000264 if (const auto *Alloca = MFI.getObjectAllocation(I))
265 YamlObject.Name.Value =
266 Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000267 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
268 ? yaml::MachineStackObject::SpillSlot
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000269 : MFI.isVariableSizedObjectIndex(I)
270 ? yaml::MachineStackObject::VariableSized
271 : yaml::MachineStackObject::DefaultType;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000272 YamlObject.Offset = MFI.getObjectOffset(I);
273 YamlObject.Size = MFI.getObjectSize(I);
274 YamlObject.Alignment = MFI.getObjectAlignment(I);
275
276 MF.StackObjects.push_back(YamlObject);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000277 StackObjectOperandMapping.insert(std::make_pair(
278 I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000279 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000280
281 for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
282 yaml::StringValue Reg;
283 printReg(CSInfo.getReg(), Reg, TRI);
284 auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
285 assert(StackObjectInfo != StackObjectOperandMapping.end() &&
286 "Invalid stack object index");
287 const FrameIndexOperand &StackObject = StackObjectInfo->second;
288 if (StackObject.IsFixed)
289 MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
290 else
291 MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
292 }
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000293}
294
Alex Lorenzab980492015-07-20 20:51:18 +0000295void MIRPrinter::convert(yaml::MachineFunction &MF,
296 const MachineConstantPool &ConstantPool) {
297 unsigned ID = 0;
298 for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
299 // TODO: Serialize target specific constant pool entries.
300 if (Constant.isMachineConstantPoolEntry())
301 llvm_unreachable("Can't print target specific constant pool entries yet");
302
303 yaml::MachineConstantPoolValue YamlConstant;
304 std::string Str;
305 raw_string_ostream StrOS(Str);
306 Constant.Val.ConstVal->printAsOperand(StrOS);
307 YamlConstant.ID = ID++;
308 YamlConstant.Value = StrOS.str();
309 YamlConstant.Alignment = Constant.getAlignment();
310 MF.Constants.push_back(YamlConstant);
311 }
312}
313
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000314void MIRPrinter::convert(ModuleSlotTracker &MST,
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000315 yaml::MachineJumpTable &YamlJTI,
316 const MachineJumpTableInfo &JTI) {
317 YamlJTI.Kind = JTI.getEntryKind();
318 unsigned ID = 0;
319 for (const auto &Table : JTI.getJumpTables()) {
320 std::string Str;
321 yaml::MachineJumpTable::Entry Entry;
322 Entry.ID = ID++;
323 for (const auto *MBB : Table.MBBs) {
324 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000325 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
326 .printMBBReference(*MBB);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000327 Entry.Blocks.push_back(StrOS.str());
328 Str.clear();
329 }
330 YamlJTI.Entries.push_back(Entry);
331 }
332}
333
334void MIRPrinter::convert(ModuleSlotTracker &MST,
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000335 yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000336 const MachineBasicBlock &MBB) {
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000337 assert(MBB.getNumber() >= 0 && "Invalid MBB number");
338 YamlMBB.ID = (unsigned)MBB.getNumber();
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000339 // TODO: Serialize unnamed BB references.
340 if (const auto *BB = MBB.getBasicBlock())
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000341 YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>";
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000342 else
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000343 YamlMBB.Name.Value = "";
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000344 YamlMBB.Alignment = MBB.getAlignment();
345 YamlMBB.AddressTaken = MBB.hasAddressTaken();
346 YamlMBB.IsLandingPad = MBB.isLandingPad();
Alex Lorenzeb5112b2015-06-30 18:32:02 +0000347 for (const auto *SuccMBB : MBB.successors()) {
Alex Lorenzf09df002015-06-30 18:16:42 +0000348 std::string Str;
349 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000350 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
351 .printMBBReference(*SuccMBB);
Alex Lorenzf09df002015-06-30 18:16:42 +0000352 YamlMBB.Successors.push_back(StrOS.str());
353 }
Alex Lorenz9fab3702015-07-14 21:24:41 +0000354 // Print the live in registers.
355 const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
356 assert(TRI && "Expected target register info");
357 for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) {
358 std::string Str;
359 raw_string_ostream StrOS(Str);
360 printReg(*I, StrOS, TRI);
361 YamlMBB.LiveIns.push_back(StrOS.str());
362 }
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000363 // Print the machine instructions.
364 YamlMBB.Instructions.reserve(MBB.size());
365 std::string Str;
366 for (const auto &MI : MBB) {
367 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000368 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000369 YamlMBB.Instructions.push_back(StrOS.str());
370 Str.clear();
371 }
372}
373
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000374void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
375 const auto *TRI = MF.getSubtarget().getRegisterInfo();
376 unsigned I = 0;
377 for (const uint32_t *Mask : TRI->getRegMasks())
378 RegisterMaskIds.insert(std::make_pair(Mask, I++));
379}
380
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000381void MIPrinter::print(const MachineInstr &MI) {
382 const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000383 const auto *TRI = SubTarget.getRegisterInfo();
384 assert(TRI && "Expected target register info");
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000385 const auto *TII = SubTarget.getInstrInfo();
386 assert(TII && "Expected target instruction info");
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000387 if (MI.isCFIInstruction())
388 assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000389
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000390 unsigned I = 0, E = MI.getNumOperands();
391 for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
392 !MI.getOperand(I).isImplicit();
393 ++I) {
394 if (I)
395 OS << ", ";
396 print(MI.getOperand(I), TRI);
397 }
398
399 if (I)
400 OS << " = ";
Alex Lorenze5a44662015-07-17 00:24:15 +0000401 if (MI.getFlag(MachineInstr::FrameSetup))
402 OS << "frame-setup ";
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000403 OS << TII->getName(MI.getOpcode());
Alex Lorenze5a44662015-07-17 00:24:15 +0000404 // TODO: Print the bundling instruction flags, machine mem operands.
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000405 if (I < E)
406 OS << ' ';
407
408 bool NeedComma = false;
409 for (; I < E; ++I) {
410 if (NeedComma)
411 OS << ", ";
412 print(MI.getOperand(I), TRI);
413 NeedComma = true;
414 }
Alex Lorenz46d760d2015-07-22 21:15:11 +0000415
416 if (MI.getDebugLoc()) {
417 if (NeedComma)
418 OS << ',';
419 OS << " debug-location ";
420 MI.getDebugLoc()->printAsOperand(OS, MST);
421 }
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000422}
423
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000424void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
425 OS << "%bb." << MBB.getNumber();
426 if (const auto *BB = MBB.getBasicBlock()) {
427 if (BB->hasName())
428 OS << '.' << BB->getName();
429 }
430}
431
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000432void MIPrinter::printStackObjectReference(int FrameIndex) {
433 auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
434 assert(ObjectInfo != StackObjectOperandMapping.end() &&
435 "Invalid frame index");
436 const FrameIndexOperand &Operand = ObjectInfo->second;
437 if (Operand.IsFixed) {
438 OS << "%fixed-stack." << Operand.ID;
439 return;
440 }
441 OS << "%stack." << Operand.ID;
442 if (!Operand.Name.empty())
443 OS << '.' << Operand.Name;
444}
445
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000446void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
447 switch (Op.getType()) {
448 case MachineOperand::MO_Register:
Alex Lorenzcb268d42015-07-06 23:07:26 +0000449 // TODO: Print the other register flags.
450 if (Op.isImplicit())
451 OS << (Op.isDef() ? "implicit-def " : "implicit ");
Alex Lorenzcbbfd0b2015-07-07 20:34:53 +0000452 if (Op.isDead())
453 OS << "dead ";
Alex Lorenz495ad872015-07-08 21:23:34 +0000454 if (Op.isKill())
455 OS << "killed ";
Alex Lorenz4d026b892015-07-08 23:58:31 +0000456 if (Op.isUndef())
457 OS << "undef ";
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000458 printReg(Op.getReg(), OS, TRI);
Alex Lorenz2eacca82015-07-13 23:24:34 +0000459 // Print the sub register.
460 if (Op.getSubReg() != 0)
461 OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000462 break;
Alex Lorenz240fc1e2015-06-23 23:42:28 +0000463 case MachineOperand::MO_Immediate:
464 OS << Op.getImm();
465 break;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000466 case MachineOperand::MO_MachineBasicBlock:
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000467 printMBBReference(*Op.getMBB());
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000468 break;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000469 case MachineOperand::MO_FrameIndex:
470 printStackObjectReference(Op.getIndex());
471 break;
Alex Lorenzab980492015-07-20 20:51:18 +0000472 case MachineOperand::MO_ConstantPoolIndex:
473 OS << "%const." << Op.getIndex();
474 // TODO: Print offset and target flags.
475 break;
Alex Lorenz31d70682015-07-15 23:38:35 +0000476 case MachineOperand::MO_JumpTableIndex:
477 OS << "%jump-table." << Op.getIndex();
478 // TODO: Print target flags.
479 break;
Alex Lorenz6ede3742015-07-21 16:59:53 +0000480 case MachineOperand::MO_ExternalSymbol:
481 OS << '$';
482 printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
483 // TODO: Print the target flags.
484 break;
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000485 case MachineOperand::MO_GlobalAddress:
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000486 Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000487 // TODO: Print offset and target flags.
488 break;
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000489 case MachineOperand::MO_RegisterMask: {
490 auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
491 if (RegMaskInfo != RegisterMaskIds.end())
492 OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
493 else
494 llvm_unreachable("Can't print this machine register mask yet.");
495 break;
496 }
Alex Lorenz35e44462015-07-22 17:58:46 +0000497 case MachineOperand::MO_Metadata:
498 Op.getMetadata()->printAsOperand(OS, MST);
499 break;
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000500 case MachineOperand::MO_CFIIndex: {
501 const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000502 print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000503 break;
504 }
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000505 default:
506 // TODO: Print the other machine operands.
507 llvm_unreachable("Can't print this machine operand at the moment");
508 }
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000509}
510
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000511static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
512 const TargetRegisterInfo *TRI) {
513 int Reg = TRI->getLLVMRegNum(DwarfReg, true);
514 if (Reg == -1) {
515 OS << "<badreg>";
516 return;
517 }
518 printReg(Reg, OS, TRI);
519}
520
521void MIPrinter::print(const MCCFIInstruction &CFI,
522 const TargetRegisterInfo *TRI) {
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000523 switch (CFI.getOperation()) {
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000524 case MCCFIInstruction::OpOffset:
525 OS << ".cfi_offset ";
526 if (CFI.getLabel())
527 OS << "<mcsymbol> ";
528 printCFIRegister(CFI.getRegister(), OS, TRI);
529 OS << ", " << CFI.getOffset();
530 break;
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000531 case MCCFIInstruction::OpDefCfaOffset:
532 OS << ".cfi_def_cfa_offset ";
533 if (CFI.getLabel())
534 OS << "<mcsymbol> ";
535 OS << CFI.getOffset();
536 break;
537 default:
538 // TODO: Print the other CFI Operations.
539 OS << "<unserializable cfi operation>";
540 break;
541 }
542}
543
Alex Lorenz345c1442015-06-15 23:52:35 +0000544void llvm::printMIR(raw_ostream &OS, const Module &M) {
545 yaml::Output Out(OS);
546 Out << const_cast<Module &>(M);
547}
548
549void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
550 MIRPrinter Printer(OS);
551 Printer.print(MF);
552}