blob: 2287dfd4480df9d32241e8c0061be8a1e9750e5b [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 Lorenz54565cf2015-06-24 19:56:10 +0000204}
205
Alex Lorenz60541c12015-07-09 19:55:27 +0000206void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
207 const MachineFrameInfo &MFI) {
208 YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
209 YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
210 YamlMFI.HasStackMap = MFI.hasStackMap();
211 YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
212 YamlMFI.StackSize = MFI.getStackSize();
213 YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
214 YamlMFI.MaxAlignment = MFI.getMaxAlignment();
215 YamlMFI.AdjustsStack = MFI.adjustsStack();
216 YamlMFI.HasCalls = MFI.hasCalls();
217 YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
218 YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
219 YamlMFI.HasVAStart = MFI.hasVAStart();
220 YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
221}
222
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000223void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000224 const MachineFrameInfo &MFI,
225 const TargetRegisterInfo *TRI) {
Alex Lorenzde491f02015-07-13 18:07:26 +0000226 // Process fixed stack objects.
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000227 unsigned ID = 0;
Alex Lorenzde491f02015-07-13 18:07:26 +0000228 for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
229 if (MFI.isDeadObjectIndex(I))
230 continue;
231
232 yaml::FixedMachineStackObject YamlObject;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000233 YamlObject.ID = ID;
Alex Lorenzde491f02015-07-13 18:07:26 +0000234 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
235 ? yaml::FixedMachineStackObject::SpillSlot
236 : yaml::FixedMachineStackObject::DefaultType;
237 YamlObject.Offset = MFI.getObjectOffset(I);
238 YamlObject.Size = MFI.getObjectSize(I);
239 YamlObject.Alignment = MFI.getObjectAlignment(I);
240 YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
241 YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
242 MF.FixedStackObjects.push_back(YamlObject);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000243 StackObjectOperandMapping.insert(
244 std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
Alex Lorenzde491f02015-07-13 18:07:26 +0000245 }
246
247 // Process ordinary stack objects.
248 ID = 0;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000249 for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
250 if (MFI.isDeadObjectIndex(I))
251 continue;
252
253 yaml::MachineStackObject YamlObject;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000254 YamlObject.ID = ID;
Alex Lorenz37643a02015-07-15 22:14:49 +0000255 if (const auto *Alloca = MFI.getObjectAllocation(I))
256 YamlObject.Name.Value =
257 Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000258 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
259 ? yaml::MachineStackObject::SpillSlot
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000260 : MFI.isVariableSizedObjectIndex(I)
261 ? yaml::MachineStackObject::VariableSized
262 : yaml::MachineStackObject::DefaultType;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000263 YamlObject.Offset = MFI.getObjectOffset(I);
264 YamlObject.Size = MFI.getObjectSize(I);
265 YamlObject.Alignment = MFI.getObjectAlignment(I);
266
267 MF.StackObjects.push_back(YamlObject);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000268 StackObjectOperandMapping.insert(std::make_pair(
269 I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000270 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000271
272 for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
273 yaml::StringValue Reg;
274 printReg(CSInfo.getReg(), Reg, TRI);
275 auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
276 assert(StackObjectInfo != StackObjectOperandMapping.end() &&
277 "Invalid stack object index");
278 const FrameIndexOperand &StackObject = StackObjectInfo->second;
279 if (StackObject.IsFixed)
280 MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
281 else
282 MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
283 }
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000284}
285
Alex Lorenzab980492015-07-20 20:51:18 +0000286void MIRPrinter::convert(yaml::MachineFunction &MF,
287 const MachineConstantPool &ConstantPool) {
288 unsigned ID = 0;
289 for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
290 // TODO: Serialize target specific constant pool entries.
291 if (Constant.isMachineConstantPoolEntry())
292 llvm_unreachable("Can't print target specific constant pool entries yet");
293
294 yaml::MachineConstantPoolValue YamlConstant;
295 std::string Str;
296 raw_string_ostream StrOS(Str);
297 Constant.Val.ConstVal->printAsOperand(StrOS);
298 YamlConstant.ID = ID++;
299 YamlConstant.Value = StrOS.str();
300 YamlConstant.Alignment = Constant.getAlignment();
301 MF.Constants.push_back(YamlConstant);
302 }
303}
304
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000305void MIRPrinter::convert(ModuleSlotTracker &MST,
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000306 yaml::MachineJumpTable &YamlJTI,
307 const MachineJumpTableInfo &JTI) {
308 YamlJTI.Kind = JTI.getEntryKind();
309 unsigned ID = 0;
310 for (const auto &Table : JTI.getJumpTables()) {
311 std::string Str;
312 yaml::MachineJumpTable::Entry Entry;
313 Entry.ID = ID++;
314 for (const auto *MBB : Table.MBBs) {
315 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000316 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
317 .printMBBReference(*MBB);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000318 Entry.Blocks.push_back(StrOS.str());
319 Str.clear();
320 }
321 YamlJTI.Entries.push_back(Entry);
322 }
323}
324
325void MIRPrinter::convert(ModuleSlotTracker &MST,
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000326 yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000327 const MachineBasicBlock &MBB) {
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000328 assert(MBB.getNumber() >= 0 && "Invalid MBB number");
329 YamlMBB.ID = (unsigned)MBB.getNumber();
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000330 // TODO: Serialize unnamed BB references.
331 if (const auto *BB = MBB.getBasicBlock())
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000332 YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>";
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000333 else
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000334 YamlMBB.Name.Value = "";
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000335 YamlMBB.Alignment = MBB.getAlignment();
336 YamlMBB.AddressTaken = MBB.hasAddressTaken();
337 YamlMBB.IsLandingPad = MBB.isLandingPad();
Alex Lorenzeb5112b2015-06-30 18:32:02 +0000338 for (const auto *SuccMBB : MBB.successors()) {
Alex Lorenzf09df002015-06-30 18:16:42 +0000339 std::string Str;
340 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000341 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
342 .printMBBReference(*SuccMBB);
Alex Lorenzf09df002015-06-30 18:16:42 +0000343 YamlMBB.Successors.push_back(StrOS.str());
344 }
Alex Lorenz9fab3702015-07-14 21:24:41 +0000345 // Print the live in registers.
346 const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
347 assert(TRI && "Expected target register info");
348 for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) {
349 std::string Str;
350 raw_string_ostream StrOS(Str);
351 printReg(*I, StrOS, TRI);
352 YamlMBB.LiveIns.push_back(StrOS.str());
353 }
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000354 // Print the machine instructions.
355 YamlMBB.Instructions.reserve(MBB.size());
356 std::string Str;
357 for (const auto &MI : MBB) {
358 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000359 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000360 YamlMBB.Instructions.push_back(StrOS.str());
361 Str.clear();
362 }
363}
364
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000365void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
366 const auto *TRI = MF.getSubtarget().getRegisterInfo();
367 unsigned I = 0;
368 for (const uint32_t *Mask : TRI->getRegMasks())
369 RegisterMaskIds.insert(std::make_pair(Mask, I++));
370}
371
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000372void MIPrinter::print(const MachineInstr &MI) {
373 const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000374 const auto *TRI = SubTarget.getRegisterInfo();
375 assert(TRI && "Expected target register info");
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000376 const auto *TII = SubTarget.getInstrInfo();
377 assert(TII && "Expected target instruction info");
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000378 if (MI.isCFIInstruction())
379 assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000380
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000381 unsigned I = 0, E = MI.getNumOperands();
382 for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
383 !MI.getOperand(I).isImplicit();
384 ++I) {
385 if (I)
386 OS << ", ";
387 print(MI.getOperand(I), TRI);
388 }
389
390 if (I)
391 OS << " = ";
Alex Lorenze5a44662015-07-17 00:24:15 +0000392 if (MI.getFlag(MachineInstr::FrameSetup))
393 OS << "frame-setup ";
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000394 OS << TII->getName(MI.getOpcode());
Alex Lorenze5a44662015-07-17 00:24:15 +0000395 // TODO: Print the bundling instruction flags, machine mem operands.
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000396 if (I < E)
397 OS << ' ';
398
399 bool NeedComma = false;
400 for (; I < E; ++I) {
401 if (NeedComma)
402 OS << ", ";
403 print(MI.getOperand(I), TRI);
404 NeedComma = true;
405 }
Alex Lorenz46d760d2015-07-22 21:15:11 +0000406
407 if (MI.getDebugLoc()) {
408 if (NeedComma)
409 OS << ',';
410 OS << " debug-location ";
411 MI.getDebugLoc()->printAsOperand(OS, MST);
412 }
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000413}
414
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000415void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
416 OS << "%bb." << MBB.getNumber();
417 if (const auto *BB = MBB.getBasicBlock()) {
418 if (BB->hasName())
419 OS << '.' << BB->getName();
420 }
421}
422
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000423void MIPrinter::printStackObjectReference(int FrameIndex) {
424 auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
425 assert(ObjectInfo != StackObjectOperandMapping.end() &&
426 "Invalid frame index");
427 const FrameIndexOperand &Operand = ObjectInfo->second;
428 if (Operand.IsFixed) {
429 OS << "%fixed-stack." << Operand.ID;
430 return;
431 }
432 OS << "%stack." << Operand.ID;
433 if (!Operand.Name.empty())
434 OS << '.' << Operand.Name;
435}
436
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000437void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
438 switch (Op.getType()) {
439 case MachineOperand::MO_Register:
Alex Lorenzcb268d42015-07-06 23:07:26 +0000440 // TODO: Print the other register flags.
441 if (Op.isImplicit())
442 OS << (Op.isDef() ? "implicit-def " : "implicit ");
Alex Lorenzcbbfd0b2015-07-07 20:34:53 +0000443 if (Op.isDead())
444 OS << "dead ";
Alex Lorenz495ad872015-07-08 21:23:34 +0000445 if (Op.isKill())
446 OS << "killed ";
Alex Lorenz4d026b892015-07-08 23:58:31 +0000447 if (Op.isUndef())
448 OS << "undef ";
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000449 printReg(Op.getReg(), OS, TRI);
Alex Lorenz2eacca82015-07-13 23:24:34 +0000450 // Print the sub register.
451 if (Op.getSubReg() != 0)
452 OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000453 break;
Alex Lorenz240fc1e2015-06-23 23:42:28 +0000454 case MachineOperand::MO_Immediate:
455 OS << Op.getImm();
456 break;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000457 case MachineOperand::MO_MachineBasicBlock:
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000458 printMBBReference(*Op.getMBB());
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000459 break;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000460 case MachineOperand::MO_FrameIndex:
461 printStackObjectReference(Op.getIndex());
462 break;
Alex Lorenzab980492015-07-20 20:51:18 +0000463 case MachineOperand::MO_ConstantPoolIndex:
464 OS << "%const." << Op.getIndex();
465 // TODO: Print offset and target flags.
466 break;
Alex Lorenz31d70682015-07-15 23:38:35 +0000467 case MachineOperand::MO_JumpTableIndex:
468 OS << "%jump-table." << Op.getIndex();
469 // TODO: Print target flags.
470 break;
Alex Lorenz6ede3742015-07-21 16:59:53 +0000471 case MachineOperand::MO_ExternalSymbol:
472 OS << '$';
473 printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
474 // TODO: Print the target flags.
475 break;
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000476 case MachineOperand::MO_GlobalAddress:
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000477 Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000478 // TODO: Print offset and target flags.
479 break;
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000480 case MachineOperand::MO_RegisterMask: {
481 auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
482 if (RegMaskInfo != RegisterMaskIds.end())
483 OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
484 else
485 llvm_unreachable("Can't print this machine register mask yet.");
486 break;
487 }
Alex Lorenz35e44462015-07-22 17:58:46 +0000488 case MachineOperand::MO_Metadata:
489 Op.getMetadata()->printAsOperand(OS, MST);
490 break;
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000491 case MachineOperand::MO_CFIIndex: {
492 const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000493 print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000494 break;
495 }
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000496 default:
497 // TODO: Print the other machine operands.
498 llvm_unreachable("Can't print this machine operand at the moment");
499 }
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000500}
501
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000502static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
503 const TargetRegisterInfo *TRI) {
504 int Reg = TRI->getLLVMRegNum(DwarfReg, true);
505 if (Reg == -1) {
506 OS << "<badreg>";
507 return;
508 }
509 printReg(Reg, OS, TRI);
510}
511
512void MIPrinter::print(const MCCFIInstruction &CFI,
513 const TargetRegisterInfo *TRI) {
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000514 switch (CFI.getOperation()) {
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000515 case MCCFIInstruction::OpOffset:
516 OS << ".cfi_offset ";
517 if (CFI.getLabel())
518 OS << "<mcsymbol> ";
519 printCFIRegister(CFI.getRegister(), OS, TRI);
520 OS << ", " << CFI.getOffset();
521 break;
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000522 case MCCFIInstruction::OpDefCfaOffset:
523 OS << ".cfi_def_cfa_offset ";
524 if (CFI.getLabel())
525 OS << "<mcsymbol> ";
526 OS << CFI.getOffset();
527 break;
528 default:
529 // TODO: Print the other CFI Operations.
530 OS << "<unserializable cfi operation>";
531 break;
532 }
533}
534
Alex Lorenz345c1442015-06-15 23:52:35 +0000535void llvm::printMIR(raw_ostream &OS, const Module &M) {
536 yaml::Output Out(OS);
537 Out << const_cast<Module &>(M);
538}
539
540void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
541 MIRPrinter Printer(OS);
542 Printer.print(MF);
543}